diff --git a/.eslintrc.js b/.eslintrc.js index 14077276c2..c14862093d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,18 +3,25 @@ module.exports = { browser: true, es2021: true, }, - extends: ['plugin:react/recommended', 'standard-with-typescript', 'prettier'], - overrides: [], + extends: [ + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', + '@typescript-eslint/recommended', + 'prettier', + ], + parser: '@typescript-eslint/parser', parserOptions: { ecmaVersion: 'latest', sourceType: 'module', project: './tsconfig.json', }, - plugins: ['react', 'prettier'], + plugins: ['react', 'react-hooks', '@typescript-eslint', 'prettier'], rules: { 'comma-dangle': 'off', '@typescript-eslint/comma-dangle': 'off', 'prettier/prettier': 'error', + 'react/react-in-jsx-scope': 'off', // Not needed in React 17+ + 'react/prop-types': 'off', // Using TypeScript for prop validation }, settings: { react: { diff --git a/.gitignore b/.gitignore index 3e17ad05f9..820f24fc44 100644 --- a/.gitignore +++ b/.gitignore @@ -33,8 +33,6 @@ docs/build/core-contracts/flow-ft/* docs/build/core-contracts/flow-nft/* !docs/build/core-contracts/flow-nft/index.md -docs/ecosystem/overview/* - docs/.obsidian # flow diff --git a/README.md b/README.md index b290843e7d..9eecb5ce22 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ If you're looking for the Flow docs, they're live at [developers.flow.com](https://developers.flow.com) -This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. +This website is built using [Docusaurus 3](https://docusaurus.io/), a modern static website generator. it pulls doc sections from repositories defined in https://github.com/onflow/developer-portal/tree/main/app/data/doc-collections @@ -46,4 +46,4 @@ If you are using GitHub pages for hosting, this command is a convenient way to b ### Search Indexing -- copy `.env Flow Docusaurus Prod`/`.env Flow Docusaurus Prod` to your local `.env` file from 1Password->`Flow Team` vault +- See `typesense cluster api keys` from 1Password->`Flow Team` vault diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index e00595dae7..0000000000 --- a/babel.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - presets: [require.resolve('@docusaurus/core/lib/babel/preset')], -}; diff --git a/docs/build/guides/account-linking-with-dapper.md b/docs/blockchain-development-tutorials/cadence/account-management/account-linking-with-dapper.md similarity index 83% rename from docs/build/guides/account-linking-with-dapper.md rename to docs/blockchain-development-tutorials/cadence/account-management/account-linking-with-dapper.md index 821c1cba8b..ae79003590 100644 --- a/docs/build/guides/account-linking-with-dapper.md +++ b/docs/blockchain-development-tutorials/cadence/account-management/account-linking-with-dapper.md @@ -1,7 +1,7 @@ --- title: Account Linking With NBA Top Shot description: Use Account Linking between the Dapper Wallet and Flow Wallet to effortlessly use NBA Top Shot Moments in your app. -sidebar_position: 5 +sidebar_position: 3 sidebar_custom_props: icon: ⛓️ keywords: @@ -22,28 +22,28 @@ keywords: - asset management --- -# Account Linking With NBA Top Shot +# Account Linking with NBA Top Shot -[Account Linking] is a powerful Flow feature that allows users to connect their wallets, enabling linked wallets to view and manage assets in one wallet with another. This feature helps reduce or even eliminate the challenges posed by other account abstraction solutions, which often lead to multiple isolated wallets and fragmented assets. +[Account Linking] is a powerful Flow feature that allows users to connect their wallets, which allows linked wallets to view and manage assets in one wallet with another. This feature helps reduce or even eliminate the challenges posed by other account abstraction solutions, which often lead to multiple isolated wallets and fragmented assets. -![Top Shot Preview](./top-shot-preview.png) +![Top Shot Preview](./imgs/top-shot-preview.png) -In this tutorial, you'll build a [simple onchain app] that allows users to sign into your app with their Flow wallet and view [NBA Top Shot] Moments that reside in their [Dapper Wallet] - without those users needing to sign in with Dapper. +In this tutorial, you'll build a [simple onchain app] that allows users to sign in to your app with their Flow wallet and view [NBA Top Shot] Moments that reside in their [Dapper Wallet] without the need for those users to sign in with Dapper. ## Objectives -After completing this guide, you'll be able to: +After you complete this guide, you'll be able to: -- Pull your users' NBA Top Shot Moments into your Flow app without needing to transfer them out of their Dapper wallet -- Retrieve and list all NFT collections in any child wallet linked to a given Flow address -- Write a [Cadence] script to iterate through the storage of a Flow wallet to find NFT collections -- Run Cadence Scripts from the frontend +- Pull your users' NBA Top Shot Moments into your Flow app without the need to transfer them out of their Dapper wallet. +- Retrieve and list all NFT collections in any child wallet linked to a given Flow address. +- Write a [Cadence] script to iterate through the storage of a Flow wallet to find NFT collections. +- Run Cadence Scripts from the frontend. ## Prerequisites ### Next.js and Modern Frontend Development -This tutorial uses [Next.js]. You don't need to be an expert, but it's helpful to be comfortable with development using a current React framework. You'll be on your own to select and use a package manager, manage Node versions, and other frontend environment tasks. If you don't have your own preference, you can just follow along with us and use [Yarn]. +This tutorial uses [Next.js]. You don't need to be an expert, but it's helpful to be comfortable with development with a current React framework. You'll be on your own to select and use a package manager, manage Node versions, and other frontend environment tasks. If you don't have your own preference, you can just follow along with us and use [Yarn]. ### Flow Wallet @@ -51,9 +51,9 @@ You'll need a [Flow Wallet], but you don't need to deposit any funds. ## Moments NFTs -You'll need a [Dapper Wallet] containing some Moments NFTs, such as [NBA Top Shot] Moments. +You'll need a [Dapper Wallet] that contains some Moments NFTs, such as [NBA Top Shot] Moments. -## Getting Started +## Get Started This tutorial will use a [Next.js] project as the foundation of the frontend. Create a new project with: @@ -61,7 +61,7 @@ This tutorial will use a [Next.js] project as the foundation of the frontend. Cr npx create-next-app@latest ``` -We will be using TypeScript and the App Router, in this tutorial. +We will use TypeScript and the App Router, in this tutorial. Open your new project in the editor of your choice, install dependencies, and run the project. @@ -70,27 +70,27 @@ yarn install yarn run dev ``` -If everything is working properly, you'll be able to navigate to `localhost:3000` and see the default [Next.js] page. +If everything works properly, you can navigate to `localhost:3000` and see the default [Next.js] page. -## Flow Cadence Setup +## Flow Cadence setup You'll need a few more dependencies to efficiently work with Cadence inside of your app. -### Flow CLI and Types +### Flow CLI and types -The [Flow CLI] contains a number of command-line tools for interacting with the Flow ecosystem. If you don't already have it installed, you can add it with Brew (or using [other installation methods]): +The [Flow CLI] contains a number of command-line tools to interact with the Flow ecosystem. If you don't have it installed, you can add it with Brew (or with [other installation methods]): ```zsh brew install flow-cli ``` -Once it's installed, you'll need to initialize Flow in your Next.js project. From the root, run: +After it's installed, initialize Flow in your `Next.js` project. From the root, run: ```zsh flow init --config-only ``` -The `--config-only` flag [initializes a project] with the just the config file. This allows the Flow CLI to interact with your project without adding any unnecessary files. +The `--config-only` flag [initializes a project] with the just the config file. This allows the Flow CLI to interact with your project without the need to add the other files you want for most projects. Next, you'll need to do a little bit of config work so that your project knows how to read Cadence files. Install the Flow Cadence Plugin: @@ -116,9 +116,9 @@ const nextConfig: NextConfig = { export default nextConfig; ``` -## Frontend Setup +## Frontend setup -We'll use the Flow Client Library [FCL] to manage blockchain interaction from the frontend. It's similar to viem, ethers, or web3.js, but works with the Flow blockchain and transactions and scripts written in Cadence. +We'll use the Flow Client Library [FCL] to manage blockchain interaction from the frontend. It's similar to `viem`, `ethers`, or `web3.js`, but works with the Flow blockchain and transactions and scripts written in Cadence. ```zsh yarn add @onflow/fcl @@ -130,9 +130,9 @@ Go ahead and install `dotenv` as well: yarn add dotenv ``` -### Provider Setup +### Provider setup -A fair amount of boilerplate code is needed to set up your provider. We'll provide it, but since it's not the purpose of this tutorial, we'll be brief on explanations. For more details, check out the [App Quickstart Guide]. +You'll need a fair amount of boilerplate code to set up your provider. We'll provide it, but since it's not the purpose of this tutorial, we'll be brief on explanations. For more details, check out the [App Quickstart Guide]. Add `app/providers/AuthProvider.tsx`: @@ -227,9 +227,9 @@ Don't forget to replace `` with your own [Wallet Connect] app id! ::: -### Implement the Provider and Flow Config +### Implement the provider and Flow Ccnfig -Finally, open `layout.tsx`. Start by importing Flow dependencies and the AuthProvider: +Finally, open `layout.tsx`. TO start, import Flow dependencies and the AuthProvider: ```tsx import flowJSON from '../flow.json'; @@ -253,7 +253,7 @@ fcl :::warning -We're going to force some things client side to get this proof-of-concept working quickly. Use Next.js best practices for a production app. +We're going to force some things client side to get this proof-of-concept working quickly. Use `Next.js` best practices for a production app. ::: @@ -300,9 +300,9 @@ export default function RootLayout({ } ``` -### Add the Connect Button +### Add the connect button -Open `page.tsx` and clean up the demo code leaving only the `
` block: +Open `page.tsx` and clean up the demo code, leaving only the `
` block: ```tsx import Image from 'next/image'; @@ -343,7 +343,7 @@ Then add a button in the `
` to handle logging in or out:
``` -## Testing Pass +## Test pass Run the app: @@ -351,19 +351,17 @@ Run the app: yarn dev ``` -You'll see your `Log In` button in the middle of the window. +![Welcome](./imgs/welcome.png) -![Welcome](welcome.png) +Click `Log In` in the middle of the window and log in with your Flow wallet. -Click the button and log in with your Flow wallet. - -![Flow Wallet](flow-wallet.png) +![Flow Wallet](./imgs/flow-wallet.png) ## Account Linking Now that your app is set up, you can make use of [Account Linking] to to pull your NFTs from your Dapper Wallet, through your Flow Wallet, and into the app. -### Setting Up Account Linking +### Set up Account Linking If you haven't yet, you'll need to [link your Dapper Wallet] to your Flow Wallet. @@ -373,17 +371,17 @@ The Dapper Wallet requires that you complete KYC before you can use Account Link ::: -### Discovering the NFTs with a Script +### Discover the NFTs with a script -With your accounts linked, your Flow Wallet now has a set of capabilities related to your Dapper Wallet and it's permitted to use those to view and even manipulate those NFTs and assets. +With your accounts linked, your Flow Wallet now has a set of capabilities related to your Dapper Wallet and it can use those to view and even manipulate those NFTs and assets. -Before you can add a script that can handle this, you'll need to import the `HybridCustody` contract using the [Flow Dependency Manager]: +Before you can add a script that can handle this, you'll need to import the `HybridCustody` contract with the [Flow Dependency Manager]: ```zsh flow dependencies install mainnet://d8a7e05a7ac670c0.HybridCustody ``` -Choose `none` to skip deploying on the `emulator` and skip adding testnet aliases. There's no point, these NFTs are on mainnet! +Choose `none` to skip deployment on the `emulator` and skip adding testnet aliases. There's no point, these NFTs are on mainnet! You'll get a complete summary from the Dependency Manager: @@ -421,7 +419,7 @@ You'll get a complete summary from the Dependency Manager: ✅ CapabilityFilter added to flow.json ``` -Add `app/cadence/scripts/FetchNFTsFromLinkedAccts.cdc`. In it, add this script. Review the inline comments to see what each step is doing: +Add `app/cadence/scripts/FetchNFTsFromLinkedAccts.cdc`. In it, add this script. Review the inline comments to see what each step does: ```cadence import "HybridCustody" @@ -520,7 +518,7 @@ The above script is a relatively naive implementation. For production, you'll wa ::: -### Running the Script and Displaying the NFTs +### Run the script and display the NFTs Add a component in `app/components` called `DisplayLinkedNFTs.cdc`. @@ -534,7 +532,7 @@ import * as t from '@onflow/types'; import FetchNFTs from '../cadence/scripts/FetchNFTsFromLinkedAccts.cdc'; ``` -As we're using TypeScript, you should add some types as well to manage the data from the NFTs nicely. For now, just add them to this file: +As we use TypeScript, add some types as well to manage the data from the NFTs nicely. For now, just add them to this file: ```typescript type Thumbnail = { @@ -572,7 +570,7 @@ const DisplayLinkedNFTs: React.FC = ({ address }) => { export default DisplayLinkedNFTs; ``` -In the function, add a state variable to store the data retrieved by the script: +In the function, add a state variable to store the data that the script retrieves: ```typescript const [responseData, setResponseData] = useState(null); @@ -614,13 +612,13 @@ Return to `page.tsx`, import your new component, and add an instance of ` { }; ``` -Next, add a rendering function with some basic styling: +Next, add a render function with some basic styling: ```tsx // Function to render moments with validation @@ -707,7 +705,7 @@ return ( ); ``` -### Further Polish +### Further polish Finally, you can polish up your `page.tsx` to look a little nicer, and guide your users to the Account Linking process in the Dapper Wallet: @@ -776,7 +774,7 @@ In this tutorial, you took your first steps towards building powerful new experi :::warning -You are **not** saving time by skipping the the reference implementation. You'll learn much faster by doing the tutorials as presented! +You **won't** save time if you skipo the the reference implementation. You'll learn much faster if you do the tutorials as presented! Reference solutions are functional, but may not be optimal. @@ -784,19 +782,19 @@ Reference solutions are functional, but may not be optimal. [Reference Solution] -[Account Linking]: ./account-linking/index.md +[Account Linking]: ./index.md [NBA Top Shot]: https://nbatopshot.com [simple onchain app]: https://nextjs-topshot-account-linking.vercel.app [Dapper Wallet]: https://meetdapper.com [Cadence]: https://cadence-lang.org/docs [Next.js]: https://nextjs.org/docs/app/getting-started/installation [Yarn]: https://yarnpkg.com -[Flow CLI]: ../../tools/flow-cli/index.md -[other installation methods]: ../../tools/flow-cli/install.md -[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]: ../getting-started/fcl-quickstart.md +[Flow CLI]: ../../../build/tools/flow-cli/index.md +[other installation methods]: ../../../build/tools/flow-cli/install.md +[initializes a project]: ../../../build/tools/flow-cli/commands.md#init +[Flow Dependency Manager]: ../../../build/tools/flow-cli/dependency-manager.md +[FCL]: ../../../build/tools/clients/fcl-js/index.md +[App Quickstart Guide]: ../getting-started/index.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 diff --git a/docs/build/guides/account-linking/child-accounts.md b/docs/blockchain-development-tutorials/cadence/account-management/child-accounts.md similarity index 64% rename from docs/build/guides/account-linking/child-accounts.md rename to docs/blockchain-development-tutorials/cadence/account-management/child-accounts.md index c2f0e15221..168c04b966 100644 --- a/docs/build/guides/account-linking/child-accounts.md +++ b/docs/blockchain-development-tutorials/cadence/account-management/child-accounts.md @@ -20,44 +20,36 @@ keywords: - user onboarding --- -In this doc, we'll dive into a progressive onboarding flow, including the Cadence scripts & transactions that go into -its implementation in your app. These components will enable any implementing app to create a custodial account, mediate -the user's onchain actions on their behalf, and later delegate access of that app-created account to the user's wallet. -We'll refer to this custodial pattern as the Hybrid Custody Model and the process of delegating control of the app -account as Account Linking. +# Building Walletless Applications Using Child Accounts + +In this tutorial, we'll dive into a progressive onboarding flow, along with the Cadence scripts and transactions that go into its implementation in your app. These components will allow any implementing app to create a custodial account, mediate the user's onchain actions on their behalf, and later delegate access of that app-created account to the user's wallet. We'll refer to this custodial pattern as the Hybrid Custody Model and the process of app account control delegation as Account Linking. ## Objectives -- Create a [walletless onboarding](https://flow.com/post/flow-blockchain-mainstream-adoption-easy-onboarding-wallets) - transaction -- Link an existing app account as a child to a newly authenticated parent account -- Get your app to recognize "parent" accounts along with any associated "child" accounts -- Put it all together to create a blockchain-native onboarding transaction -- View fungible and non-fungible Token metadata relating to assets across all of a user's associated accounts - their - wallet-mediated "parent" account and any "child" accounts -- Facilitate transactions acting on assets in child accounts +- Create a [walletless onboarding] + transaction. +- Link a current app account as a child to a newly authenticated parent account. +- Get your app to recognize "parent" accounts along with any associated "child" accounts. +- Put it all together to create a blockchain-native onboarding transaction. +- View fungible and non-fungible Token metadata that relates to assets across all of a user's associated accounts - their + wallet-mediated "parent" account and any "child" accounts. +- Facilitate transactions acting on assets in child accounts. -## Point of Clarity +## Point of clarity -Before diving in, let's make a distinction between "account linking" and "linking accounts". +Before we dive in, let's make a distinction between "Account Linking" and "linking accounts". ### Account Linking :::info -Note that since account linking is a sensitive action, transactions where an account may be linked are designated by a -topline pragma `#allowAccountLinking`. This lets wallet providers inform users that their account may be linked in the -signed transaction. +Since Account Linking is a sensitive action, transactions where an account may be linked are designated by a topline pragma `#allowAccountLinking`. This lets wallet providers inform users that their account may be linked in the signed transaction. ::: -Very simply, account linking is a [feature in Cadence](https://github.com/onflow/flips/pull/53) that let's an -[Account](https://cadence-lang.org/docs/language/accounts#authaccount) create a -[Capability](https://cadence-lang.org/docs/language/capabilities) on itself. - -Below is an example demonstrating how to issue an `&Account` Capability from a signing account +Very simply, Account Linking is a [feature in Cadence] that lets an [Account] create a [Capability] on itself. -transaction: +Below is an example that demonstrates how to issue an `&Account` Capability from a signing account transaction: ```cadence link_account.cdc #allowAccountLinking @@ -72,67 +64,39 @@ transaction(linkPathSuffix: String) { } ``` -From there, the signing account can retrieve the privately linked `&Account` Capability and delegate it to another -account, revoking the Capability if they wish to revoke delegated access. +From there, the signing account can retrieve the privately linked `&Account` Capability and delegate it to another account, which revokes the Capability if they wish to revoke delegated access. -Note that in order to link an account, a transaction must state the `#allowAccountLinking` pragma in the top line of the -transaction. This is an interim safety measure so that wallet providers can notify users they're about to sign a -transaction that may create a Capability on their `Account`. +To link an account, a transaction must state the `#allowAccountLinking` pragma in the top line of the transaction. This is an interim safety measure so that wallet providers can notify users they're about to sign a transaction that may create a Capability on their `Account`. -### Linking Accounts +### Linking accounts -Linking accounts leverages this account link, otherwise known as an **`&Account` Capability**, and encapsulates it. The -[components and actions](https://github.com/onflow/flips/pull/72) involved in this process - what the Capability is -encapsulated in, the collection that holds those encapsulations, etc. is what we'll dive into in this doc. +Linking accounts leverages this account link, otherwise known as an **`&Account` Capability**, and encapsulates it. The [components and actions] involved in this process - what the Capability is encapsulated in, the collection that holds those encapsulations, and so on is what we'll dive into in this doc. ## Terminology -**Parent-Child accounts** - For the moment, we'll call the account created by the app the "child" account and the -account receiving its `&Account` Capability the "parent" account. Existing methods of account access & delegation (i.e. -keys) still imply ownership over the account, but insofar as linked accounts are concerned, the account to which both -the user and the app share access via `&Account` Capability will be considered the "child" account. +**Parent-Child accounts** - For the moment, we'll call the account that the app creates the "child" account and the account that receives its `&Account` Capability the "parent" account. Current methods of account access and delegation (for example, keys) still imply ownership over the account, but where linked accounts are concerned, the account to which both the user and the app share access via `&Account` Capability are considered the "child" account. -**Walletless onboarding** - An onboarding flow whereby an app creates a custodial account for a user, onboarding them to -the app, obviating the need for user wallet authentication. +**Walletless onboarding** - An onboarding flow whereby an app creates a custodial account for a user and onboards them to the app, which obviates the need for user wallet authentication. -**Blockchain-native onboarding** - Similar to the already familiar Web3 onboarding flow where a user authenticates with -their existing wallet, an app onboards a user via wallet authentication while additionally creating a custodial app -account and linking it with the authenticated account, resulting in a "hybrid custody" model. +**Blockchain-native onboarding** - Similar to the already familiar Web3 onboarding flow where a user authenticates with their existing wallet, an app onboards a user via wallet authentication while it also creates a custodial app account and links it with the authenticated account, which creates a "hybrid custody" model. -**Hybrid Custody Model** - A custodial pattern in which an app and a user maintain access to an app created account and -user access to that account has been mediated via account linking. +**Hybrid Custody Model** - A custodial pattern in which an app and a user maintain access to an app-created account and user access to that account is mediated via Account Linking. -**Account Linking** - Technically speaking, account linking in our context consists of giving some other account an -`&Account` Capability from the granting account. This Capability is maintained in standardized resource called a -`HybridCustody.Manager`, providing its owning user access to any and all of their linked accounts. +**Account Linking** - Account Linking in our context means to give some other account an `&Account` Capability from the granting account. This Capability is maintained in standardized resource called a `HybridCustody.Manager`, which provides its owning user access to any and all of their linked accounts. -**Progressive Onboarding** - An onboarding flow that walks a user up to self-custodial ownership, starting with -walletless onboarding and later linking the app account with the user's authenticated wallet once the user chooses to do -so. +**Progressive Onboarding** - An onboarding flow that walks a user up to self-custodial ownership, which starts with walletless onboarding and later links the app account with the user's authenticated wallet when the user chooses to do so. -**Restricted Child Account** - An account delegation where the access on the delegating account is restricted according -to rules set by the linking child account. The distinctions between this and the subsequent term ("owned" account) will -be expanding on later. +**Restricted Child Account** - An account delegation where the access on the delegating account is restricted according to rules set by the linking child account. We will expand on the distinctions between this and the subsequent term ("owned" account) later. -**Owned Account** - An account delegation where the delegatee has unrestricted access on the delegating child account, -thereby giving the delegatee presiding authority superseding any other "restricted" parent accounts. +**Owned Account** - An account delegation where the delegatee has unrestricted access on the delegating child account, which gives the delegatee presiding authority that supersedes any other "restricted" parent accounts. ## Account Linking -Linking an account is the process of delegating account access via `&Account` Capability. Of course, we want to do this -in a way that allows the receiving account to maintain that Capability and allows easy identification of the accounts on -either end of the linkage - the user's main "parent" account and the linked "child" account. This is accomplished in the -`HybridCustody` contract which we'll continue to use in this guidance. +Linking an account delegates account access via `&Account` Capability. Of course, we want to do this in a way that allows the receiving account to maintain that Capability and allows easy identification of the accounts on either end of the linkage - the user's main "parent" account and the linked "child" account. This is accomplished in the `HybridCustody` contract which we'll continue to use in this guidance. ### Prerequisites -Since account delegation is mediated by developer-defined rules, you should make sure to first configure the resources -that contain those rules. Contracts involved in defining and enforcing this ruleset are -[`CapabilityFilter`](https://github.com/onflow/hybrid-custody/blob/main/contracts/CapabilityFilter.cdc) and -[`CapabilityFactory`](https://github.com/onflow/hybrid-custody/blob/main/contracts/CapabilityFactory.cdc). The former -enumerates those types that are and are not accessible from a child account while the latter enables the access of those -allowable Capabilities such that the returned values can be properly typed - e.g. retrieving a Capability that can be -cast to `Capability<&NonFungibleToken.Collection>` for example. +Since account delegation is mediated by developer-defined rules, you should make sure to first configure the resources that contain those rules. Contracts that help define and enforce this ruleset are [`CapabilityFilter`] and [`CapabilityFactory`]. The former enumerates those types that are and are not accessible from a child account while the latter allows the access of those allowable Capabilities such that the returned values can be properly typed - for example, to retrieve a Capability that can be cast to `Capability<&NonFungibleToken.Collection>`. Here's how you would configure an `AllowlistFilter` and add allowed types to it: @@ -174,9 +138,7 @@ And the following transaction configures a `CapabilityFactory.Manager`, adding N :::info -Note that the Manager configured here enables retrieval of castable Capabilities. It's recommended that you implement -Factory resource definitions to support any NFT Collections related with the use of your application so that users can -retrieve Typed Capabilities from accounts linked from your app. +The Manager configured here allows retrieval of castable Capabilities. We recommend that you implement Factory resource definitions to support any NFT Collections related with the use of your application so that users can retrieve Typed Capabilities from accounts linked from your app. ::: @@ -222,41 +184,32 @@ transaction { } ``` -![resources/hybrid_custody_high_level](./resources/hybrid_custody_high_level.png) +![resources/hybrid_custody_high_level](./imgs/hybrid_custody_high_level.png) -_In this scenario, a user custodies a key for their main account which maintains access to a wrapped `Account` -Capability, providing the user restricted access on the app account. The app maintains custodial access to the account -and regulates the access restrictions to delegatee "parent" accounts._ +_In this scenario, a user custodies a key for their main account which maintains access to a wrapped `Account` Capability. This provides the user restricted access on the app account. The app maintains custodial access to the account and regulates the access restrictions to delegatee "parent" accounts._ -Linking accounts can be done in one of two ways. Put simply, the child account needs to get the parent an `Account` -Capability, and the parent needs to save that Capability so they can retain access. This delegation must be done manner -that represents each side of the link while safeguarding the integrity of any access restrictions an application puts in -place on delegated access. +You can link accounts in one of two ways. Put simply, the child account needs to get the parent an `Account` Capability, and the parent needs to save that Capability so they can retain access. This delegation must occur in a way that represents each side of the link and safeguard the integrity of any access restrictions an application puts in place on delegated access. -We can achieve issuance from the child account and claim from the parent account pattern by either: +To achieve issuance from the child account and claim from the parent account pattern, we can either: -1. Leveraging [Cadence's `Account.Inbox`](https://cadence-lang.org/docs/language/accounts#account-inbox) to publish the - Capability from the child account & have the parent claim the Capability in a subsequent transaction. -2. Executing a multi-party signed transaction, signed by both the child and parent accounts. +1. Leverage [Cadence's `Account.Inbox`] to publish the Capability from the child account and have the parent claim the Capability in a subsequent transaction. +2. Execute a multi-party signed transaction, signed by both the child and parent accounts. Let's take a look at both. :::info -You'll want to consider whether you would like the parent account to be configured with some app-specific resources or -Capabilities and compose you multisig or claim transactions to include such configurations. +You'll want to consider whether you would like the parent account to be configured with some app-specific resources or Capabilities and compose you multisig or claim transactions to include such configurations. -For example, if your app deals with specific NFTs, you may want to configure the parent account with Collections for -those NFTs so the user can easily transfer them between their linked accounts. +For example, if your app deals with specific NFTs, you may want to configure the parent account with Collections for those NFTs so the user can easily transfer them between their linked accounts. ::: -### Publish & Claim +### Publish and claim #### Publish -Here, the account delegating access to itself links its `&Account` Capability, and publishes it to be claimed by the -designated parent account. +Here, the account delegates access to itself, which links its `&Account` Capability and publishes it to be claimed by the designated parent account. ```cadence publish_to_parent.cdc import "HybridCustody" @@ -295,8 +248,7 @@ transaction(parent: Address, factoryAddress: Address, filterAddress: Address) { #### Claim -On the other side, the receiving account claims the published `ChildAccount` Capability, adding it to the signer's -`HybridCustody.Manager.childAccounts` indexed on the child account's Address. +On the other side, the receiving account claims the published `ChildAccount` Capability, which adds it to the signer's `HybridCustody.Manager.childAccounts` indexed on the child account's Address. ```cadence redeem_account.cdc import "MetadataViews" @@ -356,13 +308,11 @@ transaction(childAddress: Address, filterAddress: Address?, filterPath: PublicPa ### Multi-Signed Transaction -We can combine the two transactions in [Publish](#publish) and [Claim](#claim) into a single multi-signed transaction to -achieve Hybrid Custody in a single step. +We can combine the two transactions in [Publish] and [Claim] into a single multi-signed transaction to achieve Hybrid Custody in a single step. :::info -Note that while the following code links both accounts in a single transaction, in practicality you may find it easier -to execute publish and claim transactions separately depending on your custodial infrastructure. +While this code links both accounts in a single transaction, in practicality you may find it easier to execute publish and claim transactions separately depending on your custodial infrastructure. ::: @@ -461,21 +411,13 @@ transaction(parentFilterAddress: Address?, childAccountFactoryAddress: Address, } ``` -## Onboarding Flows +## Onboarding flows -Given the ability to establish an account and later delegate access to a user, apps are freed from the constraints of -dichotomous custodial & self-custodial paradigms. A developer can choose to onboard a user via traditional Web2 identity -and later delegate access to the user's wallet account. Alternatively, an app can enable wallet authentication at the -outset, creating an app-specific account & linking with the user's wallet account. As specified above, these two flows -are known as "walletless" and "blockchain-native" onboarding respectively. Developers can choose to implement one for -simplicity or both for maximum flexibility. +Given the ability to establish an account and later delegate access to a user, apps are freed from the constraints of dichotomous custodial and self-custodial paradigms. A developer can choose to onboard a user via traditional Web2 identity and later delegate access to the user's wallet account. Alternatively, an app can enable wallet authentication at the outset, which creates an app-specific account & link with the user's wallet account. As specified above, these two flows are known as "walletless" and "blockchain-native" onboarding respectively. Developers can choose to implement one for simplicity or both for maximum flexibility. -### Walletless Onboarding +### Walletless onboarding -The following transaction creates an account, funding creation via the signer and adding the provided public key. You'll -notice this transaction is pretty much your standard account creation. The magic for you will be how you custody the key -for this account (locally, KMS, wallet service, etc.) in a manner that allows your app to mediate onchain interactions -on behalf of your user. +This transaction creates an account, funding creation via the signer and adding the provided public key. You'll notice this transaction is pretty much your standard account creation. The magic for you will be how you custody the key for this account (locally, KMS, wallet service, and so on) in a manner that allows your app to mediate onchain interactions on behalf of your user. ```cadence walletless_onboarding import "FungibleToken" @@ -531,31 +473,25 @@ transaction(pubKey: String, initialFundingAmt: UFix64) { } ``` -### Blockchain-Native Onboarding +### Blockchain-native onboarding This onboarding flow is really a single-transaction composition of the steps covered above. This is a testament to the power of the complex transactions you can compose on Flow with Cadence! :::info -Recall the [prerequisites](#prerequisites) needed to be satisfied before linking an account: +Recall the [prerequisites] needed to be satisfied before linking an account: -1. CapabilityFilter Filter saved and linked -2. CapabilityFactory Manager saved and linked as well as Factory implementations supporting the Capability Types you'll - want accessible from linked child accounts as Typed Capabilities. +1. CapabilityFilter Filter saved and linked. +2. CapabilityFactory Manager saved and linked as well as Factory implementations supporting the Capability Types you'll want accessible from linked child accounts as Typed Capabilities. ::: -#### Account Creation & Linking +#### Account creation & linking -Compared to walletless onboarding where a user does not have a Flow account, blockchain-native onboarding assumes a user -already has a wallet configured and immediately links it with a newly created app account. This enables the app to sign -transactions on the user's behalf via the new child account while immediately delegating control of that account to the -onboarding user's main account. +Compared to walletless onboarding where a user does not have a Flow account, blockchain-native onboarding assumes a user already has a wallet configured and immediately links it with a newly created app account. This allows the app to sign transactions on the user's behalf via the new child account and immediately delegate control of that account to the onboarding user's main account. -After this transaction, both the custodial party (presumably the client/app) and the signing parent account will have -access to the newly created account - the custodial party via key access and the parent account via their -`HybridCustody.Manager` maintaining the new account's `ChildAccount` Capability. +After this transaction, both the custodial party (presumably the client/app) and the signing parent account will have access to the newly created account - the custodial party via key access and the parent account via their `HybridCustody.Manager` that maintains the new account's `ChildAccount` Capability. ```cadence blockchain_native_onboarding.cdc #allowAccountLinking @@ -685,50 +621,42 @@ transaction( ## Funding & Custody Patterns -Aside from implementing onboarding flows & account linking, you'll want to also consider the account funding & custodial -pattern appropriate for the app you're building. The only pattern compatible with walletless onboarding (and therefore -the only one showcased above) is one in which the app custodies the child account's key and funds account creation. +Aside from the implementation of onboarding flows and Account Linking, you'll want to also consider the account funding & custodial pattern appropriate for the app you want to build. The only pattern compatible with walletless onboarding (and therefore the only one showcased above) is one in which the app custodies the child account's key and funds account creation. -In general, the funding pattern for account creation will determine to some extent the backend infrastructure needed to -support your app and the onboarding flow your app can support. For example, if you want to to create a service-less -client (a totally local app without backend infrastructure), you could forego walletless onboarding in favor of a -user-funded blockchain-native onboarding to achieve a hybrid custody model. Your app maintains the keys to the app -account locally to sign on behalf of the user, and the user funds the creation of the the account, linking to their main -account on account creation. This would be a **user-funded, app custodied** pattern. +In general, the funding pattern for account creation will determine, to some extent, the backend infrastructure needed to support your app and the onboarding flow your app can support. For example, if you want to to create a service-less client (a totally local app without backend infrastructure), you could forego walletless onboarding in favor of a user-funded blockchain-native onboarding to achieve a hybrid custody model. Your app maintains the keys to the app account locally to sign on behalf of the user, and the user funds the creation of the the account, which links to their main account on account creation. This would be a **user-funded, app custodied** pattern. -Again, custody may deserve some regulatory insight depending on your jurisdiction. If building for production, you'll -likely want to consider these non-technical implications in your technical decision-making. Such is the nature of -building in crypto. +Again, custody may deserve some regulatory insight depending on your jurisdiction. If you build for production, you'll likely want to consider these non-technical implications in your technical decision-making. Such is the nature of building in crypto. Here are the patterns you might consider: -### App-Funded, App-Custodied +### App-funded, app-custodied + +If you want to implement walletless onboarding, you can stop here as this is the only compatible pattern. In this scenario, a backend app account funds the creation of a new account and the app custodies the key for said account either on the user's device or some backend KMS. + +### App-funded, user-custodied -If you want to implement walletless onboarding, you can stop here as this is the only compatible pattern. In this -scenario, a backend app account funds the creation of a new account and the app custodies the key for said account -either on the user's device or some backend KMS. +In this case, the backend app account funds account creation, but adds a key to the account which the user custodies. For the app to act on the user's behalf, it has to be delegated access via `&Account` Capability which the backend app account would maintain in a `HybridCustody.Manager`. This means that the new account would have two parent accounts - the user's and the app. -### App-Funded, User-Custodied +While this pattern provides the user maximum ownership and authority over the child account, it may present unique considerations and edge cases for you as a builder depending on your app's access to the child account. Also note that this and the following patterns are incompatible with walletless onboarding in that the user must have a walletvpre-configured before onboarding. -In this case, the backend app account funds account creation, but adds a key to the account which the user custodies. In -order for the app to act on the user's behalf, it has to be delegated access via `&Account` Capability which the backend -app account would maintain in a `HybridCustody.Manager`. This means that the new account would have two parent accounts -- the user's and the app. +### User-funded, app-custodied -While this pattern provides the user maximum ownership and authority over the child account, it may present unique -considerations and edge cases for you as a builder depending on your app's access to the child account. Also note that -this and the following patterns are incompatible with walletless onboarding in that the user must have a wallet -pre-configured before onboarding. +As mentioned above, this pattern unlocks totally service-less architectures - just a local client and smart contracts. An authenticated user signs a transaction creating an account, adds the key that the client provides, and links the account as a child account. At the end of the transaction, hybrid custody is achieved and the app can sign with the custodied key on the user's behalf with the newly-created account. -### User-Funded, App-Custodied +### User-funded, user-custodied -As mentioned above, this pattern unlocks totally service-less architectures - just a local client & smart contracts. An -authenticated user signs a transaction creating an account, adding the key provided by the client, and linking the -account as a child account. At the end of the transaction, hybrid custody is achieved and the app can sign with the -custodied key on the user's behalf using the newly created account. +While perhaps not useful for most apps, this pattern may be desirable for advanced users who wish to create a shared access account themselves. The user funds account creation, adds keys they custody, and delegates secondary access to some other account. -### User-Funded, User-Custodied + -While perhaps not useful for most apps, this pattern may be desirable for advanced users who wish to create a shared -access account themselves. The user funds account creation, adding keys they custody, and delegates secondary access to -some other account. +[Account]: https://cadence-lang.org/docs/language/accounts#authaccount +[Cadence's `Account.Inbox`]: https://cadence-lang.org/docs/language/accounts#account-inbox +[Capability]: https://cadence-lang.org/docs/language/capabilities +[`CapabilityFilter`]: https://github.com/onflow/hybrid-custody/blob/main/contracts/CapabilityFilter.cdc +[`CapabilityFactory`]: https://github.com/onflow/hybrid-custody/blob/main/contracts/CapabilityFactory.cdc +[Claim]: #claim +[components and actions]: https://github.com/onflow/flips/pull/72 +[feature in Cadence]: https://github.com/onflow/flips/pull/53 +[walletless onboarding]: https://flow.com/post/flow-blockchain-mainstream-adoption-easy-onboarding-wallets +[prerequisites]: #prerequisites +[Publish]: #publish \ No newline at end of file diff --git a/docs/build/guides/account-linking/resources/account-linking-multiple-accounts.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/account-linking-multiple-accounts.png similarity index 100% rename from docs/build/guides/account-linking/resources/account-linking-multiple-accounts.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/account-linking-multiple-accounts.png diff --git a/docs/build/guides/account-linking/resources/account-linking-relational-diagram.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/account-linking-relational-diagram.png similarity index 100% rename from docs/build/guides/account-linking/resources/account-linking-relational-diagram.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/account-linking-relational-diagram.png diff --git a/docs/build/guides/account-linking/resources/account-linking-steps-high-level.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/account-linking-steps-high-level.png similarity index 100% rename from docs/build/guides/account-linking/resources/account-linking-steps-high-level.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/account-linking-steps-high-level.png diff --git a/docs/build/guides/account-linking/resources/account-structure.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/account-structure.png similarity index 100% rename from docs/build/guides/account-linking/resources/account-structure.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/account-structure.png diff --git a/docs/build/guides/emulator-output.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/emulator-output.png similarity index 100% rename from docs/build/guides/emulator-output.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/emulator-output.png diff --git a/docs/build/guides/flow-dapp-anatomy.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/flow-dapp-anatomy.png similarity index 100% rename from docs/build/guides/flow-dapp-anatomy.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/flow-dapp-anatomy.png diff --git a/docs/build/guides/flow-wallet.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/flow-wallet.png similarity index 100% rename from docs/build/guides/flow-wallet.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/flow-wallet.png diff --git a/docs/build/guides/hello-world-update-contract.gif b/docs/blockchain-development-tutorials/cadence/account-management/imgs/hello-world-update-contract.gif similarity index 100% rename from docs/build/guides/hello-world-update-contract.gif rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/hello-world-update-contract.gif diff --git a/docs/build/guides/account-linking/resources/hybrid_custody_conceptual_overview.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/hybrid_custody_conceptual_overview.png similarity index 100% rename from docs/build/guides/account-linking/resources/hybrid_custody_conceptual_overview.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/hybrid_custody_conceptual_overview.png diff --git a/docs/build/guides/account-linking/resources/hybrid_custody_high_level.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/hybrid_custody_high_level.png similarity index 100% rename from docs/build/guides/account-linking/resources/hybrid_custody_high_level.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/hybrid_custody_high_level.png diff --git a/docs/build/guides/account-linking/resources/hybrid_custody_low_level.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/hybrid_custody_low_level.png similarity index 100% rename from docs/build/guides/account-linking/resources/hybrid_custody_low_level.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/hybrid_custody_low_level.png diff --git a/docs/build/guides/account-linking/resources/linking-steps.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/linking-steps.png similarity index 100% rename from docs/build/guides/account-linking/resources/linking-steps.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/linking-steps.png diff --git a/docs/build/guides/query-helloWorld-contract.gif b/docs/blockchain-development-tutorials/cadence/account-management/imgs/query-helloWorld-contract.gif similarity index 100% rename from docs/build/guides/query-helloWorld-contract.gif rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/query-helloWorld-contract.gif diff --git a/docs/build/guides/top-shot-preview.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/top-shot-preview.png similarity index 100% rename from docs/build/guides/top-shot-preview.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/top-shot-preview.png diff --git a/docs/build/guides/user-login-hello-world.gif b/docs/blockchain-development-tutorials/cadence/account-management/imgs/user-login-hello-world.gif similarity index 100% rename from docs/build/guides/user-login-hello-world.gif rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/user-login-hello-world.gif diff --git a/docs/build/guides/welcome.png b/docs/blockchain-development-tutorials/cadence/account-management/imgs/welcome.png similarity index 100% rename from docs/build/guides/welcome.png rename to docs/blockchain-development-tutorials/cadence/account-management/imgs/welcome.png diff --git a/docs/blockchain-development-tutorials/cadence/account-management/index.md b/docs/blockchain-development-tutorials/cadence/account-management/index.md new file mode 100644 index 0000000000..2d4373b51b --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/account-management/index.md @@ -0,0 +1,180 @@ +--- +title: Account Linking +sidebar_position: 3 +description: Learn about Flow's unique account linking feature that enables shared ownership of accounts. Understand how accounts can be accessed, delegated, and managed through capabilities and hybrid custody. +keywords: + - account linking + - FLIP 72 + - account capabilities + - hybrid custody + - account access + - account delegation + - Flow accounts + - account ownership + - account security + - parent accounts + - child accounts + - account management + - Flow protocol + - account control + - custody model +--- + +# Account Linking + +Account Linking is a unique Flow concept that allows sharing ownership over [accounts]. To understand how we can achieve that, we must first understand how to access accounts on Flow. + +You can access accounts on flow in Cadence through two types, `PublicAccount` and `Account`. As the name implies, the `PublicAccount` type gives access to all public account information such as address, balance, storage capacity, etc., but doesn't allow changes to the account. The `Account` type (or more specifically, an [entitled]`&Account`) allows the same access as `PublicAccount` but also allows changes to the account, which includes adding or revoking account keys, managing the deployed contracts, as well as linking and publishing Capabilities. + +![Flow account structure](./imgs/account-structure.png) + +## Access Account + +When you access `Account`, you can modify account storage, so it's essential to mandate that the account being accessed signs all transactions, which safeguards this access. [Account entitlements] allow for more granular access control over the specific parts of the account that you can access from within the signed transaction. A transaction can list multiple authorizing account it wants to access as part of the `prepare` section of the transaction. Read more about transaction signing in the [transaction documentation]. + +Since access to the `Account` object allows state change, the idea of account ownership actually translates to the ability to access the underlying account. Traditionally, you might consider this the same as having key access on an account, but we'll see in just a minute how programmatic, ownership-level access is unlocked with [Cadence Capabilities] + +## Account Capabilities + +Before you continue with this section, you'll need a clear understanding of [Cadence Capabilities]. Advanced features such as Account Capabilities are powerful, but they can put your app or users at risk if used incorrectly. + +Cadence allows for Capabilities creation to delegate access to account storage, which means any account that obtains a valid Ccapability to another account object in the storage can access it. This is a powerful feature on its own - to access another account programmatically without the need for an active key on the accessible account. You can limit the access to the object when you create a Capability so your users can only access intended functions or fields. + +Account Linking is made possible by the extension of Capabilities on the `Account` object itself. Similar to how storage capabilities allow access to a value stored in an account's storage, `&Account` Capabilities allow delegated access to the issuing `Account`. These Capabilities allow for access to key assignment, contract deployment, and other privileged actions on the delegating `Account` - which effectively shares account ownership without the need to add or share a key. The delegating account can revoke this Capability at any time. + +### Create Account Links + +When we refer to 'Account Linking,' we mean that the parent account creates an `&Account` Capability and published to another account. The account that owns the `&Account` Capability which was made available to another account is the child account. The account in possession of the Capability given by the child account becomes its parent account. + +![Account linking on Flow relational diagram](./imgs/account-linking-relational-diagram.png) + +You can create a link between two current accounts on Flow in two steps: + +1. A child account creates an `&Account` Capability and publishes it to the parent account. +2. The parent account, claims that Capability and can access the child's account through it. + +![Account linking steps on Flow](./imgs/account-linking-steps-high-level.png) + +These two steps are implemented in Cadence as two transactions: + +**\*\***\*\*\*\***\*\***\*\*\*\***\*\***\*\*\*\***\*\***Create capability**\*\***\*\*\*\***\*\***\*\*\*\***\*\***\*\*\*\***\*\*** + +The account B creates and publishes the `&Account` Capability to the account A at the address `0x01` + +```cadence +#allowAccountLinking + +transaction { + prepare(signer: auth(IssueAccountCapabilityController, PublishInboxCapability) &Account) { + // Issue a fully-entitled account capability + let capability = signer.capabilities + .account + .issue() + // Publish the capability for the specified recipient + signer.inbox.publish(capability, name: "accountCapA", recipient: 0x1) + } +} +``` + +\***\*\*\*\*\*\*\***\*\*\*\*\***\*\*\*\*\*\*\***Claim capability\***\*\*\*\*\*\*\***\*\*\*\*\***\*\*\*\*\*\*\*** + +The account A claims the Capability published by account B. + +```cadence +transaction { + prepare(signer: auth(ClaimInboxCapability) &Account) { + let capabilityName = "accountCapB" + let providerAddress = 0x2 + // Claim the capability published by the account 0x2 + let capability = signer.inbox + .claim( + capabilityName, + provider: providerAddress + ) ?? panic( + "Capability with name ".concat(capabilityName) + .concat(" from provider ").concat(providerAddress.toString()) + .concat(" not found") + ) + // Simply borrowing an Account reference here for demonstration purposes + let accountRef = capability.borrow()! + } +} +``` + +## What is Account Linking most useful for? + +Account Linking was specifically designed to allow smooth and seamless custodial onboarding of users to your Flow-based application without the requirement of a wallet to do so. This pattern overcomes both the technical hurdle, as well as user's reluctance to install a wallet, which opens access to Flow applications to every user. Users can experience an app without any delay and still offer a path to self-sovreign ownership. + +Naturally, users may expect to use their account with another application, or otherwise move assets stored in that account elsewhere - at minimum from their wallet. When an app initially leverages Account Linking, the app creates the account instead of the user and stores that user's specific state in the app-created account. At a later point, users can take ownership of the app account if they possess a full [Flow account], which they can get if they install a wallet app. + +Account Linking allows users to possess multiple linked child accounts from different apps. Access complexities associated with those child accounts are eliminated if you abstract access to them through the user's parent account. + +:::info + +Simply put, child accounts are accessed and can be treated as a seamless part of the parent account. + +::: + +All assets in the app account can now jump the walled garden to play in the rest of the Flow ecosystem. The user does not need to rely on the custodial app to execute transactions moving assets from the child account as the parent account already has access to the assets in the child account. + +![Multiple parent-child accounts on Flow](./imgs/account-linking-multiple-accounts.png) + +This shared control over the digital items in the in-app account allows users to establish real ownership of the items beyond the context of the app, where they can use their parent account to view inventory, take the items to other apps in the ecosystem, such as a marketplace or a game. + +Most importantly, users can do this without the need to transfer the digital items between accounts, which makes it seamless to continue to use the original app and enjoy their assets in other contexts. + +## Security considerations + +Account Linking is a _very_ powerful Cadence feature, and thus you must treat it with care. So far in this document, we've discussed Account Linking between two accounts we own, even if a third-party application manages the child account. But, we can't make the same trust assumptions about custodial accounts in the real world. + +If we create an `&Account` Capability and publish it to an account we don't own, we give that account full access to our account. This should be seen as an anti-pattern. + +:::warning + +If you create an `&Account` Capability and share it with a third-party account, you effectively give that person your account's private keys. + +::: + +Because unfiltered account linking can be dangerous, Flow introduces the `HybridCustody` contract that helps custodial applications regulate access and allows parent accounts to manage their many child accounts and assets within them. + +Learn more about it in the [Working With Parent Accounts] documentation. + +## Hybrid custody and Account Linking + +Apps need assurances that their own resources are safe from malicious actors, so to permit full access might not be what they want. Hybrid custody contracts will allow the app to maintain control of their managed accounts, but they can: + +1. Share capabilities freely, with a few built-in controls over the types of capabilities that can be retrieved by + parent accounts via helper contracts (the `CapabilityFactory`, and `CapabilityFilter`). +2. Share additional capabilities (public or private) with a parent account via a `CapabilityDelegator` resource. + + + +### Guides + +- [Building Walletless Applications Using Child Accounts] covers how apps can leverage Account Linking to create a seamless user experience and allow future self-custody. +- [Working With Parent Accounts] covers features activated by the core `HybridCustody` contract to access child account assets from parent accounts. This is useful for apps like marketplaces or wallets that work with accounts that have potential child accounts. + +### Resources + +- [Forum Post] where core concepts were introduced and discussed. +- [GitHub repository] where `HybridCustody` core contracts and scripts are maintained. Check out the repository for more advanced script or transaction examples. +- [Example] - Account Linking project with [Magic]. +- [Starter template] for [Niftory] Account Linking API. + + + + +[accounts]: ../../../build/cadence/basics/accounts.md +[Account entitlements]: https://cadence-lang.org/docs/language/accounts/#performing-write-operations +[Building Walletless Applications Using Child Accounts]: ./child-accounts.md +[Cadence capabilities]: https://cadence-lang.org/docs/language/capabilities +[entitled]: https://cadence-lang.org/docs/language/access-control#entitlements) +[Flow account]: ../../../build/cadence/basics/accounts.md +[Forum Post]: https://forum.flow.com/t/hybrid-custody/4016 +[GitHub repository]: https://github.com/onflow/hybrid-custody +[Example]: https://github.com/jribbink/magic-link-hc-sample/ +[Magic]: https://magic.link/ +[Starter template]: https://github.com/Niftory/niftory-samples/tree/main/walletless-onboarding +[Niftory]: https://niftory.com/ +[transaction documentation]: ../../../build/cadence/basics/transactions.md +[Working With Parent Accounts]: ./parent-accounts.md \ No newline at end of file diff --git a/docs/build/guides/account-linking/parent-accounts.md b/docs/blockchain-development-tutorials/cadence/account-management/parent-accounts.md similarity index 55% rename from docs/build/guides/account-linking/parent-accounts.md rename to docs/blockchain-development-tutorials/cadence/account-management/parent-accounts.md index 4313493f4a..0b3c5b8f34 100644 --- a/docs/build/guides/account-linking/parent-accounts.md +++ b/docs/blockchain-development-tutorials/cadence/account-management/parent-accounts.md @@ -20,127 +20,82 @@ keywords: - account security --- -In this doc, we'll continue from the perspective of a wallet or marketplace app seeking to facilitate a unified account -experience, abstracting away the partitioned access between accounts into a single dashboard for user interactions on -all their owned assets. +# Working With Parent Accounts + +In this tutorial, we'll continue from the perspective of a wallet or marketplace app who seeks to facilitate a unified account experience, and abstract away the partitioned access between accounts into a single dashboard for user interactions on all their owned assets. ## Objectives -- Understand the Hybrid Custody account model -- Differentiate between restricted child accounts and unrestricted owned accounts -- Get your app to recognize "parent" accounts along with any associated "child" accounts +- Understand the Hybrid Custody account model. +- Differentiate between restricted child accounts and unrestricted owned accounts. +- Get your app to recognize "parent" accounts along with any associated "child" accounts. - View Fungible and NonFungible Token metadata relating to assets across all of a user's associated accounts - their - wallet-mediated "parent" account and any hybrid custody model "child" accounts -- Facilitate transactions acting on assets in child accounts + wallet-mediated "parent" account and any hybrid custody model "child" accounts. +- Facilitate transactions acting on assets in child accounts. ## Design Overview :::info -TL;DR: An account's -[`HybridCustody.Manager`](https://github.com/onflow/hybrid-custody/blob/main/contracts/HybridCustody.cdc) is the entry -point for all of a user's associated accounts. +TL;DR: An account's [`HybridCustody.Manager`] is the entry point for all of a user's associated accounts. ::: -The basic idea in the Hybrid Custody model is relatively simple. A parent account is one that has received delegated -(albeit restricted) access on another account. The account which has delegated authority over itself to the parent -account is the child account. +The basic idea in the Hybrid Custody model is relatively simple. A parent account is one that has received delegated (albeit restricted) access on another account. The account which has delegated authority over itself to the parent account is the child account. -In the [Hybrid Custody Model](https://forum.flow.com/t/hybrid-custody/4016), this child account would have shared -access between the app - the entity which created and likely custodies the account - and the linked parent account. +In the [Hybrid Custody Model], this child account would have shared access between the app - the entity which created and likely custodies the account - and the linked parent account. -How does this delegation occur? Typically when we think of shared account access in crypto, we think keys. However, -Cadence enables [accounts to link Capabilities on -themselves](https://cadence-lang.org/docs/language/accounts/capabilities#accountcapabilities) and issue those -Capabilities to other parties (more on [capability-based access -here](https://cadence-lang.org/docs/language/capabilities)). +How does this delegation occur? Typically when we think of shared account access in crypto, we think keys. However, Cadence allows [accounts to link Capabilities on themselves] and issue those Capabilities to other parties (more on [capability-based access here]). -This feature has been leveraged in an ecosystem standard so that apps can implement a hybrid custody model whereby the app -creates an account it controls, then later delegates access on that account to the user once they've authenticated with -their wallet. +This feature was leveraged in an ecosystem standard so that apps can implement a hybrid custody model whereby the app creates an account it controls, then later delegates access on that account to the user once they've authenticated with their wallet. -All related constructs are used together in the [`HybridCustody` -contract](https://github.com/onflow/hybrid-custody/tree/main) to define the standard. +All related constructs are used together in the [`HybridCustody` contract] to define the standard. -Parent accounts own a `Manager` resource which stores Capabilities to `ChildAccount` (restricted access) and -`OwnedAccount` (unrestricted access) resources, both of which are stored in any given child account. +Parent accounts own a `Manager` resource which stores Capabilities to `ChildAccount` (restricted access) and `OwnedAccount` (unrestricted access) resources, both of which are stored in any given child account. -Therefore, the presence of a `Manager` in an account implies there are potentially associated accounts for which the -owning account has delegated access. This resource is intended to be configured with a public Capability that enables -querying of an account's child account addresses via `getAccountAddresses()` and `getOwnedAccountAddresses()`. As you can -deduce from these two methods, there is a notion of "owned" accounts which we'll expand on in a bit. +Therefore, the presence of a `Manager` in an account implies there are potentially associated accounts for which the owning account has delegated access. This resource is intended to be configured with a public Capability that allows you to query an account's child account addresses via `getAccountAddresses()` and `getOwnedAccountAddresses()`. As you can deduce from these two methods, there is a notion of "owned" accounts which we'll expand on later. -A wallet or marketplace wishing to discover all of a user's accounts and assets within them can do so by first looking -to the user's `Manager`. +If a wallet or marketplace wants to discover all of a user's accounts and assets within them, they can first look to the user's `Manager`. -### Identifying Account Hierarchy +### Identify account hierarchy -To clarify, insofar as the standard is concerned, an account is a parent account if it contains a `Manager` resource, -and an account is a child account if it contains at minimum an `OwnedAccount` or additionally a `ChildAccount` resource. +To clarify, insofar as the standard is concerned, an account is a parent account if it contains a `Manager` resource, and an account is a child account if it contains at minimum an `OwnedAccount` or additionally a `ChildAccount` resource. -Within a user's `Manager`, its mapping of `childAccounts` points to the addresses of its child accounts in each key, -with corresponding values giving the `Manager` access to those accounts via corresponding `ChildAccount` Capability. +Within a user's `Manager`, its mapping of `childAccounts` points to the addresses of its child accounts in each key, with corresponding values that give the `Manager` access to those accounts via corresponding `ChildAccount` Capability. -![HybridCustody Conceptual Overview](./resources/hybrid_custody_conceptual_overview.png) +![HybridCustody Conceptual Overview](./imgs/hybrid_custody_conceptual_overview.png) -Likewise, the child account's `ChildAccount.parentAddress` (which owns a `Manager`) points to the user's account as its -parent address. This makes it easy to both identify whether an account is a parent, child, or both, and its associated -parent/child account(s). +Likewise, the child account's `ChildAccount.parentAddress` (which owns a `Manager`) points to the user's account as its parent address. This makes it easy to both identify whether an account is a parent, child, or both, and its associated parent or child account(s). -`OwnedAccount` resources underly all account delegations, so can have multiple parents whereas `ChildAccount`s are 1:1. -This provides more granular revocation as each parent account has its own Capability path on which its access relies. +`OwnedAccount` resources underly all account delegations, so can have multiple parents whereas `ChildAccount`s are 1:1. This provides more granular revocation as each parent account has its own Capability path on which its access relies. #### Restricted vs. Owned Accounts -It's worth noting here that `ChildAccount` Capabilities enable access to the underlying account according to rules -configured by the child account delegating access. The `ChildAccount` maintains these rules along with an `OwnedAccount` -Capability within which the `&Account` Capability is stored. Anyone with access to the surface level `ChildAccount` -can then access the underlying `Account`, but only according the pre-defined rule set. These rules are fundamentally -a list of Types that can/cannot be retrieved from an account. + `ChildAccount` Capabilities allow access to the underlying account according to rules configured when the child account delegates access. The `ChildAccount` maintains these rules along with an `OwnedAccount` Capability within which the `&Account` Capability is stored. Anyone with access to the surface level `ChildAccount` can then access the underlying `Account`, but only within the pre-defined rule set. These rules are fundamentally a list of Types that can or can't be retrieved from an account. -The app developer can codify these rule sets on allowable Capability types in a -[`CapabilityFilter`](https://github.com/onflow/hybrid-custody/blob/main/contracts/CapabilityFilter.cdc) along with a -[`CapabilityFactory`](https://github.com/onflow/hybrid-custody/blob/main/contracts/CapabilityFactory.cdc) defining retrieval -patterns for those Capabilities. When delegation occurs, the developer would provide the `CapabilityFilter` and -`CapabilityFactory` Capabilities to an `OwnedAccount` resource which stores them in a `ChildAccount` resource. Then, -capabilities are created for the `OwnedAccount` and `ChildAccount` resource and are given to the specified parent -account. +The app developer can codify these rule sets on allowable Capability types in a [`CapabilityFilter`] along with a [`CapabilityFactory`] defining retrieval patterns for those Capabilities. When delegation occurs, the developer would provide the `CapabilityFilter` and `CapabilityFactory` Capabilities to an `OwnedAccount` resource which stores them in a `ChildAccount` resource. Then, capabilities are created for the `OwnedAccount` and `ChildAccount` resource and are given to the specified parent account. -So, if an app developer wants to enable Hybrid Custody but doesn't want to allow parent accounts to access FungibleToken -Vaults, for example, the app developer can codify rule sets enumerating allowable Capability types in a -`CapabilityFilter` along with a `CapabilityFactory` defining retrieval patterns for those Capabilities. +So, if an app developer wants to turn on Hybrid Custody but doesn't want to allow parent accounts to access FungibleToken Vaults, for example, the app developer can codify rule sets enumerating allowable Capability types in a `CapabilityFilter` along with a `CapabilityFactory` defining retrieval patterns for those Capabilities. -When delegation occurs, they would provide the `CapabilityFilter` and `CapabilityFactory` Capabilities to an -`OwnedAccount`. This `OwnedAccount` then wraps the given filter & factory Capabilities in a `ChildAccount` along with a -Capability to itself before publishing the new `ChildAccount` Capability for the specified parent account to claim. +When delegation occurs, they would provide the `CapabilityFilter` and `CapabilityFactory` Capabilities to an `OwnedAccount`. This `OwnedAccount` then wraps the given filter & factory Capabilities in a `ChildAccount` along with a Capability to itself before it publishes the new `ChildAccount` Capability for the specified parent account to claim. :::info -Note that by enumerating allowable Types in your `CapabilityFilter.Filter` implementation, you're by default excluding -access to anything other than the Types you declare as allowable. +If you enumerate allowable Types in your `CapabilityFilter.Filter` implementation, you by default exclude access to anything other than the Types you declare as allowable. ::: -As mentioned earlier, `Manager`s also maintain access to "owned" accounts - accounts which define unrestricted access as -they allow direct retrieval of encapsulated `&Account` Capabilities. These owned accounts, found in `Manager.ownedAccounts`, -are simply `OwnedAccount` Capabilities instead of `ChildAccount` Capabilities. +As mentioned earlier, `Manager`s also maintain access to "owned" accounts - accounts which define unrestricted access as they allow direct retrieval of encapsulated `&Account` Capabilities. These owned accounts, found in `Manager.ownedAccounts`, are simply `OwnedAccount` Capabilities instead of `ChildAccount` Capabilities. -![HybridCustody Total Overview](./resources/hybrid_custody_low_level.png) +![HybridCustody Total Overview](./imgs/hybrid_custody_low_level.png) ### Considerations -Do note that this construction does not prevent an account from having multiple parent accounts or a child account from -being the parent to other accounts. While initial intuition might lead one to believe that account associations are a -tree with the user at the root, the graph of associated accounts among child accounts may lead to cycles of association. +This construction does not prevent an account from having multiple parent accounts or a child account from being the parent to other accounts. While initial intuition might lead one to believe that account associations are a tree with the user at the root, the graph of associated accounts among child accounts may lead to cycles of association. -We believe it would be unlikely for a use case to demand a user delegates authority over their main account (in fact -we'd discourage such constructions), but delegating access between child accounts could be useful. As an example, -consider a set of local game clients across mobile and web platforms, each with self-custodied app accounts having -delegated authority to each other while both are child accounts of the user's main account. +We believe it's unlikely for a use case to demand a user delegates authority over their main account (in fact we'd discourage such constructions), but it might be useful to delegate access between child accounts. As an example, consider a set of local game clients across mobile and web platforms, each with self-custodied app accounts that have delegated authority to each other while both are child accounts of the user's main account. -Ultimately, it will be up to the implementing wallet/marketplace how far down the graph of account associations they'd -want to traverse and display to the user. +Ultimately, it's' up to the wallet or marketplace who implements this how far down the graph of account associations they'd want to traverse and display to the user. ## Implementation @@ -151,14 +106,14 @@ From the perspective of a wallet or marketplace app, some relevant things to kno - What NFTs are owned by this user across all associated accounts? - What are the balances of all FungibleTokens across all associated accounts? -And with respect to acting on the assets of child accounts and managing child accounts themselves: +And with respect to actions on the assets of child accounts and management of the child accounts themselves: -- Accessing an NFT from a linked account's Collection -- Removing a linked account +- Access an NFT from a linked account's Collection +- Remove a linked account ## Examples -### Query Whether an Address Has Associated Accounts +### Query whether an address has associated accounts This script will return `true` if a `HybridCustody.Manager` is stored and `false` otherwise @@ -174,10 +129,9 @@ access(all) fun main(parent: Address): Bool { } ``` -### Query All Accounts Associated with Address +### Query all accounts associated with address -The following script will return an array of addresses associated with a given account's address, inclusive of the -provided address. If a `HybridCustody.Manager` is not found, the script will revert. +The following script will return an array of addresses associated with a given account's address, inclusive of the provided address. If a `HybridCustody.Manager` is not found, the script will revert. ```cadence get_child_addresses.cdc import "HybridCustody" @@ -190,20 +144,16 @@ access(all) fun main(parent: Address): [Address] { } ``` -### Query All Owned NFT Metadata +### Query all owned NFT metadata -While it is possible to iterate over the storage of all associated accounts in a single script, memory limits prevent -this approach from scaling well. +While it is possible to iterate over the storage of all associated accounts in a single script, memory limits prevent this approach from scaling well. -Since some accounts hold thousands of NFTs, we recommend breaking up iteration, utilizing several queries to iterate -over accounts and the storage of each account. Batching queries on individual accounts may even be required based on the -number of NFTs held. +Since some accounts hold thousands of NFTs, we recommend that you break up iteration and use several queries to iterate over accounts and the storage of each account. Based on the number of NFTs held, you might be required to batch the queries on individual accounts. -1. Get all associated account addresses (see above) -2. Looping over each associated account address client-side, get each address's owned NFT metadata +1. Get all associated account addresses (see above). +2. Loop over each associated account address client-side and get each address's owned NFT metadata. -For simplicity, we'll show a condensed query, returning NFT display views from all accounts associated with a given -address for a specified NFT Collection path. +For simplicity, we'll show a condensed query that returns NFT display views from all accounts associated with a given address for a specified NFT Collection path. ```cadence get_nft_display_view_from_public.cdc import "NonFungibleToken" @@ -267,16 +217,14 @@ fun main(address: Address, resolverCollectionPath: PublicPath): {Address: {UInt6 } ``` -At the end of this query, the caller will have a mapping of `Display` views indexed on the NFT ID and grouped by account -Address. Note that this script does not take batching into consideration and assumes that each NFT resolves the -`MetadataViews.Display` view type. +At the end of this query, the caller will have a mapping of `Display` views indexed on the NFT ID and grouped by account Address. This script does not take batching into consideration and assumes that each NFT resolves the `MetadataViews.Display` view type. -### Query All Account FungibleToken Balances +### Query all acount FungibleToken balances -Similar to the previous example, we recommend breaking up this task due to memory limits. +Similar to the previous example, we recommend that you break up this task due to memory limits. -1. Get all linked account addresses (see above) -2. Looping over each associated account address client-side, get each address's owned FungibleToken Vault metadata +1. Get all linked account addresses (see above). +2. Loop over each associated account address client-side and get each address's owned FungibleToken Vault metadata. However, we'll condense both of these steps down into one script for simplicity: @@ -351,18 +299,13 @@ fun main(address: Address): {Address: {Type: UFix64}} { The above script returns a dictionary of balances indexed on the type and further grouped by account Address. -The returned data at the end of address iteration should be sufficient to achieve a unified balance of all Vaults of -similar types across all of a user's associated account as well as a more granular per account view. +The returned data at the end of address iteration should be sufficient to achieve a unified balance of all Vaults of similar types across all of a user's associated account as well as a more granular per account view. -You might consider resolving -[`FungibleTokenMetadataViews`](https://github.com/onflow/flow-ft/blob/master/contracts/FungibleTokenMetadataViews.cdc) -to aggregate more information about the underlying Vaults. +You might resolve [`FungibleTokenMetadataViews`] to aggregate more information about the underlying Vaults. -### Access NFT in Child Account from Parent Account +### Access NFT in child account from parent account -A user with NFTs in their child accounts will likely want to utilize said NFTs. In this example, the user will sign a -transaction with their authenticated account that retrieves a reference to a child account's -`NonFungibleToken.Provider`, enabling withdrawal from the child account having signed as the parent account. +A user with NFTs in their child accounts will likely want to utilize said NFTs. In this example, the user signs a transaction with their authenticated account that retrieves a reference to a child account's `NonFungibleToken.Provider`, which allows withdrawal from the child account that signs as the parent account. ```cadence withdraw_nft_from_child.cdc import "NonFungibleToken" @@ -422,27 +365,19 @@ transaction( ``` -At the end of this transaction, you withdrew an NFT from the specified account using an NFT `Provider` Capability. A -similar approach could get you any allowable Capabilities from a signer's child account. +At the end of this transaction, you withdrew an NFT from the specified account with an NFT `Provider` Capability. A similar approach could get you any allowable Capabilities from a signer's child account. -### Revoking Secondary Access on a Linked Account +### Revoke secondary access on a linked account -The expected uses of child accounts for progressive onboarding implies that they will be accounts with shared access. A -user may decide that they no longer want secondary parties to have access to the child account. +The expected uses of child accounts for progressive onboarding implies that they will be accounts with shared access. A user may decide that they no longer want secondary parties to have access to the child account. -There are two ways a party can have delegated access to an account - keys and `&Account` Capability. With -`ChildAccount` mediated access, a user wouldn't be able to revoke anyone's access except for their own. With -unrestricted access via `OwnedAccount`, one could remove parents (`OwnedAccount.removeParent(parent: Address)`) thereby -unlinking relevant Capabilities and further destroying their `ChildAccount` and `CapabilityDelegator` resources. +There are two ways a party can have delegated access to an account - keys and `&Account` Capability. With `ChildAccount` mediated access, a user wouldn't be able to revoke anyone's access except for their own. With unrestricted access via `OwnedAccount`, one could remove parents (`OwnedAccount.removeParent(parent: Address)`) thereby unlinking relevant Capabilities and further destroying their `ChildAccount` and `CapabilityDelegator` resources. -For now, we recommend that if users want to revoke secondary access, they transfer any assets from the relevant child -account and remove it from their `Manager` altogether. +For now, we recommend that if users want to revoke secondary access, they transfer any assets from the relevant child account and remove it from their `Manager` altogether. ### Remove a Child Account -As mentioned above, if a user no longer wishes to share access with another party, it's recommended that desired assets -be transferred from that account to either their main account or other linked accounts and the linked account be removed -from their `HybridCustody.Manager`. Let's see how to complete that removal. +As mentioned above, if a user no longer wishes to share access with another party, we recommended that they transfer desired assets from that account to either their main account or other linked accounts and the linked account be removed from their `HybridCustody.Manager`. Let's see how to complete that removal. ```cadence remove_child_account.cdc import "HybridCustody" @@ -460,5 +395,16 @@ transaction(child: Address) { After removal, the signer no longer has delegated access to the removed account via their `Manager` and the caller is removed as a parent of the removed child. -Note also that it's possible for a child account to remove a parent. This is necessary to give application developers +It's also possible for a child account to remove a parent. This is necessary to give application developers and ultimately the owners of these child accounts the ability to revoke secondary access on owned accounts. + + + +[`HybridCustody.Manager`]: https://github.com/onflow/hybrid-custody/blob/main/contracts/HybridCustody.cdc +[Hybrid Custody Model]: https://forum.flow.com/t/hybrid-custody/4016 +[accounts to link Capabilities on themselves]: https://cadence-lang.org/docs/language/accounts/capabilities#accountcapabilities +[capability-based access here]: https://cadence-lang.org/docs/language/capabilities. +[`HybridCustody` contract]: https://github.com/onflow/hybrid-custody/tree/main +[`CapabilityFilter`]: https://github.com/onflow/hybrid-custody/blob/main/contracts/CapabilityFilter.cdc +[`CapabilityFactory`]: https://github.com/onflow/hybrid-custody/blob/main/contracts/CapabilityFactory.cdc +[`FungibleTokenMetadataViews`]: https://github.com/onflow/flow-ft/blob/master/contracts/FungibleTokenMetadataViews.cdc \ No newline at end of file diff --git a/docs/blockchain-development-tutorials/cadence/cadence-advantages/compose-with-cadence-transactions.md b/docs/blockchain-development-tutorials/cadence/cadence-advantages/compose-with-cadence-transactions.md new file mode 100644 index 0000000000..84cfb285a6 --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/cadence-advantages/compose-with-cadence-transactions.md @@ -0,0 +1,439 @@ +--- +title: Compose with Cadence Transactions +description: Learn how to compose with someone else's on-chain contracts by writing a Cadence transaction that conditionally calls a public contract on testnet, then extend it to mint NFTs when conditions are met—no redeploy required. +sidebar_position: 1 +keywords: + - Cadence transactions + - composition + - public contracts + - Flow testnet + - Flow CLI + - commands + - dependency manager + - Counter + - ExampleNFT + - NonFungibleToken + - NFT minting + - onchain reads + - onchain writes + - Flowscan +--- + +# Compose wth Cadence Transactions + +In this tutorial, you'll **compose with someone else's contracts** on Flow testnet. You'll write a Cadence transaction that reads public state from a contract named `Counter` and only increments the counter when it is odd. Then you'll extend the transaction to mint NFTs when the counter is odd, demonstrating how to compose multiple contracts in a single transaction. Everything runs against testnet using the Flow CLI and the dependency manager. + +You can use transactions developed and tested this way from the frontend of your app. + +## Objectives + +After you complete this guide, you will be able to: + +- Configure the Flow CLI _dependency manager_ to import named contracts from **testnet**. +- Write a Cadence **transaction** that reads and writes to a public contract you didn't deploy. +- Run the transaction on **testnet** with a funded account using the Flow command line interface (CLI). +- Extend the transaction to compose multiple public contracts (`Counter` + `ExampleNFT` + `NonFungibleToken`) without redeploying anything. +- Set up NFT collections and mint NFTs conditionally based on on-chain state. +- View transaction results and NFT transfers using Flowscan. + +## Prerequisites + +- [Flow CLI installed] +- A **funded testnet account** to sign transactions + See **Create accounts** and **Fund accounts** in the Flow CLI commands: + - Create: https://developers.flow.com/build/tools/flow-cli/commands#create-accounts + - Fund: https://developers.flow.com/build/tools/flow-cli/commands#fund-accounts + +## Get started + +Create a [new project] with the [Flow CLI]: + +```bash +flow init +``` + +Follow the prompts and create a `Basic Cadence project (no dependencies)`. + +### Install dependencies + +We will resolve imports **using string format** (`import "Counter"`) with the [dependency manager]. + +We recommend that you work this way with imports of already-deployed contracts. You should also use the CLI to create new files and add existing ones to `flow.json`. + +:::warning + +For this exercise, **delete** the existing contract entry for `Counter` from your `flow.json`. You could also use an alias here, but this is simpler since you won't deploy the `Counter` contract. + +::: + +You can install dependencies for already deployed contracts, whether yours or those that others deployed: + +```bash +# Add a deployed instance of the Counter contract +flow dependencies install testnet://0x8a4dce54554b225d.Counter +``` + +Pick `none` for the deployment account as you won't need to redeploy these contracts. + +After they're installed with the dependency manager, Cadence imports like `import "Counter"` will resolve to the testnet address when they send transactions on testnet. + +:::info + +In Cadence, contracts deploy to the account storage of the deploying address. Due to security reasons, the same private key produces different address on Cadence testnet and mainnet. One of the features of the dependency manager is to automatically select the right address for imports based on the network you're working on. + +::: + +--- + +## Compose with the public `Counter` contract + +Review the `Counter` simple contract that's created as an example by `flow init`: + +```cadence +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 + } + + // Public function to increment the counter + access(all) fun increment() { + self.count = self.count + 1 + emit CounterIncremented(newCount: self.count) + } + + // Public function to decrement the counter + access(all) fun decrement() { + self.count = self.count - 1 + emit CounterDecremented(newCount: self.count) + } + + // Public function to get the current count + view access(all) fun getCount(): Int { + return self.count + } +} +``` + +Unlike in Solidity, apps aren't limited to the functionality deployed in a smart contract. One of the ways you can expand your app is to write new transactions that call multiple functions in multiple contracts, with branching based on conditions and state, with a single call and a single signature. You don't need to deploy a new contract, use a proxy, or switch to V2. + +In this simple example, imagine that you've already deployed a product that has thousands of users and is dependent on the `Counter` smart contract. After a time, you realize that a significant portion of your users only wish to use the `increment` feature if the current `count` is odd, to try and make the number be even. + +In Cadence, this sort of upgrade is easy, even if you didn't anticipate the need at contract deployment. + +All you need to do is to write a new [transaction] that **reads** the current count from `Counter` and **only increments** it if the value is odd. + +Create a new [transaction] called `IncrementIfOdd` using the Flow CLI: + +```bash +flow generate transaction IncrementIfOdd +``` + +Start by adding the code from the existing `IncrementCounter` [transaction]: + +```cadence +import "Counter" + +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())) + } +} +``` + +Then, modify it to handle the new feature: + +```cadence +import "Counter" + +transaction() { + prepare(account: &Account) {} + + execute { + // Get the current count from the Counter contract (public read) + let currentCount = Counter.getCount() + + // Print the current count + log("Current count: ".concat(currentCount.toString())) + + // If odd (remainder when divided by 2 is not 0), increment + if currentCount % 2 != 0 { + Counter.increment() + log("Counter was odd, incremented to: ".concat(Counter.getCount().toString())) + } else { + log("Counter was even, no increment performed") + } + } +} +``` + +:::info + +As with most blockchains, `logs` are not exposed or returned when transactions are run on testnet or mainnet, but they are visible in the console when you use the [emulator]. + +::: + +### Run on testnet + +You need a **funded** testnet account to sign the transaction. For development tasks, the CLI has [account commands] that you can use to create and manage your accounts. + +Create and fund an account called `testnet-account`: + +```bash +# If needed, create a testnet account (one-time) +flow accounts create --network testnet + +# If needed, fund it (one-time) +flow accounts fund testnet-account +``` + +:::danger + +As with other blockchain accounts, after an account's private key is compromised, anyone with that key completely controls an account and it's assets. **Never** put private keys directly in `flow.json`. + +::: + +When you create an account with the CLI, it automatically puts the private key in a `.pkey` file, which is already in `.gitignore`. + +[Send the transaction] to testnet, signed with `testnet-account`: + +```bash +flow transactions send cadence/transactions/IncrementIfOdd.cdc --signer testnet-account --network testnet +``` + +You will see logs that show the prior value and whether the increment occurred. + +:::tip + +You could trigger this same transaction **from an app** and **signed by a wallet** with a single user click. Your dApp would assemble and submit this exact Cadence transaction with your preferred client library, and the user's wallet would authorize it. + +::: + +--- + +## Extend with NFT minting + +Now lets take our composition to the next level and add NFT minting functionality when the counter is odd. We'll use an example NFT contract that's already deployed on testnet. + +This is a silly use case, but it demonstrates the complex use cases you can add to your apps, after contract deployment, and even if you aren't the author of any of the contracts! + +### Install the NFT contract + +First, let's install the ExampleNFT contract dependency: + +```bash +flow dependencies install testnet://012e4d204a60ac6f.ExampleNFT +``` + +:::warning + +This repository uses different deployments for core contracts than those that the Flow CLI installs. If you previously installed core contract dependencies (like `NonFungibleToken`, `MetadataViews`, etc.) with the CLI, manually delete all `dependencies` except `Counter` from your `flow.json` file to avoid conflicts. + +::: + +### Understand NFT minting + +Let's look at how NFT minting works with this contract. The [MintExampleNFT transaction] shows the pattern: + +```cadence +import "ExampleNFT" +import "NonFungibleToken" + +transaction( + recipient: Address, + name: String, + description: String, + thumbnail: String, + creator: String, + rarity: String +) { + let recipientCollectionRef: &{NonFungibleToken.Receiver} + + prepare(signer: &Account) { + self.recipientCollectionRef = getAccount(recipient) + .capabilities.get<&{NonFungibleToken.Receiver}>(ExampleNFT.CollectionPublicPath) + .borrow() + ?? panic("Could not get receiver reference to the NFT Collection") + } + + execute { + ExampleNFT.mintNFT( + recipient: self.recipientCollectionRef, + name: name, + description: description, + thumbnail: thumbnail, + creator: creator, + rarity: rarity + ) + } +} +``` + +You can copy this functionality and adapt it for our use case. + +### Update the IncrementIfOdd transaction + +Now let's update our `IncrementIfOdd` transaction to mint an NFT when the counter is odd. You can either modify the current transaction or create a new one: + +```cadence +import "Counter" +import "ExampleNFT" +import "NonFungibleToken" + +transaction() { + let recipientCollectionRef: &{NonFungibleToken.Receiver} + + prepare(acct: &Account) { + // Get the recipient's NFT collection reference + self.recipientCollectionRef = getAccount(acct.address) + .capabilities.get<&{NonFungibleToken.Receiver}>(ExampleNFT.CollectionPublicPath) + .borrow() + ?? panic("Could not get receiver reference to the NFT Collection") + } + + execute { + // Get the current count from the Counter contract (public read) + let currentCount = Counter.getCount() + + // Print the current count + log("Current count: ".concat(currentCount.toString())) + + // If odd (remainder when divided by 2 is not 0), increment and mint NFT + if currentCount % 2 != 0 { + Counter.increment() + let newCount = Counter.getCount() + log("Counter was odd, incremented to: ".concat(newCount.toString())) + + // Mint an NFT to celebrate the odd number + ExampleNFT.mintNFT( + recipient: self.recipientCollectionRef, + name: "Odd Counter NFT #".concat(newCount.toString()), + description: "This NFT was minted when the counter was odd!", + thumbnail: "https://example.com/odd-counter.png", + creator: "Counter Composer", + rarity: "Rare" + ) + log("Minted NFT for odd counter!") + } else { + log("Counter was even, no increment performed") + } + } +} +``` + +### Setup NFT collection + +Before you can mint NFTs, set up an NFT collection in your account. Create a transaction to do this: + +```bash +flow generate transaction SetupCollection +``` + +Add this content to the new transaction: + +```cadence +import "ExampleNFT" +import "NonFungibleToken" +import "MetadataViews" + +transaction { + prepare(signer: auth(BorrowValue, IssueStorageCapabilityController, PublishCapability, SaveValue) &Account) { + if signer.storage.borrow<&ExampleNFT.Collection>(from: ExampleNFT.CollectionStoragePath) != nil { + return + } + + let collection <- ExampleNFT.createEmptyCollection(nftType: Type<@ExampleNFT.NFT>()) + + signer.storage.save(<-collection, to: ExampleNFT.CollectionStoragePath) + + let cap = signer.capabilities.storage.issue<&ExampleNFT.Collection>(ExampleNFT.CollectionStoragePath) + signer.capabilities.publish(cap, at: ExampleNFT.CollectionPublicPath) + } +} +``` + +Run the setup transaction: + +```bash +flow transactions send cadence/transactions/SetupCollection.cdc --signer testnet-account --network testnet +``` + +### Test the enhanced transaction + +Now run the enhanced transaction: + +```bash +flow transactions send cadence/transactions/IncrementIfOdd.cdc --signer testnet-account --network testnet +``` + +You may need to run the regular `IncrementCounter` transaction first to get an odd number: + +```bash +flow transactions send cadence/transactions/IncrementCounter.cdc --signer testnet-account --network testnet +``` + +### View your NFT + +Click the transaction link in the console to view the transaction in [testnet Flowscan]. After you run the transaction **while the counter is odd**, you'll see an NFT in the `Asset Transfers` tab. + +:::info + +The broken image is expected. We didn't use a real URL in the example nft metadata. + +::: + +![NFT](nft.png) + +--- + +## Why this matters + +- **No redeploys, no forks:** You composed your app logic with on-chain public contracts you do not control. +- **Cadence-first composition:** Transactions can include _arbitrary logic_ that calls into multiple contracts in one atomic operation with a single signature. +- **Production-ready path:** The same code path works from a CLI or a dApp frontend, authorized by a wallet. + +## Conclusion + +In this tutorial, you learned how to compose with multiple on-chain contracts using Cadence transactions. You built a transaction that conditionally interacts with a Counter contract based on its current state, and then extended it to mint NFTs when the counter is odd, which demonstrates the power and flexibility of Cadence's composition model. + +Now that you have completed the tutorial, you should be able to: + +- Configure the Flow CLI _dependency manager_ to import named contracts from **testnet**. +- Write a Cadence **transaction** that reads and writes to a public contract you did not deploy. +- Run the transaction on **testnet** with a funded account with the Flow CLI. +- Extend the transaction to compose multiple public contracts (`Counter` + `ExampleNFT` + `NonFungibleToken`) without the need to redeploy anything. +- Set up NFT collections and mint NFTs conditionally based on on-chain state. +- View transaction results and NFT transfers with Flowscan. + +This approach gives you the freedom to build complex application logic that composes with any public contracts on Flow, which makes Cadence's composition model a powerful tool for developers building on Flow. + + + +[Flow CLI installed]: ../../../build/tools/flow-cli/install.md +[dependency manager]: ../../../build/tools/flow-cli/dependency-manager.md +[new project]: ../../../build/tools/flow-cli/flow.json/initialize-configuration +[Flow CLI]: ../../../build/tools/flow-cli/index.md +[transaction]: https://cadence-lang.org/docs/language/transactions +[account commands]: ../../../build/tools/flow-cli/commands#account-management +[Send the transaction]: ../../../build/tools/flow-cli/commands#send-transaction +[emulator]: ../../../build/tools/emulator/index.md +[MintExampleNFT transaction]: https://github.com/mfbz/flow-nft-tester/blob/main/cadence/transactions/MintExampleNFT.cdc +[testnet Flowscan]: https://testnet.flowscan.io/ diff --git a/docs/blockchain-development-tutorials/cadence/cadence-advantages/index.md b/docs/blockchain-development-tutorials/cadence/cadence-advantages/index.md new file mode 100644 index 0000000000..83a313b6ca --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/cadence-advantages/index.md @@ -0,0 +1,49 @@ +--- +title: Cadence Advantages +description: A series of tutorials showcasing the unique advantages and capabilities of Cadence smart contracts on Flow. +sidebar_position: 2 +keywords: + - Cadence advantages + - smart contracts + - Flow blockchain + - tutorials + - composition + - native data availability + - resource-oriented programming + - transaction composition + - script queries + - contract upgrades + - contract updatability + - incremental upgrades +--- + +# Cadence Advantages + +This series explores the unique advantages and capabilities of Cadence smart contracts on Flow, and demonstrates how Cadence's innovative features allow powerful development patterns that aren't possible on other blockchain platforms. From native data availability to seamless transaction composition, these tutorials showcase why Cadence represents the future of smart contract development. + +## Tutorials + +### [Compose with Cadence Transactions] + +Learn how to compose with someone else's on-chain contracts by writing a Cadence transaction that conditionally calls a public contract on testnet, then extend it to mint NFTs when conditions are met, with no redeploy required. This tutorial demonstrates Cadence's powerful composition model, which lets you build complex application logic that interacts with multiple contracts in a single atomic transaction. You'll work with the Flow command line interface (CLI) dependency manager, learn to set up NFT collections, and view results using Flowscan. + +### [Native Data Availability with Cadence Scripts] + +Discover how Cadence scripts provide native data availability, which allows you to query any on-chain data directly from Flow's state without the need to rely on external indexers or APIs. This comprehensive tutorial shows you how to build scripts that can discover and query NFT collections across multiple child accounts with Hybrid Custody, then extend it to include both NBA Top Shot and NFL All Day NFTs. You'll learn to filter and process NFT collections, extract specific metadata, and compare Cadence's native data availability with Solidity's limitations. + +### [Upgrading Cadence Contracts] + +Learn how to upgrade deployed Cadence contracts through multiple incremental upgrades, preserve the current state, and maintain the same contract address. This tutorial demonstrates Cadence's sophisticated contract upgrade system through two realistic scenarios: + +- Add an event to notify users when the counter reaches an even number. +- Extend the contract with additional functionality like increment by two and check if numbers are even. + +You'll understand what you can and can't change when you upgrade, perform multiple contract updates with Flow CLI, and test upgraded functionality with comprehensive transactions and scripts. + +## Conclusion + +Cadence's unique features, such as resource-oriented programming to native data availability, seamless transaction composition, and sophisticated contract upgrade capabilities, represent a fundamental advancement in smart contract development. These tutorials demonstrate how Cadence allows developers to build sophisticated applications with capabilities that simply aren't possible on other blockchain platforms and maintain security and developer experience as core principles. + +[Compose with Cadence Transactions]: ./compose-with-cadence-transactions.md +[Native Data Availability with Cadence Scripts]: ./native-data-availibility-with-cadence-scripts.md +[Upgrading Cadence Contracts]: ./upgrading-cadence-contracts.md diff --git a/docs/blockchain-development-tutorials/cadence/cadence-advantages/native-data-availibility-with-cadence-scripts.md b/docs/blockchain-development-tutorials/cadence/cadence-advantages/native-data-availibility-with-cadence-scripts.md new file mode 100644 index 0000000000..82ba109b88 --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/cadence-advantages/native-data-availibility-with-cadence-scripts.md @@ -0,0 +1,470 @@ +--- +title: Native Data Availability With Cadence Scripts +sidebar: Data Availability +description: Learn why Cadence scripts are more powerful than Solidity views by incrementally building a post-1.0 Cadence script that lists a parent account's child accounts and returns their NBA Top Shot NFTs using the Flow CLI commands. +sidebar_position: 1 +keywords: + - Cadence scripts + - Solidity views + - data availability + - blockchain indexers + - Hybrid Custody + - capabilities + - entitlements + - Flow CLI + - commands + - NonFungibleToken + - MetadataViews + - NBA Top Shot + - Flow NFTs + - account storage + - read operations +--- + +# Native Data Availability With Cadence Scripts + +In Solidity, you can only retrieve data from **view** functions that the contract author anticipated and included in the original contract. If the exact query you want isn't exposed, teams typically rely on a _data availability service_ such as The Graph, Covalent, Alchemy Enhanced APIs, Reservoir, or NFTScan to compute and serve that view. + +In Cadence, **scripts** are general-purpose read programs. They can traverse public account storage, read public capabilities, and compose types from multiple contracts to answer new questions without the need to modify those contracts. You are not limited to the pre-written surface area of a single contract's views. + +:::info + +In Cadence, a _script_ is a read-only program that can access public data across accounts and contracts in a strongly typed way. It does not require a user signatures not does it incur any fees. + +::: + +## Objectives + +After you complete this guide, you will be able to: + +- Explain why Cadence **scripts** are more powerful than Solidity **view** functions. +- Use the [Flow CLI Commands] to execute a Cadence script against mainnet. +- Analyze an account for [NBA Top Shot] NFTs held by the account or its child accounts. +- Build the script incrementally to: + - Query a parent account for child accounts via [_Hybrid Custody_]. + - Inspect each child account's storage paths. + - Detect NFT collections the parent can control. + - List only NBA Top Shot NFTs with display metadata. + - Update the script to also list NFL All Day NFT metadata. + +## Prerequisites + +- Basic familiarity with [Cadence] and [Flow accounts]. +- Flow command line interface (CLI) installed and authenticated for mainnet (see [Flow CLI Commands]). +- The target parent account uses _Hybrid Custody_ and controls at least one child account that holds NBA Top Shot NFTs. + - If you don't have an account that owns NBA Top Shots, you can use `0xfeb88a0fcc175a3d` for this tutorial. + +:::tip + +If you are new to [_Hybrid Custody_], the high-level idea is that in Cadence, a parent account can manage one or more child accounts through managed capabilities. This guide uses those capabilities to enumerate NFT collections the parent can control. + +::: + +## Get started + +Create a new Flow project and generate a script file: + +```bash +# Create a new Flow project +flow init cadence-scripts-tutorial + +# Navigate to the project directory +cd cadence-scripts-tutorial + +# Generate a new script file +flow generate script TopShotQuery +``` + +This creates a proper Flow project structure with `flow.json` configuration and generates a script template at `cadence/scripts/TopShotQuery.cdc`. + +We will **revise one script file** in four passes, and run it after each step. This mirrors how you would build and verify a script from scratch. + +--- + +## Query the account to find child accounts + +To start, write a script that borrows the parent's _Hybrid Custody_ manager and returns the child addresses it controls. This verifies that imports resolve and that the parent account is configured as expected. + +First, you'll need to install the `HybridCustody` contract from mainnet. + +:::info + +In Cadence, you can import a file from a path as you'd expect. You can also **import an already deployed contract** into your project. + +::: + +Use the [dependency manager] to install the contract with: + +```bash +flow dependencies install mainnet://0xd8a7e05a7ac670c0.HybridCustody +``` + +This will install the contract and its own dependencies. You don't need to deploy these contracts again, so pick `none` for the account to deploy. You also don't need an alias. + +:::warning + +The language server treats dependency installations in this way similar to package installations in other platforms. You'll need to close and reopen the file or type something to trigger a refresh. + +::: + +Open `scripts/TopShotQuery.cdc` Replace the file contents with: + +```cadence +import "HybridCustody" + +// Return the child account addresses managed by the given parent. +access(all) fun main(addr: Address): [Address] { + let parent = getAuthAccount(addr) + + let manager = + parent.storage.borrow( + from: HybridCustody.ManagerStoragePath + ) ?? panic("manager does not exist") + + return manager.getChildAddresses() +} +``` + +Run it: + +```bash +flow scripts execute cadence/scripts/TopShotQuery.cdc --network mainnet 0xfeb88a0fcc175a3d +``` + +You will see a list of child addresses. If you do not, confirm the parent actually stores a manager at `HybridCustody.ManagerStoragePath`. + +```bash +Result: [0xa16b948ba2c9a858] +``` + +--- + +## Listing the storage paths found in each child account + +Next, for each child, enumerate storage paths. This helps us understand what each account stores before we try to detect NFTs. + +:::info + +In Cadence, data is stored in a users account in [storage paths]. + +::: + +Update the query to iterate through the child addresses in the `manager` and collect their storage paths and return those paths: + +```cadence +import "HybridCustody" + +// Map child address -> array of storage path strings (e.g. "storage/SomePath"). +access(all) fun main(addr: Address): {Address: [String]} { + let parent = getAuthAccount(addr) + + let manager = + parent.storage.borrow( + from: HybridCustody.ManagerStoragePath + ) ?? panic("manager does not exist") + + var pathsByChild: {Address: [String]} = {} + + for child in manager.getChildAddresses() { + let acct = getAuthAccount(child) + var paths: [String] = [] + for sp in acct.storage.storagePaths { + paths.append(sp.toString()) + } + pathsByChild[child] = paths + } + + return pathsByChild +} +``` + +Run it again: + +```bash +flow scripts execute cadence/scripts/TopShotQuery.cdc --network mainnet 0xfeb88a0fcc175a3d +``` + +You'll see a map from each child address to its storage paths. This tells us where to look for potential collections. + +```bash +Result: {0xa16b948ba2c9a858: ["/storage/flowTokenVault", "/storage/PinnacleNFTCollectionProviderForNFTStorefront", "/storage/BackpackCollection", "/storage/PackNFTCollection", "/storage/HybridCustodyChild_0xd8a7e05a7ac670c0", "/storage/ChildAccount_0xfeb88a0fcc175a3d", "/storage/privateForwardingStorage", "/storage/PinnacleCollection", "/storage/AllDayNFTCollection", "/storage/NFTStorefrontV2", "/storage/PinnaclePackNFTCollection", "/storage/ChildAccount_0x0f566b3217c33c4a", "/storage/dapperUtilityCoinReceiver", "/storage/CapFilterParent0xfeb88a0fcc175a3d", "/storage/ChildCapabilityDelegator_0x0f566b3217c33c4a", "/storage/CapFilterParent0x0f566b3217c33c4a", "/storage/flowUtilityTokenReceiver", "/storage/MomentCollection", "/storage/ChildCapabilityDelegator_0xfeb88a0fcc175a3d", "/storage/NFTStorefrontV20x3cdbb3d569211ff3"]} +``` + +--- + +## Detecting NFT collections the parent can control + +Now you can identify which stored items are NFT collections that the **parent** can act on. In Cadence, a [_capability_] exposes specific interfaces on a stored value. We look for a capability whose type includes [`{NonFungibleToken.Provider}`] and confirm the parent has access via _Hybrid Custody_. + +Update the script to iterate through storage paths found in child accounts to search for providers of the `NonFungibleToken.Provider` type: + +```cadence +import "HybridCustody" +import "NonFungibleToken" + +// Map child address -> array of type identifiers for NFT collections +// that the parent can control (i.e. has a Provider capability for). +access(all) fun main(addr: Address): {Address: [String]} { + let parent = getAuthAccount(addr) + + let manager = + parent.storage.borrow( + from: HybridCustody.ManagerStoragePath + ) ?? panic("manager does not exist") + + let providerType = Type() + var controllableTypes: {Address: [String]} = {} + + for child in manager.getChildAddresses() { + let acct = getAuthAccount(child) + let childAcct = manager.borrowAccount(addr: child) ?? panic("child account not found") + var found: [String] = [] + + // For each storage path, inspect its controllers (capability controllers). + for sp in acct.storage.storagePaths { + for ctrl in acct.capabilities.storage.getControllers(forPath: sp) { + // If the controller's borrow type does not include Provider, skip. + if !ctrl.borrowType.isSubtype(of: providerType) { + continue + } + + // Verify the parent has an accessible capability through Hybrid Custody. + if let cap: Capability = childAcct.getCapability( + controllerID: ctrl.capabilityID, + type: providerType + ) { + let providerCap = cap as! Capability<&{NonFungibleToken.Provider}> + if providerCap.check() { + // Record the concrete type identifier behind this capability. + let typeId = cap.borrow<&AnyResource>()!.getType().identifier + found.append(typeId) + // One confirmation per path is sufficient. + break + } + } + } + } + + controllableTypes[child] = found + } + + return controllableTypes +} +``` + +Run it: + +```bash +flow scripts execute cadence/scripts/TopShotQuery.cdc --network mainnet 0xfeb88a0fcc175a3d +``` + +You will now see type identifiers such as `A.
..` for collections the parent can control. We will use these identifiers to filter for Top Shot. + +```bash +Result: {0xa16b948ba2c9a858: ["A.807c3d470888cc48.Backpack.Collection", "A.e4cf4bdc1751c65d.AllDay.Collection", "A.0b2a3299cc857e29.TopShot.Collection"]} +``` + +--- + +## Filter NFT collection to find and return Top Shots + +Finally, for each detected collection, [borrow] the collection `{NonFungibleToken.CollectionPublic}`, iterate IDs, resolve `MetadataViews.Display`, and return only Top Shot items. We add a small `isTopShot` predicate that you can customize to your deployment. + +:::info + +The [borrow] function is how you use a published [_capability_] in your code. In this case, you borrow the **public** functionality of Cadence NFTs, which includes [`MetadataViews`] that return a view of the **fully-onchain metadata** for the NFT. + +::: + +Update the query to borrow a reference to each public collection and return metadata for those that are NBA Top Shots: + +```cadence +import "HybridCustody" +import "NonFungibleToken" +import "MetadataViews" + +// Map child address -> { tokenId : MetadataViews.Display } for Top Shot NFTs only. +access(all) fun main(addr: Address): {Address: {UInt64: MetadataViews.Display}} { + let parent = getAuthAccount(addr) + + let manager = + parent.storage.borrow( + from: HybridCustody.ManagerStoragePath + ) ?? panic("manager does not exist") + + let providerType = Type() + let collectionIface: Type = Type<@{NonFungibleToken.CollectionPublic}>() + + // Customize this to match other collections found in the previous step! + fun isTopShot(_ typeId: String): Bool { + // Common pattern: typeId.contains("TopShot") + return typeId.contains("TopShot") + } + + var result: {Address: {UInt64: MetadataViews.Display}} = {} + + for child in manager.getChildAddresses() { + let acct = getAuthAccount(child) + let childAcct = manager.borrowAccount(addr: child) ?? panic("child account not found") + + // First, collect controllable type identifiers for this child. + var typesWithProvider: [String] = [] + + for sp in acct.storage.storagePaths { + for ctrl in acct.capabilities.storage.getControllers(forPath: sp) { + if !ctrl.borrowType.isSubtype(of: providerType) { + continue + } + if let cap: Capability = childAcct.getCapability( + controllerID: ctrl.capabilityID, + type: providerType + ) { + let providerCap = cap as! Capability<&{NonFungibleToken.Provider}> + if providerCap.check() { + let typeId = cap.borrow<&AnyResource>()!.getType().identifier + typesWithProvider.append(typeId) + break + } + } + } + } + + var displays: {UInt64: MetadataViews.Display} = {} + + // Walk storage again to borrow the matching collections and read their items. + acct.storage.forEachStored(fun (path: StoragePath, t: Type): Bool { + // Only consider types we know are controllable and that match Top Shot. + var match = false + for tid in typesWithProvider { + if tid == t.identifier && isTopShot(tid) { + match = true + break + } + } + if !match { + return true + } + + // Skip the concrete resource type token; we want the collection interface. + if t.isInstance(collectionIface) { + return true + } + + if let col = acct.storage.borrow<&{NonFungibleToken.CollectionPublic}>(from: path) { + for id in col.getIDs() { + let nft = col.borrowNFT(id)! + if let display = nft.resolveView(Type())! as? MetadataViews.Display { + displays[id] = display + } + } + } + return true + }) + + result[child] = displays + } + + return result +} +``` + +Run it: + +```bash +flow scripts execute cadence/scripts/TopShotQuery.cdc --network mainnet 0xfeb88a0fcc175a3d +``` + +The output is a Cadence representation of: + +``` +{ Address: { UInt64: MetadataViews.Display } } +``` + +which maps each child account address to a map of NFT IDs to their display metadata (name, description, thumbnail). + +```bash +Result: {0xa16b948ba2c9a858: {44311697: A.1d7e57aa55817448.MetadataViews.Display(name: "Immanuel Quickley 3 Pointer", description: "", thumbnail: A.1d7e57aa55817448.MetadataViews.HTTPFile(url: "https://assets.nbatopshot.com/media/44311697?width=256")), 44274843: A.1d7e57aa55817448.MetadataViews.Display(name: "Rudy Gobert Rim", description: "", thumbnail: A.1d7e57aa55817448.MetadataViews.HTTPFile(url: "https://assets.nbatopshot.com/media/44274843?width=256")), 44219960: A.1d7e57aa55817448.MetadataViews.Display(name: "Sasha Vezenkov 3 Pointer", description: "", thumbnail: A.1d7e57aa55817448.MetadataViews.HTTPFile(url: "https://assets.nbatopshot.com/media/44219960?width=256")), 44300175: A.1d7e57aa55817448.MetadataViews.Display(name: "Malik Monk Assist", description: "", thumbnail: A.1d7e57aa55817448.MetadataViews.HTTPFile(url: "https://assets.nbatopshot.com/media/44300175?width=256")), 43995280: A.1d7e57aa55817448.MetadataViews.Display(name: "Kelly Olynyk 3 Pointer", description: "Regardless of the stakes, regardless of the stage, Kelly Olynyk is calm and collected beyond the arc. Trailing in the fourth quarter of a tight contest, the Utah Jazz big gets to his spot in the corner and buries a triple to claw within one. After a defensive stop on the next possession Olynyk doubles down on the momentum and drains a transition three to give his team the lead. Olynyk finished with 15 points on 5 of 6 shooting in the October 27, 2023 matchup and the Jazz held on for the W at the hands of the LA Clippers.", thumbnail: A.1d7e57aa55817448.MetadataViews.HTTPFile(url: "https://assets.nbatopshot.com/media/43995280?width=256"))}} +``` + +--- + +## Extend the script to include AllDay NFTs + +Now that you have a working script for Top Shot NFTs, let's extend it to also return NFL All Day NFTs. This demonstrates the flexibility of Cadence scripts - you can easily modify them to answer new questions without the need to change any contracts. + +Update the `isTopShot` function to also include AllDay NFTs: + +```cadence +// Customize this to match other collections found in the previous step! +fun isTopShot(_ typeId: String): Bool { + // Include both TopShot and AllDay NFTs + return typeId.contains("TopShot") || typeId.contains("AllDay") +} +``` + +Run the updated script: + +```bash +flow scripts execute cadence/scripts/TopShotQuery.cdc --network mainnet 0xfeb88a0fcc175a3d +``` + +You will see both Top Shot and AllDay NFTs in the results (truncated for space): + +```bash +Result: {0xa16b948ba2c9a858: {44311697: A.1d7e57aa55817448.MetadataViews.Display(name: "Immanuel Quickley 3 Pointer", description: "", thumbnail: A.1d7e57aa55817448.MetadataViews.HTTPFile(url: "https://assets.nbatopshot.com/media/44311697?width=256")), 8220605: A.1d7e57aa55817448.MetadataViews.Display(name: "Zach Ertz Reception", description: "Normally used to overwhelming his NFC East foes in a different, midnight-green attire, Zach Ertz, in his most productive yardage-based game since 2022, showed in Week 2 that productivity remains well within reach. Challenged to a \u{201c}who wants it more\u{201d}-type battle during a corner route, Ertz adjusted to a floated ball, using both a 6-foot-5 frame and pure strength to rip away a potential interception, turning it into a 21-yard catch for himself. The 12-year veteran helped the Washington Commanders \u{2014} whose seven field goals offset the New York Giants\u{2019} three touchdowns \u{2014} survive for a unique 21-18 win, with Ertz providing four catches (on four targets) and 62 yards on Sept. 15, 2024.", thumbnail: A.1d7e57aa55817448.MetadataViews.HTTPFile(url: "https://media.nflallday.com/editions/3304/media/image?format=jpeg&width=256"))}} +``` + +This demonstrates how you can easily modify Cadence scripts to answer different questions about the same data, unlike Solidity, where you'd need to deploy new contracts or rely on external indexers. + +--- + +## Troubleshoot + +- If you see `manager does not exist`, confirm the parent address actually stores a `HybridCustody.Manager` at `HybridCustody.ManagerStoragePath`. +- If you see empty arrays in Step 3, the parent may not have _provider_ access to any collections in those child accounts. +- If you see empty results in Step 4, confirm `isTopShot` matches the identifiers you observed in Step 3. +- If you are not using _Hybrid Custody_, you can adapt Steps 2-4 to use `getAccount(child)` and scan **publicly exposed** `{NonFungibleToken.CollectionPublic}` capabilities, but you will not be able to assert provider access. + +## How this compares to Solidity + +- **Solidity views are fixed**: You can only retrieve what the contract author exposed via `view` or `pure` functions. If you need a different aggregation or cross-contract traversal, you typically rely on a _data availability service_ or write a new contract to expose that view. +- **Cadence scripts are flexible**: You compose types across modules, traverse account storage, and read public capabilities at query time. You do not need to redeploy contracts to answer new questions. + +Common _data availability service_ examples used in EVM ecosystems: + +- The Graph (subgraphs) +- Covalent (unified API) +- Alchemy Enhanced APIs +- Reservoir (NFT market APIs) +- NFTScan (NFT inventory APIs) + +## Conclusion + +In this tutorial, you learned how to use Cadence scripts to query onchain data directly from Flow's state, without the need to rely on external indexers or APIs. You built a script that can discover and query NFT collections across multiple child accounts with Hybrid Custody, and then extended it to include both NBA Top Shot and NFL All Day NFTs, which demonstrates the power and flexibility of Cadence's native data availability. + +Now that you have completed the tutorial, you should be able to: + +- Query onchain data directly with Cadence scripts without external dependencies +- Use Hybrid Custody to access child account data from parent accounts +- Filter and process NFT collections to extract specific metadata +- Modify scripts to answer different questions about the same onchain data +- Compare Cadence's native data availability with Solidity's limitations +- Build applications that can access any onchain data in real-time + +This approach gives you the freedom to build applications that can access any onchain data in real-time, which makes Flow's native data availability a powerful tool for developers who build on Flow. + + + +[NBA Top Shot]: https://nbatopshot.com/ +[account linking tutorial]: ../account-management/account-linking-with-dapper.md +[_Hybrid Custody_]: ../account-management/index.md +[dependency manager]: ../../../build/tools/flow-cli/dependency-manager.md +[Hybrid Custody]: ../account-management/index.md +[Flow accounts]: ../../../build/cadence/basics/accounts.md +[Cadence]: https://cadence-lang.org/docs/tutorial/first-steps +[Flow CLI Commands]: ../../../build/tools/flow-cli/commands.md +[storage paths]: https://cadence-lang.org/docs/tutorial/resources#storage-paths +[_capability_]: https://cadence-lang.org/docs/language/capabilities +[`{NonFungibleToken.Provider}`]: https://github.com/onflow/flow-nft/blob/21c5e18a0985528b53931dc14c55332b3b47939e/contracts/NonFungibleToken.cdc#L154 +[borrow]: https://cadence-lang.org/docs/language/capabilities#borrowing-public-capabilities-with-borrow +[NFL All Day]: https://nflallday.com/ diff --git a/docs/blockchain-development-tutorials/cadence/cadence-advantages/nft.png b/docs/blockchain-development-tutorials/cadence/cadence-advantages/nft.png new file mode 100644 index 0000000000..7273c979c6 Binary files /dev/null and b/docs/blockchain-development-tutorials/cadence/cadence-advantages/nft.png differ diff --git a/docs/blockchain-development-tutorials/cadence/cadence-advantages/upgrading-cadence-contracts.md b/docs/blockchain-development-tutorials/cadence/cadence-advantages/upgrading-cadence-contracts.md new file mode 100644 index 0000000000..932c484fb6 --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/cadence-advantages/upgrading-cadence-contracts.md @@ -0,0 +1,824 @@ +--- +title: Upgrading Cadence Contracts +description: Learn how to upgrade already deployed Cadence contracts by adding new functionality while preserving existing state. Deploy a Counter contract, modify it to add even/odd counting functionality, and update it on testnet using Flow CLI. +sidebar_position: 2 +keywords: + - Cadence contract upgrades + - contract updates + - Flow CLI + - contract deployment + - testnet deployment + - contract modification + - state preservation + - contract versioning + - Flow CLI commands + - account update contract + - contract evolution +--- + +# Upgrading Cadence Contracts + +In Cadence, to upgrade deployed contracts, you can add new functionality while preserving the current state and maintain the same contract address. Unlike other blockchain platforms that require complex proxy patterns or complete redeployment, Cadence allows you to seamlessly extend your contracts with new functions and events through multiple incremental upgrades. + +This tutorial demonstrates how to upgrade a deployed contract through two scenarios: + +- Add an event to notify users when the counter reaches an even number. +- Extend the contract with additional functionality, like incrementing by two and checking if numbers are even. + +## Objectives + +After you complete this guide, you will be able to: + +- **Deploy a contract** to Flow testnet using Flow command line interface (CLI). +- **Perform incremental contract upgrades** by adding new events and functions. +- **Update deployed contracts multiple times** using the `flow accounts update-contract` command +- **Test upgraded functionality** with Cadence transactions and scripts. +- **Understand what can and cannot be changed** during contract upgrades. +- **Apply realistic upgrade scenarios** based on user feedback and requirements. + +## Prerequisites + +- [Flow CLI installed] and configured. +- Basic familiarity with [Cadence] and [Flow accounts]. +- A **funded testnet account** to deploy and update contracts. + - See [Create accounts] and [Fund accounts] in the Flow CLI commands. + +## Contract upgrade overview + +Cadence provides a sophisticated contract upgrade system that allows you to modify deployed contracts while ensuring data consistency and preventing runtime crashes. It's crucial for successful upgrades that you understand what you can and can't change. + +### What you CAN upgrade + +- **Add new functions** - Extend contract functionality with new methods. +- **Add new events** - Emit additional events for monitoring and indexing. +- **Modify function implementations** - Change how existing functions work. +- **Change function signatures** - Update parameters and return types. +- **Remove functions** - Delete functions that are no longer needed. +- **Change access modifiers** - Update visibility of functions and fields. +- **Reorder existing fields** - Field order doesn't affect storage. + +### What you CANNOT upgrade + +- **Add new fields** - Would cause runtime crashes when loading existing data. +- **Change field types** - Would cause deserialization errors. +- **Remove existing fields** - Fields become inaccessible, but data remains. +- **Change enum structures** - Raw values must remain consistent. +- **Change contract name** - Contract address must remain the same. + +### Why these restrictions exist + +The [Cadence Contract Updatability documentation](https://cadence-lang.org/docs/language/contract-updatability) explains that these restrictions prevent: + +- **Runtime crashes** from missing or garbage field values. +- **Data corruption** from type mismatches. +- **Storage inconsistencies** from structural changes. +- **Type confusion** from enum value changes. + +The validation system ensures that current stored data remains valid and accessible after upgrades. + +## Get started + +Create a new Flow project for this tutorial: + +```bash +# Create a new Flow project +flow init upgrading-contracts-tutorial +``` + +Follow the prompts and create a `Basic Cadence project (no dependencies)` then open the new project in your editor. + +### Create and fund testnet account + +You'll need a funded testnet account to deploy and update contracts. In a terminal in the root of your project folder: + +```bash +# Create a testnet account +flow accounts create --network testnet +``` + +When prompted: + +1. **Account name**: Enter `testnet-account` +2. Select `testnet` as the network when prompted + +Fund your account with testnet FLOW tokens: + +```bash +# Fund the account +flow accounts fund testnet-account +``` + +This will open the faucet in your browser where you can request 100,000 testnet FLOW tokens. + +:::info + +The faucet provides free testnet tokens for development and testing purposes. These tokens have no real value and are only used on the testnet network. + +::: + +--- + +## Deploy the initial counter contract + +To start, let's deploy a simple Counter contract to testnet. + +Open and review `cadence/contracts/Counter.cdc`. This is a simple contract created with all projects: + +```cadence +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 + } + + // Public function to increment the counter + access(all) fun increment() { + self.count = self.count + 1 + emit CounterIncremented(newCount: self.count) + + // NEW: Also emit event if the result is even + if self.count % 2 == 0 { + emit CounterIncrementedToEven(newCount: self.count) + } + } + + // Public function to decrement the counter + access(all) fun decrement() { + self.count = self.count - 1 + emit CounterDecremented(newCount: self.count) + } + + // Public function to get the current count + view access(all) fun getCount(): Int { + return self.count + } +} +``` + +### Configure deployment + +Add testnet deployment configuration to your `flow.json`: + +```bash +flow config add deployment +``` + +Follow the prompts: + +1. **Network**: `testnet` +2. **Account**: `testnet-account` +3. **Contract**: `Counter` +4. **Deploy more contracts**: `no` + +Your `flow.json` will now include a testnet deployment section: + +```json +{ + "deployments": { + "testnet": { + "testnet-account": ["Counter"] + } + } +} +``` + +### Deploy to Testnet + +Deploy your Counter contract to testnet: + +```bash +flow project deploy --network testnet +``` + +You will see output similar to: + +```bash +Deploying 1 contracts for accounts: testnet-account + +Counter -> 0x9942a81bc6c3c5b7 (contract deployed successfully) + +🎉 All contracts deployed successfully +``` + +### Test the initial contract + +Use the provided transaction to test initial functionality: + +Review `cadence/transactions/TestCounter.cdc`. This transaction simply increments the counter: + +```cadence +import "Counter" + +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())) + } +} +``` + +:::info + +Cadence transactions are written in Cadence and can call one or more functions on one or more contracts, all with a single user signature. Check out our tutorial to learn how to [Compose with Cadence Transactions] to learn more! + +::: + +Run the test transaction: + +```bash +flow transactions send cadence/transactions/IncrementCounter.cdc --signer testnet-account --network testnet +``` + +You will see logs that show the counter incrementing and decrementing as expected. + +```bash +Transaction ID: 251ee40a050b8c7298d33f1b73ed94996a9d99deae8559526d9dddae182f7752 + +Block ID 25cdb14fcbaf47b3fb13e6ec43bdef0ede85a6a580caea758220c53d48493e17 +Block Height 284173579 +Status ✅ SEALED +ID 251ee40a050b8c7298d33f1b73ed94996a9d99deae8559526d9dddae182f7752 +Payer adb1efc5826d3768 +Authorizers [adb1efc5826d3768] + +Proposal Key: + Address adb1efc5826d3768 + Index 0 + Sequence 1 + +No Payload Signatures + +Envelope Signature 0: adb1efc5826d3768 +Signatures (minimized, use --include signatures) + +Events: + Index 0 + Type A.adb1efc5826d3768.Counter.CounterIncremented + Tx ID 251ee40a050b8c7298d33f1b73ed94996a9d99deae8559526d9dddae182f7752 + Values + - newCount (Int): 1 +``` + +--- + +## Upgrade the contract - Part 1: add event for even numbers + +Let's start with a realistic scenario: What if we've realized it's very important to our users that they know when the counter reaches an even number, but we forgot to add an event for that case? Let's add that functionality first. + +### Modify the Counter contract - first upgrade + +Update `cadence/contracts/Counter.cdc` to add the new event and enhance the current `increment()` function: + +```cadence +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) + + // NEW: Event to be emitted when the counter is incremented and the result is even + access(all) event CounterIncrementedToEven(newCount: Int) + + init() { + self.count = 0 + } + + // Public function to increment the counter + access(all) fun increment() { + self.count = self.count + 1 + emit CounterIncremented(newCount: self.count) + + // NEW: Also emit event if the result is even + if self.count % 2 == 0 { + emit CounterIncrementedToEven(newCount: self.count) + } + } + + // Public function to decrement the counter + access(all) fun decrement() { + self.count = self.count - 1 + emit CounterDecremented(newCount: self.count) + } + + // Public function to get the current count + view access(all) fun getCount(): Int { + return self.count + } +} +``` + +### Key changes made - part 1 + +This first upgrade adds: + +1. **New event**: `CounterIncrementedToEven` to notify when incrementing results in an even number. +2. **Enhanced existing function**: The `increment()` function now also emits the new event when appropriate. +3. **No new fields**: We only use the current `count` field to avoid validation errors. + +:::info + +This demonstrates how you can add new behavior and modify current function behavior, which enhances current functionality. The original `CounterIncremented` event still works as before, which ensures backward compatibility. + +::: + +--- + +## Update the deployed contract - part 1 + +Now let's update the deployed contract on testnet with the Flow CLI update command with our first upgrade. + +### Update the contract + +Use the [Flow CLI update contract command] to upgrade your deployed contract: + +```bash +flow accounts update-contract ./cadence/contracts/Counter.cdc --signer testnet-account --network testnet +``` + +You will see output similar to: + +```bash +Contract 'Counter' updated on account '0x9942a81bc6c3c5b7' + +Address 0x9942a81bc6c3c5b7 +Balance 99999999999.70000000 +Keys 1 + +Key 0 Public Key [your public key] + Weight 1000 + Signature Algorithm ECDSA_P256 + Hash Algorithm SHA3_256 + Revoked false + Sequence Number 2 + Index 0 + +Contracts Deployed: 1 +Contract: 'Counter' +``` + +:::success + +The contract successfully updated! Notice that: + +- The contract address remains the same (`0x9942a81bc6c3c5b7`). +- The current state (`count`) is preserved. +- New functionality is available. + +::: + +### Test the first upgrade + +Let's test the new event functionality. Create a simple transaction to test the enhanced `increment()` function: + +```bash +flow generate transaction TestEvenEvent +``` + +Replace the contents of `cadence/scripts/CheckCounter.cdc` with: + +```cadence +import "Counter" + +access(all) fun main(): {String: AnyStruct} { + return { + "count": Counter.getCount(), + "isEven": Counter.isEven() + } +} +``` + +Run the script to check the current state: + +```bash +flow scripts execute cadence/scripts/CheckCounter.cdc --network testnet +``` + +You will see output that shows the counter state: + +```bash +Result: {"count": 1, "isEven": false} +``` + +Notice that: + +- The original `count` value is preserved (showing the increment from our earlier test). +- The new `isEven()` function works correctly (1 is odd, so it returns false). + +--- + +## Upgrade the contract - part 2: add more functionality + +Now that we've successfully added the even number event, let's add more functionality to our contract. This demonstrates how you can make multiple incremental upgrades to extend your contract's capabilities. + +### Modify the Counter contract - second upgrade + +Update `cadence/contracts/Counter.cdc` to add the additional functionality: + +```cadence +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) + + // Event to be emitted when the counter is incremented and the result is even + access(all) event CounterIncrementedToEven(newCount: Int) + + // NEW: Event to be emitted when the counter is incremented by 2 + access(all) event CounterIncrementedByTwo(newCount: Int) + + // NEW: Event to be emitted when the counter is decremented by 2 + access(all) event CounterDecrementedByTwo(newCount: Int) + + init() { + self.count = 0 + } + + // Public function to increment the counter + access(all) fun increment() { + self.count = self.count + 1 + emit CounterIncremented(newCount: self.count) + + // Also emit event if the result is even + if self.count % 2 == 0 { + emit CounterIncrementedToEven(newCount: self.count) + } + } + + // Public function to decrement the counter + access(all) fun decrement() { + self.count = self.count - 1 + emit CounterDecremented(newCount: self.count) + } + + // Public function to get the current count + view access(all) fun getCount(): Int { + return self.count + } + + // NEW: Public function to increment the counter by 2 + access(all) fun incrementByTwo() { + self.count = self.count + 2 + emit CounterIncrementedByTwo(newCount: self.count) + } + + // NEW: Public function to decrement the counter by 2 + access(all) fun decrementByTwo() { + self.count = self.count - 2 + emit CounterDecrementedByTwo(newCount: self.count) + } + + // NEW: Public function to check if the current count is even + view access(all) fun isEven(): Bool { + return self.count % 2 == 0 + } +} +``` + +### Key changes made - part 2 + +This second upgrade adds: + +1. **New functions**: `incrementByTwo()` and `decrementByTwo()` that modify the current counter by two. +2. **New events**: `CounterIncrementedByTwo` and `CounterDecrementedByTwo` for the new functionality. +3. **New view function**: `isEven()` to check if the current count is even. +4. **Preserved existing functionality**: All previous functionality remains intact. + +--- + +## Update the deployed contract - part 2 + +Now let's update the deployed contract with our second upgrade. + +### Update the contract again + +Use the [Flow CLI update contract command] to upgrade your deployed contract with the additional functionality: + +```bash +flow accounts update-contract ./cadence/contracts/Counter.cdc --signer testnet-account --network testnet +``` + +You will see output similar to: + +```bash +Contract 'Counter' updated on account '0x9942a81bc6c3c5b7' + +Address 0x9942a81bc6c3c5b7 +Balance 99999999999.70000000 +Keys 1 + +Key 0 Public Key [your public key] + Weight 1000 + Signature Algorithm ECDSA_P256 + Hash Algorithm SHA3_256 + Revoked false + Sequence Number 3 + Index 0 + +Contracts Deployed: 1 +Contract: 'Counter' +``` + +:::success + +The contract successfully updated again! Notice that: + +- The contract address remains the same (`0x9942a81bc6c3c5b7`). +- The current state (`count`) is preserved. +- All previous functionality is still available. +- New functionality is now available. + +::: + +### Verify the update + +Let's verify that the existing functionality still works and the new functionality is available. + +Create a script to check the current state: + +```bash +flow generate script CheckCounter +``` + +Replace the contents of `cadence/scripts/CheckCounter.cdc` with: + +```cadence +import "Counter" + +access(all) fun main(): {String: AnyStruct} { + return { + "count": Counter.getCount(), + "isEven": Counter.isEven() + } +} +``` + +Run the script to check the current state: + +```bash +flow scripts execute cadence/scripts/CheckCounter.cdc --network testnet +``` + +You will see output showing the counter state: + +```bash +Result: {"count": 2, "isEven": true} +``` + +Notice that: + +- The original `count` value is preserved (showing the increments from our earlier tests). +- The new `isEven()` function works correctly (two is even, so it returns true). + +--- + +## Test the new functionality + +Now let's create a transaction to test the new even counter functionality. + +### Create test transaction + +Create a new transaction to test the upgraded functionality: + +```bash +flow generate transaction TestNewCounter +``` + +Replace the contents of `cadence/transactions/TestNewCounter.cdc` with: + +```cadence +import "Counter" + +transaction { + prepare(acct: &Account) { + // Authorizes the transaction + } + + execute { + // Test the new functionality + log("Current count: ".concat(Counter.getCount().toString())) + log("Is even: ".concat(Counter.isEven().toString())) + + // Test the new incrementByTwo function + Counter.incrementByTwo() + log("After incrementByTwo: ".concat(Counter.getCount().toString())) + log("Is even now: ".concat(Counter.isEven().toString())) + + Counter.incrementByTwo() + log("After second incrementByTwo: ".concat(Counter.getCount().toString())) + + // Test the new decrementByTwo function + Counter.decrementByTwo() + log("After decrementByTwo: ".concat(Counter.getCount().toString())) + + // Verify original functionality still works and test the new event + Counter.increment() + log("After regular increment: ".concat(Counter.getCount().toString())) + log("Is even now: ".concat(Counter.isEven().toString())) + + // Increment again to trigger the CounterIncrementedToEven event + Counter.increment() + log("After second increment: ".concat(Counter.getCount().toString())) + log("Is even now: ".concat(Counter.isEven().toString())) + } +} +``` + +### Run the test transaction + +Execute the transaction to test the new functionality: + +```bash +flow transactions send cadence/transactions/TestNewCounter.cdc --signer testnet-account --network testnet +``` + +You will see logs that show: + +- The counter incrementing by two each time with `incrementByTwo()` +- The counter decrementing by two with `decrementByTwo()` +- The `isEven()` function working correctly +- The original `increment()` function still working normally +- The new `CounterIncrementedToEven` event being emitted when incrementing results in an even number + +### Verify final state + +Run the check script again to see the final state: + +```bash +flow scripts execute cadence/scripts/CheckCounter.cdc --network testnet +``` + +You will see output similar to: + +```bash +Result: {"count": 6, "isEven": true} +``` + +This confirms that: + +- The new functions work correctly with the existing counter. +- The original state was preserved during the upgrade. +- The new functionality is fully operational. + +--- + +## Understand contract upgrades in Cadence + +Cadence provides a sophisticated contract upgrade system that ensures data consistency and allows controlled modifications. The [Cadence Contract Updatability documentation] provides comprehensive details about the validation rules and restrictions. + +### What you can upgrade + +When you upgrade Cadence contracts, you can: + +- **Add new state variables** (like `countEven`) +- **Add new functions** (like `incrementEven()` and `decrementEven()`) +- **Add new events** (like `EvenCounterIncremented`) +- **Add new interfaces** and resource types +- **Modify function implementations** (with careful consideration) +- **Remove existing functions** (they are not stored as data) +- **Change function signatures** (parameters, return types) +- **Change access modifiers** of fields and functions +- **Reorder existing fields** (order doesn't affect storage) + +### What You cannot change + +There are important limitations to contract upgrades: + +- **Cannot add new fields** to current structs, resources, or contracts. + - This would cause runtime crashes when you load current data. + - The initializer only runs once during deployment, not on updates. +- **Cannot change the type** of current state variables. + - Would cause deserialization errors with stored data. +- **Cannot remove existing state variables** (though they become inaccessible). +- **Cannot change enum structures** (raw values must remain consistent). +- **Cannot change the contract name** or address. + +### Validation goals + +The contract update validation ensures that: + +- **Stored data doesn't change its meaning** when a contract updates. +- **Decoding and using stored data** does not lead to runtime crashes. +- **Type safety is maintained** across all stored values. + +:::warning + +The validation system focuses on how to prevent runtime inconsistencies with stored data. It does not ensure that programs which import the updated contract remain valid - you may need to update dependent code if you change function signatures or remove functions. + +::: + +### Advanced upgrade patterns + +#### The `#removedType` pragma + +For cases where you need to remove a type declaration (which is normally invalid), Cadence provides the `#removedType` pragma. This allows you to "tombstone" a type, which prevents it from being re-added with the same name: + +```cadence +access(all) contract Foo { + // Remove the resource R permanently + #removedType(R) + + // Other contract code... +} +``` + +This pragma: + +- **Prevents security issues** from type confusion. +- **Cannot be removed** after you add it (prevents circumventing restrictions). +- **Only works with composite types**, not interfaces. + +#### Enum upgrade restrictions + +Enums have special restrictions due to their raw value representation: + +- **Can only add enum cases at the end** of current cases. +- **Cannot reorder, rename, or remove** current enum cases. +- **Cannot change the raw type** of an enum. +- **Cannot change enum case names** (would change stored values' meaning). + +### Best practices + +When you upgrade contracts: + +1. **Plan upgrades carefully** - Consider future extensibility and avoid breaking changes. +2. **Test thoroughly** - Verify both old and new functionality work correctly. +3. **Use events** - Emit events for new functionality to allow monitoring and indexing. +4. **Document changes** - Keep track of what was added, removed, or modified in each upgrade. +5. **Consider dependent code** - Update any programs that import your contract if you change function signatures. +6. **Use the `#removedType` pragma** - When you need to permanently remove types. +7. **Validate enum changes** - Ensure enum modifications follow the strict rules. +8. **Test with existing data** - Verify upgrades work with real stored state, not just empty contracts. + +--- + +## Why this matters + +Cadence's contract upgrade model provides several advantages: + +- **No proxy patterns needed** - Unlike Ethereum, you don't need complex proxy contracts. +- **State preservation** - Current data and functionality remain intact. +- **Address stability** - Contract addresses don't change during upgrades. +- **Gas efficiency** - Upgrades are more efficient than redeployment. +- **User experience** - Applications continue working without interruption. + +This approach allows you to evolve your contracts over time, You can add new features and capabilities and maintain backward compatibility and preserve user data. + +## Conclusion + +In this tutorial, you learned how to upgrade deployed Cadence contracts through multiple incremental upgrades by: + +- **Deploying an initial contract** to Flow testnet. +- **Performing a first upgrade** to add an event for even numbers based on user feedback. +- **Testing the first upgrade** to verify the new event functionality works correctly. +- **Performing a second upgrade** to add additional functions and events. +- **Testing the complete upgraded functionality** with comprehensive transactions. +- **Verifying state preservation** and backward compatibility across multiple upgrades. + +Now that you have completed the tutorial, you should be able to: + +- Deploy contracts to Flow testnet with Flow CLI. +- Perform incremental contract upgrades by adding new functions and events. +- Update deployed contracts multiple times and preserve the current state. +- Test upgraded functionality with Cadence transactions and scripts. +- Understand what can and cannot be changed during contract upgrades. +- Apply realistic upgrade scenarios based on user feedback and requirements. +- Plan and execute multiple contract upgrades over time. + +This incremental upgrade model makes Cadence contracts more flexible and maintainable than traditional smart contract platforms, which allows you to evolve your applications over time based on real user needs without complex migration patterns or breaking changes. The ability to make multiple upgrades while you maintain state and the same contract address provides a powerful foundation for long-term application development. + + + +[Flow CLI installed]: ../../../build/tools/flow-cli/install.md +[Cadence]: https://cadence-lang.org/docs/tutorial/first-steps +[Flow accounts]: ../../../build/cadence/basics/accounts.md +[Create accounts]: ../../../build/tools/flow-cli/commands.md#create-accounts +[Fund accounts]: ../../../build/tools/flow-cli/commands.md#fund-accounts +[Flow CLI update contract command]: ../../../build/tools/flow-cli/accounts/account-update-contract.md +[Cadence Contract Updatability documentation]: https://cadence-lang.org/docs/language/contract-updatability +[Compose with Cadence Transactions]: ./compose-with-cadence-transactions.md diff --git a/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md new file mode 100644 index 0000000000..e7504b6e87 --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/emulator-fork-testing/index.md @@ -0,0 +1,1194 @@ +--- +sidebar_position: 21 +sidebar_label: Emulator Fork Testing +title: Interactive Testing with Forked Emulator +description: Run your app, E2E tests, and manual explorations against a forked mainnet or testnet using the Flow Emulator. Test with production state and real contracts without deploying to live networks. +keywords: + - flow emulator --fork + - emulator fork mode + - E2E testing + - app testing + - frontend testing + - Cypress testing + - Playwright testing + - FCL configuration + - mainnet fork + - testnet fork + - account impersonation + - interactive testing + - production state + - local development + - forked emulator + - React testing + - wallet testing + - migration testing + - exploratory testing + - manual testing + - fork-height + - pinned fork +--- + +# Interactive Testing with Forked Emulator + +Fork testing gives you a local copy of mainnet state that you can freely modify and reset instantly. Test your DeFi app against real DEX liquidity pools and lending protocols without risking funds, verify integrations with existing mainnet contracts before deploying, and debug production issues at specific block heights with exact mainnet state. + +This tutorial teaches you how to run your app and E2E tests against Flow mainnet using `flow emulator --fork`. You'll connect your frontend to production-like state, impersonate any mainnet account, and test with real balances and assets—all running locally. + +## What You'll Learn + +After you complete this tutorial, you'll be able to: + +- **Start the emulator in fork mode** with `flow emulator --fork`. +- **Connect your app frontend** to the forked emulator. +- **Test DeFi integrations** against real liquidity pools, DEXs, and protocols. +- **Test against real mainnet contracts** and production data interactively. +- **Run E2E tests** (Cypress, Playwright) against forked state. +- **Use account impersonation** to test as any mainnet account with real balances and assets. +- **Pin to specific block heights** for reproducible testing. +- **Debug and explore** contract interactions manually. + +## What You'll Build + +You'll create a complete forked emulator setup that demonstrates: + +- Starting the emulator with forked mainnet state. +- A React app connected to the forked emulator reading real FlowToken data. +- Manual testing flows using account impersonation. +- Automating tests with E2E frameworks against forked state. +- A reusable pattern for interactive testing and debugging. + +## Prerequisites + +### Flow CLI + +This tutorial requires [Flow CLI] v1.8.0 or later installed. If you haven't installed it yet and have [homebrew] installed, run: + +```bash +brew install flow-cli +``` + +For other operating systems, refer to the [installation guide]. + +### Node.js and npm + +You'll need Node.js (v16+) and npm to run the React frontend examples. Check your installation: + +```bash +node --version +npm --version +``` + +### Frontend development knowledge + +Basic familiarity with React and JavaScript is helpful but not required. The examples use the [Flow React SDK] for Flow blockchain integration. + +:::tip + +This tutorial uses `@onflow/react-sdk` for all React examples. The React SDK provides hooks and components that make Flow development feel native to React. For non-React applications, you can use `@onflow/fcl` directly. + +::: + +### Network access + +You'll need network access to Flow's public access nodes: + +- Mainnet: `access.mainnet.nodes.onflow.org:9000` +- Testnet: `access.devnet.nodes.onflow.org:9000` + +:::info + +This tutorial covers `flow emulator --fork` (interactive testing with a forked emulator), which is different from `flow test --fork` (running Cadence test files against forked state). For an overview of both modes, see [Fork Testing](../../../build/tools/flow-cli/fork-testing.md). For testing Cadence contracts with test files, see [Fork Testing with Cadence]. + +::: + +## Understanding Emulator Fork Mode + +### What is `flow emulator --fork`? + +The emulator's fork mode starts a local Flow blockchain that connects to a real network (mainnet or testnet) and fetches state on-demand. Your app, scripts, and transactions run locally but can read from and interact with real network data. + +**Key capabilities:** + +- Full gRPC and REST API servers running locally +- On-demand fetching of accounts, contracts, and state from the live network +- Disabled signature validation. You can impersonate any mainnet account to execute transactions +- All mutations stay local—never affect the real network +- Perfect for E2E tests, manual exploration, and debugging + +### When to Use This + +Use `flow emulator --fork` for: + +- **DeFi application testing**: Test against real liquidity pools, DEXs, and lending protocols with production state +- **E2E and frontend testing**: Run Cypress/Playwright tests against production-like state +- **Manual exploration**: Interact with your app connected to forked mainnet +- **Debugging user issues**: Reproduce bugs at specific block heights +- **Migration testing**: Test contract upgrades with real account state +- **Wallet integration**: Test wallet connect flows and transactions +- **Bot and indexer testing**: Run automated tools against forked data + +**Don't use this for:** + +- Cadence unit/integration tests (use `flow test --fork` instead—see [Fork Testing with Cadence]) + +### Emulator Fork vs Test Framework Fork + +| Feature | `flow emulator --fork` | `flow test --fork` | +| --------------- | --------------------------------------- | ------------------------------ | +| **Use for** | App E2E, manual testing, debugging | Cadence unit/integration tests | +| **Connects to** | Frontend, wallets, bots, E2E tools | Cadence Testing Framework | +| **Run with** | FCL, Cypress, Playwright, manual clicks | `flow test` command | +| **Best for** | User flows, UI testing, exploration | Contract logic validation | +| **Examples** | React app, wallet flows, E2E suites | `*_test.cdc` files | + +Both modes are valuable—use the right tool for the job. + +## Quick Start: Run in 60 Seconds + +Want to see it work immediately? Here's the fastest path: + +```bash +# 1. Initialize a Flow project +flow init + +# 2. Install FlowToken dependency +flow dependencies install FlowToken FungibleToken + +# 3. Start forked emulator (in a separate terminal) +flow emulator --fork mainnet + +# 4. Create a script to check the forked state +flow generate script getFlowSupply +``` + +Add the following to `cadence/scripts/getFlowSupply.cdc`: + +```cadence +import "FlowToken" + +access(all) fun main(): UFix64 { + return FlowToken.totalSupply +} +``` + +First, verify the script works against real mainnet: + +```bash +flow scripts execute cadence/scripts/getFlowSupply.cdc --network mainnet +``` + +Then, in another terminal, run the script against the fork: + +```bash +flow scripts execute cadence/scripts/getFlowSupply.cdc --network mainnet-fork +``` + +You'll see the real mainnet FlowToken supply! Now let's build a complete example with a frontend. + +## Create Your Project + +Navigate to your development directory and create a new Flow project: + +```bash +mkdir emulator-fork-demo +cd emulator-fork-demo +flow init --yes +``` + +This creates an empty Flow project with default configuration. + +## Start the Forked Emulator + +Start the emulator in fork mode, connected to mainnet: + +```bash +flow emulator --fork mainnet +``` + +You'll see output like: + +``` +INFO[0000] ⚙️ Using service account 0xf8d6e0586b0a20c7 +INFO[0000] 🌱 Starting Flow Emulator in fork mode (mainnet) +INFO[0000] 🛠 GRPC server started on 127.0.0.1:3569 +INFO[0000] 📡 REST server started on 127.0.0.1:8888 +INFO[0000] 🌐 Forking from access.mainnet.nodes.onflow.org:9000 +``` + +**Leave this terminal running.** The emulator is now serving: + +- **REST API**: `http://localhost:8888` (for FCL/frontend) +- **gRPC API**: `localhost:3569` (for Flow CLI) + +:::info Fork Network Configuration + +When you run `flow init`, the CLI automatically configures a `mainnet-fork` network in your `flow.json` that inherits all contract aliases from mainnet. This means you don't need to manually configure fork networks—it just works! + +For details on fork network configuration, see the [Fork Testing Overview](../../../build/tools/flow-cli/fork-testing.md) and [flow.json Configuration Reference](../../../build/tools/flow-cli/flow.json/configuration.md#networks). + +::: + +:::tip + +Pin to a specific block height for reproducibility: + +```bash +flow emulator --fork mainnet --fork-height +``` + +This ensures the forked state is consistent across runs—essential for E2E tests in CI. + +::: + +## Deploy Your Contracts Against Mainnet State + +The most common use case: deploy your NEW contracts to the forked emulator so they can interact with real mainnet contracts and data. This lets you test your DeFi protocol against live DEXs, lending protocols, liquidity pools, and other production DeFi infrastructure. + +### Example: Deploy and Test Your Contract + +**1. Create your contract:** + +```bash +flow generate contract MyDeFiProtocol +``` + +Edit `cadence/contracts/MyDeFiProtocol.cdc`: + +```cadence +import "FlowToken" + +access(all) contract MyDeFiProtocol { + // Your DeFi logic that reads real mainnet FlowToken data + access(all) fun getTotalSupply(): UFix64 { + return FlowToken.totalSupply + } +} +``` + +**2. Start the forked emulator:** + +```bash +flow emulator --fork mainnet +``` + +When the emulator starts, note the service account address in the logs: + +``` +⚙️ Using service account 0xe467b9dd11fa00df +``` + +**3. Configure the service account:** + +Add the forked emulator's service account (use the address from the startup logs and a dummy key). + +First, create a dummy key file. Use a simple P-256 placeholder so tooling that validates curve membership continues working: + +```bash +echo "0x0000000000000000000000000000000000000000000000000000000000000001" > blank-key.pkey +``` + +Then manually add to your `flow.json`: + +```json +{ + "accounts": { + "mainnet-fork-service": { + "address": "0xe467b9dd11fa00df", + "key": { + "type": "file", + "location": "blank-key.pkey" + } + } + } +} +``` + +Since signature validation is disabled in fork mode, the key value doesn't matter. + +**4. Configure deployment:** + +```bash +flow config add deployment \ + --network mainnet-fork \ + --account mainnet-fork-service \ + --contract MyDeFiProtocol +``` + +**5. Deploy your contract:** + +```bash +flow project deploy --network mainnet-fork --update +``` + +:::tip + +Use `--update` if you're working on an existing project that's already deployed to mainnet. The forked emulator mirrors mainnet state, so if your contract already exists at that address on mainnet, it will exist in the fork too. The `--update` flag replaces the mainnet version with your local changes. + +::: + +**6. Test your contract:** + +Your contract can now interact with real mainnet contracts! Create a script to test it: + +```bash +flow generate script getTotalSupply +``` + +Add the following to `cadence/scripts/getTotalSupply.cdc`: + +```cadence +import "MyDeFiProtocol" + +access(all) fun main(): UFix64 { + return MyDeFiProtocol.getTotalSupply() +} +``` + +Run the script: + +```bash +flow scripts execute cadence/scripts/getTotalSupply.cdc --network mainnet-fork +``` + +You'll see something like `Result: 1628083999.54686045` - the real mainnet FlowToken supply! Your contract runs locally but reads production data. Perfect for testing integrations before mainnet deployment. + +## Mock Existing Mainnet Contracts + +You can override existing mainnet contracts with your own versions for testing. This is useful for testing contract upgrades, fixing bugs, or adding test functionality to mainnet contracts. + +### Example: Mock a Mainnet Contract + +Let's say you want to test how your DeFi protocol behaves with a modified version of an existing mainnet contract. + +**1. Create your mock oracle contract:** + +```bash +flow generate contract PriceOracle +``` + +Edit `cadence/contracts/PriceOracle.cdc` to match the interface of the mainnet oracle you want to mock: + +```cadence +// Mock implementation of mainnet PriceOracle with fixed test prices +access(all) contract PriceOracle { + access(all) fun getPrice(): UFix64 { + return 123.45 // Fixed test price for predictable testing + } +} +``` + +**2. Deploy to the SAME address as the mainnet oracle:** + +In your `flow.json`, configure deployment to use the mainnet oracle's address: + +```json +{ + "contracts": { + "PriceOracle": "cadence/contracts/PriceOracle.cdc" + }, + "deployments": { + "mainnet-fork": { + "mainnet-oracle-account": ["PriceOracle"] + } + }, + "accounts": { + "mainnet-oracle-account": { + "address": "0x1654653399040a61", + "key": { + "type": "file", + "location": "blank-key.pkey" + } + } + } +} +``` + +**3. Deploy with `--update` flag:** + +```bash +flow project deploy --network mainnet-fork --update +``` + +Now your mock oracle replaces the mainnet oracle at that address. All imports and references to the original oracle will use your mocked version with fixed test prices instead! + +:::tip + +This is how you test contract upgrades or modifications against real mainnet state without affecting the live network. + +::: + +## Install Dependencies + +Use the [Dependency Manager] to install common Flow contracts. This adds them to your `flow.json` with mainnet aliases that will automatically work on the fork: + +```bash +flow dependencies install FlowToken FungibleToken +``` + +Your `flow.json` now includes: + +```json +{ + "dependencies": { + "FlowToken": { + "source": "mainnet://1654653399040a61.FlowToken", + "aliases": { + "emulator": "0x0ae53cb6e3f42a79", + "mainnet": "0x1654653399040a61", + "testnet": "0x7e60df042a9c0868" + } + }, + "FungibleToken": { + "source": "mainnet://f233dcee88fe0abe.FungibleToken", + "aliases": { + "emulator": "0xee82856bf20e2aa6", + "mainnet": "0xf233dcee88fe0abe", + "testnet": "0x9a0766d93b6608b7" + } + } + } +} +``` + +**Key insight:** Notice there's no `mainnet-fork` alias. That's the beauty—`mainnet-fork` automatically inherits the `mainnet` aliases thanks to the fork configuration! + +## Test with Flow CLI Scripts + +Before connecting a frontend, verify the fork works with a simple script. + +Generate a script file using the Flow CLI: + +```bash +flow generate script getFlowSupply +``` + +Add the following to `cadence/scripts/getFlowSupply.cdc`: + +```cadence +import "FlowToken" + +access(all) fun main(): UFix64 { + return FlowToken.totalSupply +} +``` + +Notice we're using the import shorthand `import "FlowToken"` instead of an address. The CLI will automatically resolve this to the mainnet address on the fork. + +First, verify the script works against real mainnet: + +```bash +flow scripts execute cadence/scripts/getFlowSupply.cdc --network mainnet +``` + +Then, in a **new terminal** (keep the emulator running), execute the script against the fork: + +```bash +flow scripts execute cadence/scripts/getFlowSupply.cdc --network mainnet-fork +``` + +You should see the real mainnet FlowToken supply (e.g., `Result: 1523456789.00000000`). + +**What happened:** + +1. Your script ran on the local emulator +2. The CLI resolved `"FlowToken"` to the mainnet address (`0x1654653399040a61`) +3. The emulator fetched FlowToken contract state from mainnet on-demand +4. The script returned real production data + +Now let's connect a frontend. + +## Create a React App + +Create a Next.js app with Flow integration: + +```bash +npx create-next-app@latest flow-fork-app +``` + +During setup, choose: + +- **Use TypeScript**: Yes +- **Use src directory**: Yes +- **Use App Router**: Yes + +Then install the Flow React SDK: + +```bash +cd flow-fork-app +npm install @onflow/react-sdk +``` + +Copy your project's `flow.json` into the app's `src` directory: + +```bash +# From your flow-fork-app directory +cp ../flow.json src/ +``` + +This allows the `FlowProvider` to resolve contract imports. + +### Configure for Fork Testing + +Since Next.js uses the App Router with server components, create a client component wrapper. First, create the components directory: + +```bash +mkdir -p src/components +``` + +Then create `src/components/FlowProviderWrapper.tsx`: + +```typescript +'use client'; + +import { FlowProvider } from '@onflow/react-sdk'; +import flowJSON from '../flow.json'; + +export default function FlowProviderWrapper({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} +``` + +Then update `src/app/layout.tsx` to use the wrapper: + +```typescript +import FlowProviderWrapper from '@/components/FlowProviderWrapper'; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + {children} + + + ); +} +``` + +### Create a Demo Component + +Create a simple demo that queries FlowToken supply from the forked mainnet. Update `src/app/page.tsx`: + +```typescript +'use client'; + +import { useState } from 'react'; +import { useFlowCurrentUser, useFlowQuery, Connect } from '@onflow/react-sdk'; + +export default function Home() { + const { user } = useFlowCurrentUser(); + const [shouldFetch, setShouldFetch] = useState(false); + + // Query FlowToken supply from forked mainnet + const { + data: flowSupply, + isLoading, + error, + } = useFlowQuery({ + cadence: ` + import "FlowToken" + + access(all) fun main(): UFix64 { + return FlowToken.totalSupply + } + `, + args: (arg, t) => [], + query: { + enabled: shouldFetch, // Only run when button is clicked + }, + }); + + return ( +
+

🌊 Flow Emulator Fork Demo

+

+ Connected to: Forked Mainnet (localhost:8888) +

+ +
+

FlowToken Supply (Real Mainnet Data)

+ + {error &&

Error: {(error as Error).message}

} + {flowSupply && ( +

+ Total Supply: {Number(flowSupply).toLocaleString()} FLOW +

+ )} +
+ +
+

Wallet Connection

+ + {user?.loggedIn && ( +

+ Connected: {user.addr} +

+ )} +
+
+ ); +} +``` + +### Start the dev wallet (optional) + +For wallet authentication flows, start the FCL dev wallet in another terminal: + +```bash +flow dev-wallet +``` + +This starts the dev wallet at `http://localhost:8701`. + +### Run your app + +Start the Next.js dev server: + +```bash +npm run dev +``` + +Navigate to `http://localhost:3000`. Click "Get FlowToken Supply" to see real mainnet data! + +**What's happening:** + +1. `FlowProvider` receives `flow.json` and configures import resolution +2. The string import `import "FlowToken"` resolves to the mainnet address automatically +3. `useFlowQuery` executes the Cadence script via the local emulator +4. The emulator fetches FlowToken state from mainnet on-demand +5. Your app displays real production data—all running locally! + +**Key React SDK features used:** + +- `FlowProvider` – Wraps your app, configures the Flow connection, and resolves contract imports from `flow.json` +- `useFlowCurrentUser` – Provides wallet authentication state +- `useFlowQuery` – Executes Cadence scripts with automatic caching and loading states +- `Connect` – Pre-built wallet connection UI component + +:::tip Contract Import Resolution + +By passing `flowJson` to the `FlowProvider`, string imports like `import "FlowToken"` automatically resolve to the correct network addresses. + +**How it works:** + +1. SDK looks up contract aliases for the specified `flowNetwork` +2. For fork networks, it checks if the network has a `fork` property and inherits aliases from the parent network +3. Contract imports in your Cadence code are replaced with the resolved addresses + +**Example:** With `flowNetwork: 'mainnet-fork'` (which has `fork: 'mainnet'`), `import "FlowToken"` resolves to `0x1654653399040a61` (the mainnet FlowToken address). + +::: + +## Account Impersonation + +The forked emulator's superpower: you can execute transactions as **any mainnet account** because signature validation is disabled. + +### Read Account Balance + +Generate a script to read account balances: + +```bash +flow generate script getBalance +``` + +Add the following to `cadence/scripts/getBalance.cdc`: + +```cadence +import "FlowToken" +import "FungibleToken" + +access(all) fun main(address: Address): UFix64 { + let account = getAccount(address) + let vaultRef = account.capabilities + .borrow<&{FungibleToken.Balance}>(/public/flowTokenBalance) + ?? panic("Could not borrow FlowToken Balance reference") + + return vaultRef.balance +} +``` + +Check the Flow service account balance (a real mainnet account): + +```bash +flow scripts execute cadence/scripts/getBalance.cdc 0x1654653399040a61 --network mainnet-fork +``` + +You'll see the service account's actual mainnet balance! The imports automatically resolved to mainnet addresses because you're using the `mainnet-fork` network. + +### Execute Transaction as Any Account + +Generate a transaction to transfer tokens: + +```bash +flow generate transaction transferTokens +``` + +Add the following to `cadence/transactions/transferTokens.cdc`: + +```cadence +import "FungibleToken" +import "FlowToken" + +transaction(amount: UFix64, to: Address) { + let sentVault: @{FungibleToken.Vault} + + prepare(signer: auth(Storage) &Account) { + let vaultRef = signer.storage.borrow( + from: /storage/flowTokenVault + ) ?? panic("Could not borrow reference to the owner's Vault") + + self.sentVault <- vaultRef.withdraw(amount: amount) + } + + execute { + let recipient = getAccount(to) + let receiverRef = recipient.capabilities + .borrow<&{FungibleToken.Receiver}>(/public/flowTokenReceiver) + ?? panic("Could not borrow receiver reference") + + receiverRef.deposit(from: <-self.sentVault) + } +} +``` + +The forked emulator disables transaction signature validation, allowing you to send transactions as any address without valid signatures. + +Now let's test transferring tokens from a mainnet account using impersonation. + +### CLI-Based Impersonation + +To use impersonation with the CLI, you need to add the mainnet account to your `flow.json` (signature validation is disabled, so the key value doesn't matter). + +Manually add to your `flow.json` (using the same `blank-key.pkey` file): + +```json +{ + "accounts": { + "mainnet-service": { + "address": "0x1654653399040a61", + "key": { + "type": "file", + "location": "blank-key.pkey" + } + } + } +} +``` + +Transfer tokens from the mainnet service account to another mainnet account: + +```bash +# Transfer from mainnet service account to any mainnet address (impersonation!) +flow transactions send cadence/transactions/transferTokens.cdc 100.0 0xRECIPIENT_ADDRESS \ + --signer mainnet-service \ + --network mainnet-fork + +# Verify the transfer +flow scripts execute cadence/scripts/getBalance.cdc 0xRECIPIENT_ADDRESS \ + --network mainnet-fork +``` + +### Dev Wallet Authentication with Impersonation + +The most powerful feature: when connecting your app to the forked emulator with the dev wallet, **you can authenticate as ANY mainnet account** directly in the UI. + +Start the dev wallet: + +```bash +flow dev-wallet +``` + +In your app (running against the forked emulator), click the wallet connect button. In the dev wallet UI: + +1. **Enter any mainnet address** in the address field (e.g., a whale wallet, liquidity provider, or DeFi protocol account) +2. Click "Authenticate" +3. Your app is now authenticated as that mainnet account with all its real balances, liquidity positions, and storage! + +**Additional dev wallet features in fork mode:** + +- **Fund accounts**: The dev wallet can add FLOW tokens to any account, even real mainnet accounts +- **No configuration needed**: The dev wallet handles impersonation automatically when connected to a forked emulator +- **Full account state**: Access all assets, storage, and capabilities from the real mainnet account + +This lets you: + +- Test your app as a user with specific assets or permissions +- Debug issues reported by specific mainnet accounts +- Verify flows work for accounts with large balances or complex liquidity positions +- Test edge cases with real account states +- Add test funds to accounts that need more FLOW for testing + +:::tip How "Impersonation" Works + +The forked emulator simply skips signature verification. You can specify any mainnet address as the signer, and the emulator will execute the transaction as that account. Empty or invalid signatures are accepted. This lets you test with real account balances, storage, and capabilities without needing private keys. For frontend flows with the dev wallet, it works the same way—the wallet can "sign" as any address because the emulator doesn't validate signatures. + +::: + +## Automating with E2E Testing + +The forked emulator works with any E2E testing framework (Cypress, Playwright, Puppeteer, etc.). This lets you automate your app tests against production-like state. + +### Quick Example with Cypress + +```bash +npm install --save-dev cypress +``` + +Create `cypress/e2e/flowFork.cy.js`: + +```javascript +describe('Flow Fork Test', () => { + it('reads real mainnet data', () => { + cy.visit('http://localhost:3000'); + cy.contains('Get FlowToken Supply').click(); + cy.contains('Total Supply:', { timeout: 10000 }).should('be.visible'); + }); +}); +``` + +### Running E2E Tests + +Run three terminals: + +1. **Terminal 1**: `flow emulator --fork mainnet --fork-height ` +2. **Terminal 2**: `npm start` (your React app) +3. **Terminal 3**: `npx cypress run` + +Your tests now run against forked mainnet—**perfect for CI/CD pipelines** with pinned block heights ensuring deterministic results. + +:::tip + +Use the same approach with Playwright, Puppeteer, or any browser automation tool. The key is having your app connect to the forked emulator (`http://localhost:8888`) while your E2E framework tests the UI. + +::: + +## Common Use Cases + +### Testing DeFi Applications + +Test your DeFi application against real mainnet liquidity and protocols: + +1. Fork mainnet at a specific block height +2. Impersonate accounts with large token balances or LP positions +3. Test your swap, lending, or yield farming logic against real DEX state +4. Verify slippage calculations with actual liquidity pool reserves +5. Test edge cases like low liquidity scenarios using real market conditions + +**Example: Testing a swap integration** + +```bash +# Fork at a known block with specific liquidity conditions +flow emulator --fork mainnet --fork-height + +# In your test, impersonate a whale account +# Execute swaps against real DEX contracts (IncrementFi, etc.) +# Verify your price calculations match actual execution +``` + +This lets you test against production liquidity without spending real tokens or affecting live markets. + +### Testing Contract Upgrades + +Test a contract upgrade against real mainnet state by mocking the contract with your upgraded version: + +1. Configure the mock in `flow.json` (see [Mocking Mainnet Contracts](#mocking-mainnet-contracts)) +2. Start the forked emulator +3. Deploy your upgraded contract: `flow project deploy --network mainnet-fork --update` +4. Test your app against the upgraded contract with all real mainnet state intact +5. Verify existing integrations and users aren't broken by the upgrade + +### Debugging User-Reported Issues + +Reproduce a bug at the exact block height it occurred: + +```bash +flow emulator --fork mainnet --fork-height +``` + +Then manually interact with your app or run specific transactions to reproduce the issue. + +### Testing Wallet Integrations + +Test wallet connect flows, transaction signing, and account creation against production-like state: + +1. Start forked emulator and dev wallet +2. Use your app to authenticate +3. Sign transactions as real mainnet accounts (via impersonation) +4. Verify balance updates, event emissions, etc. + +### Running Bots and Indexers + +Test automated tools against forked data by pointing your SDK to the local emulator: + +**Any Flow SDK works:** + +- **JavaScript/TypeScript**: `@onflow/fcl` +- **Go**: `flow-go-sdk` +- **Python**: `flow-py-sdk` +- **Other languages**: Configure to connect to `http://localhost:8888` + +**Example with JavaScript:** + +```javascript +// Node.js bot that monitors FlowToken transfers +const fcl = require('@onflow/fcl'); + +fcl.config({ + 'accessNode.api': 'http://localhost:8888', // Point to forked emulator +}); + +async function monitorTransfers() { + // Subscribe to blocks and process FlowToken events + // Bot reads real mainnet data but runs locally +} +``` + +**Example with Go:** + +```go +import "github.com/onflow/flow-go-sdk/client" + +// Connect to forked emulator +flowClient, err := client.New("localhost:3569", grpc.WithInsecure()) + +// Your bot/indexer logic reads from forked mainnet state +``` + +## Best Practices + +### 1. Pin Block Heights for Reproducibility + +Always pin heights in E2E tests and CI: + +```bash +flow emulator --fork mainnet --fork-height 85432100 +``` + +**Why:** Ensures tests run against identical state every time. + +### 2. Keep Emulator Running During Development + +Start the forked emulator once and leave it running. Restart only when you need to change the fork height or network. + +### 3. Use Testnet Before Mainnet + +Test against testnet first to avoid mainnet access node rate limits: + +```bash +flow emulator --fork testnet --fork-height +``` + +### 4. Mock External Dependencies + +The forked emulator only mirrors Flow blockchain state. External APIs, oracles, and cross-chain data won't work. Mock them in your E2E tests: + +```javascript +// In Cypress: Mock external oracle response +cy.intercept('GET', 'https://api.example.com/price', { + statusCode: 200, + body: { price: 123.45 }, +}); +``` + +In your React app, you can mock API calls during testing while keeping real implementations for production. + +### 5. Test Against Real User Accounts + +The forked emulator disables signature validation, so you can transact as any mainnet account. Just reference the address—empty or invalid signatures are accepted: + +```bash +# Execute a transaction as any mainnet account +flow transactions send my_transaction.cdc \ + --signer 0x1234567890abcdef \ + --network mainnet-fork +``` + +This lets you test with real whale wallets, liquidity provider accounts, or any address that has interesting DeFi state on mainnet. + +### 6. Document Your Fork Heights + +Keep a log of which block heights you use for testing and why: + +```bash +# .env.test +FORK_HEIGHT_STABLE= # Known stable state +FORK_HEIGHT_LATEST= # Latest tested state +``` + +## Limitations and Considerations + +### Network State Fetching + +Fork mode fetches state from the access node on-demand. The first access to an account or contract fetches data over the network; subsequent accesses benefit from caching. With pinned block heights, caching is very effective. + +### Spork Boundaries + +Historical data is only available within the current spork. You cannot fork to block heights from previous sporks via public access nodes. + +See: [Network Upgrade (Spork) Process]. + +### Off-Chain Services + +The fork only includes Flow blockchain state. External services don't work: + +- **Oracles**: Mock responses +- **IPFS/Arweave**: Mock or run local nodes +- **Cross-chain bridges**: Mock or test separately + +## Troubleshooting + +### Emulator Won't Start + +**Error:** `network "mainnet" not found in flow.json` + +**Solution:** Make sure your `flow.json` includes the mainnet network: + +```json +{ + "networks": { + "mainnet": "access.mainnet.nodes.onflow.org:9000" + } +} +``` + +Or use `--fork-host` directly: + +```bash +flow emulator --fork-host access.mainnet.nodes.onflow.org:9000 +``` + +### Contract Import Fails + +**Error:** `import "FlowToken" could not be resolved` + +**Solution:** Make sure you've installed dependencies with the mainnet alias: + +```bash +flow dependencies install FlowToken FungibleToken +``` + +Verify the contract has a mainnet alias that the fork can inherit. + +### App Can't Connect + +**Error:** Frontend can't reach the emulator + +**Solution:** Verify FlowProvider is configured correctly: + +```javascript + + + +``` + +Check the emulator is running and serving on port 8888. + +**Common mistakes:** + +1. **Wrong network:** Using `flowNetwork: 'emulator'` when forking mainnet will use emulator contract addresses (`0x0ae53cb6...`) instead of mainnet addresses. Use your fork network name (`'mainnet-fork'`). + +2. **Missing flowJson prop:** The `flowJson` prop is required for contract import resolution. Make sure you're importing and passing your `flow.json` file. + +### Script Returns Stale Data + +**Issue:** Script returns unexpected/old values + +**Solution:** The fork fetches state at the pinned height or latest. Verify: + +```bash +# Check which block the emulator is at +flow blocks get latest --network emulator +``` + +If you need fresher data, restart without `--fork-height`. + +### E2E Tests Flaky + +**Issue:** Tests pass sometimes but fail randomly + +**Solution:** + +1. Pin block height for consistency +2. Add longer timeouts for network calls +3. Check for race conditions in async code + +## When to Use Emulator Fork vs Test Framework Fork + +Choose the right tool: + +| Use Case | Tool | +| --------------------------------------------- | ---------------------- | +| Cadence unit tests | `flow test` (no fork) | +| Cadence integration tests with real contracts | `flow test --fork` | +| Manual testing with app | `flow emulator --fork` | +| E2E testing (Cypress/Playwright) | `flow emulator --fork` | +| Debugging frontend issues | `flow emulator --fork` | +| Testing wallets/bots/indexers | `flow emulator --fork` | + +Both modes complement each other. See [Testing Strategy] for the full picture. + +## Conclusion + +In this tutorial, you learned how to use the forked emulator for interactive testing, E2E test automation, and manual exploration. You created a React app using the Flow React SDK connected to forked mainnet, used account impersonation to test with real account states, and saw how to automate tests with E2E frameworks—all without deploying to a live network. + +Now that you have completed this tutorial, you can: + +- **Start the emulator in fork mode** with `flow emulator --fork`. +- **Connect your app frontend** to the forked emulator. +- **Test against real mainnet contracts** and production data interactively. +- **Run E2E tests** (Cypress, Playwright) against forked state. +- **Use account impersonation** to test as any mainnet account. +- **Pin to specific block heights** for reproducible testing. +- **Debug and explore** contract interactions manually. + +The forked emulator bridges the gap between local development and testnet/mainnet deployments. Use it to catch integration issues early, test against real-world conditions, and validate your app before going live. + +### Next Steps + +- Add E2E tests to your CI/CD pipeline using pinned fork heights +- Test your app's upgrade flows against forked mainnet +- Review the [Fork Testing Overview] for both emulator and test framework fork modes +- For Cadence contract testing, see [Fork Testing with Cadence] +- Explore [Flow React SDK] hooks and components (events, mutations, Cross-VM features) +- Review the [Testing Strategy] for the full testing approach +- Check [Flow Emulator] docs for advanced emulator flags + + + +[Flow CLI]: ../../../build/tools/flow-cli/index.md +[homebrew]: https://brew.sh +[installation guide]: ../../../build/tools/flow-cli/install.md +[Fork Testing Overview]: ../../../build/tools/flow-cli/fork-testing.md +[Fork Testing with Cadence]: ../fork-testing/index.md +[Testing Strategy]: ../../../build/cadence/smart-contracts/testing-strategy.md +[Network Upgrade (Spork) Process]: ../../../protocol/node-ops/node-operation/network-upgrade.md +[Flow Emulator]: ../../../build/tools/emulator/index.md +[Dependency Manager]: ../../../build/tools/flow-cli/dependency-manager.md +[Flow React SDK]: ../../../build/tools/react-sdk/index.mdx diff --git a/docs/blockchain-development-tutorials/cadence/fork-testing/index.md b/docs/blockchain-development-tutorials/cadence/fork-testing/index.md new file mode 100644 index 0000000000..4208a6fa5f --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/fork-testing/index.md @@ -0,0 +1,650 @@ +--- +sidebar_position: 20 +sidebar_label: Fork Testing +title: Fork Testing with Cadence +description: Run your Cadence test suite against a forked mainnet or testnet using fork testing. Test against real contracts and production data without deploying to live networks. +keywords: + - fork testing + - test_fork pragma + - flow test + - cadence tests + - mainnet fork + - testnet fork + - integration testing + - Flow CLI + - account impersonation + - production testing + - real contracts + - on-chain state + - block height + - historical debugging + - reproducible tests + - test deployment + - FlowToken + - FungibleToken + - test scripts + - test transactions + - local testing + - safe testing + - forked runtime +--- + +# Fork Testing with Cadence + +This tutorial teaches you how to run your Cadence tests against a snapshot of Flow mainnet using `flow test` with the `#test_fork` pragma. You'll learn how to test your contracts against real deployed contracts and production data without needing to deploy anything to a live network or bootstrap test accounts. + +Fork testing bridges the gap between isolated local unit tests and testnet deployments. It allows you to validate your contracts work correctly with real on-chain state, test integrations with deployed contracts, and debug issues with historical blockchain data—all in a safe, local environment. + +## What you'll learn + +After you complete this tutorial, you'll be able to: + +- **Run Cadence tests against forked networks** with `#test_fork`. +- **Test contracts that depend on real mainnet contracts** without manual setup. +- **Use account impersonation** to execute transactions as any mainnet account. +- **Read from production blockchain state** in your test suite. +- **Pin tests to specific block heights** for historical debugging. +- **Integrate fork testing** into your development workflow. + +## What you'll build + +You'll create a complete fork testing setup that demonstrates: + +- How to read from the live FlowToken contract on mainnet. +- How to deploy your own contract that interacts with mainnet contracts. +- How to test custom logic against real account balances and state. +- How to execute transactions with impersonated mainnet accounts. +- A reusable pattern for integration tests your Flow applications. + +## Prerequisites + +### Flow CLI + +This tutorial requires [Flow CLI] v1.8.0 or later installed. If you haven't installed it yet and have [homebrew] installed, run: + +```bash +brew install flow-cli +``` + +For other operating systems, refer to the [installation guide]. + +### Basic Cadence testing knowledge + +You should be familiar with how to write basic Cadence tests. If you're new to Cadence testing, start with [Testing Smart Contracts] first. + +### Network access + +You'll need network access to Flow's public access nodes. The tutorial uses these endpoints, which are freely available: + +- Mainnet: `access.mainnet.nodes.onflow.org:9000` +- Testnet: `access.devnet.nodes.onflow.org:9000` + +:::info + +This tutorial covers fork testing with `flow test` (running tests against forked network state), which is different from `flow emulator --fork` (starting the emulator in fork mode for manual interaction). + +::: + +## Create your project + +Navigate to your development directory and create a new Flow project: + +```zsh +mkdir fork-testing-demo +cd fork-testing-demo +flow init --yes +``` + +The `--yes` flag accepts defaults non-interactively. `flow init` is interactive by default and can scaffold various templates. + +Alternatively, create the directory and initialize in one command: + +```zsh +flow init fork-testing-demo --yes +cd fork-testing-demo +``` + +## Install dependencies + +Use the [Dependency Manager] to install the `FlowToken` and `FungibleToken` contracts: + +```zsh +flow dependencies install FlowToken FungibleToken +``` + +This downloads the contracts into the `imports/` folder and configures aliases for different networks. + +## Understanding `mainnet-fork` + +When you run `flow init`, the CLI automatically creates a `mainnet-fork` network in your `flow.json`. This network inherits all contract addresses from mainnet, so imports like `"FlowToken"` automatically resolve to their mainnet addresses (`0x1654653399040a61`). + +Using `#test_fork(network: "mainnet-fork")` in your test files runs your tests against a local snapshot of mainnet state. You can deploy contracts, impersonate accounts, and modify state locally without affecting the real network. + +## Test reading live state + +Generate a script to read `FlowToken` supply: + +```zsh +flow generate script GetFlowTokenSupply +``` + +Open `cadence/scripts/GetFlowTokenSupply.cdc` and replace its contents with: + +```cadence cadence/scripts/GetFlowTokenSupply.cdc +import "FlowToken" + +access(all) fun main(): UFix64 { + return FlowToken.totalSupply +} +``` + +Generate the test file: + +```zsh +flow generate test FlowToken +``` + +Open `cadence/tests/FlowToken_test.cdc` and replace its contents with: + +```cadence cadence/tests/FlowToken_test.cdc +#test_fork(network: "mainnet-fork", height: nil) + +import Test + +access(all) fun testFlowTokenSupplyIsPositive() { + let scriptResult = Test.executeScript( + Test.readFile("../scripts/GetFlowTokenSupply.cdc"), + [] + ) + + Test.expect(scriptResult, Test.beSucceeded()) + + let supply = scriptResult.returnValue! as! UFix64 + Test.assert(supply > 0.0, message: "FlowToken supply should be positive") +} +``` + +:::info + +- **The `#test_fork` pragma** configures this test to run against the `mainnet-fork` network +- Use `Test.executeScript()` to read contract state +- The script imports `FlowToken` by name - the dependency manager handles address resolution +- Because we're using `mainnet-fork`, this automatically uses the mainnet FlowToken contract +- Extract the return value with proper type casting and assert on it +- File paths in `Test.readFile()` are relative to the test file location (use `../scripts/` from `cadence/tests/`) + +::: + +#### Quick verify + +Run just this test file to confirm your setup works: + +```zsh +flow test cadence/tests/FlowToken_test.cdc +``` + +The pragma handles the fork configuration automatically! You will see the test PASS. If not, verify your network host in `flow.json` and that dependencies are installed. + +## Deploy and test Your contract + +Now you'll create a contract that depends on FlowToken and test it against the forked mainnet state. There's no need to bootstrap tokens or set up test accounts. + +### Create a test account + +Create a new account to deploy your contract: + +```zsh +flow accounts create +``` + +Follow the prompts: + +- Select "mainnet" for the network. +- Name your account as desired. + +This will output the new account address. Use this address as the mainnet alias for your contract in flow.json. + +:::note + +This creates a local account with a mainnet-format address for fork testing. When you're ready to deploy to actual mainnet, you'll use this same account—see the [Deploying Contracts guide](pathname:///build/cadence/smart-contracts/deploying) for details. +::: + +### Create a contract that uses `FlowToken` + +Generate a new contract: + +```zsh +flow generate contract TokenChecker +``` + +This creates `cadence/contracts/TokenChecker.cdc` and adds it to `flow.json`. Now update the contract with your logic: + +```cadence cadence/contracts/TokenChecker.cdc +import "FlowToken" + +access(all) contract TokenChecker { + + access(all) fun checkBalance(address: Address): UFix64 { + let account = getAccount(address) + + let vaultRef = account.capabilities + .borrow<&FlowToken.Vault>(/public/flowTokenBalance) + ?? panic("Could not borrow FlowToken Vault reference") + + return vaultRef.balance + } + + access(all) fun hasMinimumBalance(address: Address, minimum: UFix64): Bool { + return self.checkBalance(address: address) >= minimum + } +} +``` + +### Configure contract in flow.json + +Add the `TokenChecker` contract configuration to `flow.json`. The contract needs a **mainnet alias** so that imports can resolve properly during fork testing. + +Update your `flow.json` to include the contract with aliases, and use the address you generated in the previous step: + +```json +{ + "contracts": { + "TokenChecker": { + "source": "cadence/contracts/TokenChecker.cdc", + "aliases": { + "testing": "0000000000000008", + "mainnet": "" + } + } + }, + "accounts": { + "mainnet-test": { + "address": "" + } + } +} +``` + +:::info + +No local private key is required for forked tests. The accounts entry above is included so you can copy and reference the address in your config. You can also omit keys for fork tests. Contracts deploy to the testing environment at `testing` alias, and transactions that interact with forked state can use impersonation. The `Test.deployContract` function will automatically deploy your contract to the testing environment during test execution. + +::: + +### Create scripts for testing + +Generate the scripts: + +```zsh +flow generate script CheckBalance +flow generate script HasMinimumBalance +``` + +Open `cadence/scripts/CheckBalance.cdc` and replace its contents with: + +```cadence cadence/scripts/CheckBalance.cdc +import "TokenChecker" + +access(all) fun main(addr: Address): UFix64 { + return TokenChecker.checkBalance(address: addr) +} +``` + +Open `cadence/scripts/HasMinimumBalance.cdc` and replace its contents with: + +```cadence cadence/scripts/HasMinimumBalance.cdc +import "TokenChecker" + +access(all) fun main(addr: Address, min: UFix64): Bool { + return TokenChecker.hasMinimumBalance(address: addr, minimum: min) +} +``` + +### Test Your contract with forked state + +Generate the test file: + +```zsh +flow generate test TokenChecker +``` + +Open `cadence/tests/TokenChecker_test.cdc` and replace its contents with: + +```cadence cadence/tests/TokenChecker_test.cdc +#test_fork(network: "mainnet-fork", height: nil) + +import Test + +access(all) fun setup() { + // Deploy TokenChecker to the test account + let err = Test.deployContract( + name: "TokenChecker", + path: "../contracts/TokenChecker.cdc", + arguments: [] + ) + Test.expect(err, Test.beNil()) +} + +access(all) fun testCheckBalanceOnRealAccount() { + // Test against a real mainnet account (Flow service account) + let scriptResult = Test.executeScript( + Test.readFile("../scripts/CheckBalance.cdc"), + [Address(0x1654653399040a61)] // Flow service account on mainnet + ) + + Test.expect(scriptResult, Test.beSucceeded()) + + let balance = scriptResult.returnValue! as! UFix64 + // The Flow service account should have a balance + Test.assert(balance > 0.0, message: "Service account should have FLOW tokens") +} + +access(all) fun testHasMinimumBalance() { + let scriptResult = Test.executeScript( + Test.readFile("../scripts/HasMinimumBalance.cdc"), + [Address(0x1654653399040a61), 1.0] + ) + + Test.expect(scriptResult, Test.beSucceeded()) + + let hasMinimum = scriptResult.returnValue! as! Bool + Test.assert(hasMinimum == true, message: "Service account should have at least 1 FLOW") +} +``` + +### What's happening here + +1. **The `#test_fork` pragma configures the test**: At the top of the file, the pragma tells the test framework to run against mainnet. +2. **Your contract uses FlowToken**: `TokenChecker` imports and interacts with the real FlowToken contract. +3. **No bootstrapping needed**: With the fork pragma, real mainnet accounts (like `0x1654653399040a61`, the Flow service account) already have balances. +4. **Test against real state**: You can query actual accounts and verify your contract logic works with production data. +5. **Local deployment**: Your `TokenChecker` contract is deployed locally to the test environment, but it reads from forked mainnet state. + +## Execute transactions with account impersonation + +Fork testing includes built-in account impersonation—you can execute transactions as **any mainnet account** without the need for private keys. This lets you test interactions with real accounts and their current state. + +### Create transactions + +Generate the transactions: + +```zsh +flow generate transaction SetupFlowTokenVault +flow generate transaction TransferTokens +``` + +Open `cadence/transactions/SetupFlowTokenVault.cdc` and replace its contents with: + +```cadence cadence/transactions/SetupFlowTokenVault.cdc +import "FungibleToken" +import "FlowToken" + +transaction { + prepare(signer: auth(Storage, Capabilities) &Account) { + if signer.storage.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault) == nil { + signer.storage.save(<-FlowToken.createEmptyVault(vaultType: Type<@FlowToken.Vault>()), to: /storage/flowTokenVault) + let cap = signer.capabilities.storage.issue<&FlowToken.Vault>(/storage/flowTokenVault) + signer.capabilities.publish(cap, at: /public/flowTokenReceiver) + signer.capabilities.publish(cap, at: /public/flowTokenBalance) + } + } +} +``` + +Open `cadence/transactions/TransferTokens.cdc` and replace its contents with: + +```cadence cadence/transactions/TransferTokens.cdc +import "FungibleToken" +import "FlowToken" + +transaction(amount: UFix64, to: Address) { + let sentVault: @{FungibleToken.Vault} + + prepare(signer: auth(Storage) &Account) { + let vaultRef = signer.storage.borrow( + from: /storage/flowTokenVault + ) ?? panic("Could not borrow reference to the owner's Vault") + + self.sentVault <- vaultRef.withdraw(amount: amount) + } + + execute { + let recipient = getAccount(to) + let receiverRef = recipient.capabilities + .borrow<&{FungibleToken.Receiver}>(/public/flowTokenReceiver) + ?? panic("Could not borrow receiver reference") + + receiverRef.deposit(from: <-self.sentVault) + } +} +``` + +### Test transaction execution with impersonation + +Add this test function to the current `cadence/tests/TokenChecker_test.cdc` file (the pragma is already at the top of the file): + +```cadence +access(all) fun testTransactionAsMainnetAccount() { + // Impersonate the Flow service account (or any mainnet account) + // No private keys needed - fork testing has built-in impersonation + let serviceAccount = Test.getAccount(0x1654653399040a61) + + // Check initial balance + let initialBalanceScript = Test.executeScript( + Test.readFile("../scripts/CheckBalance.cdc"), + [serviceAccount.address] + ) + Test.expect(initialBalanceScript, Test.beSucceeded()) + let initialBalance = initialBalanceScript.returnValue! as! UFix64 + + // Create a test recipient account and set up FlowToken vault + let recipient = Test.createAccount() + + // Set up the recipient's FlowToken vault + let setupResult = Test.executeTransaction( + Test.Transaction( + code: Test.readFile("../transactions/SetupFlowTokenVault.cdc"), + authorizers: [recipient.address], + signers: [recipient], + arguments: [] + ) + ) + Test.expect(setupResult, Test.beSucceeded()) + + // Execute transaction AS the mainnet service account + // This works because fork testing allows impersonating any account + let txResult = Test.executeTransaction( + Test.Transaction( + code: Test.readFile("../transactions/TransferTokens.cdc"), + authorizers: [serviceAccount.address], + signers: [serviceAccount], + arguments: [10.0, recipient.address] + ) + ) + + Test.expect(txResult, Test.beSucceeded()) + + // Verify the sender's balance decreased + let newBalanceScript = Test.executeScript( + Test.readFile("../scripts/CheckBalance.cdc"), + [serviceAccount.address] + ) + Test.expect(newBalanceScript, Test.beSucceeded()) + let newBalance = newBalanceScript.returnValue! as! UFix64 + + // Balance should have decreased by exactly the transfer amount + Test.assertEqual(initialBalance - 10.0, newBalance) + + // Verify the recipient received the tokens + let recipientBalanceScript = Test.executeScript( + Test.readFile("../scripts/CheckBalance.cdc"), + [recipient.address] + ) + Test.expect(recipientBalanceScript, Test.beSucceeded()) + let recipientBalance = recipientBalanceScript.returnValue! as! UFix64 + // Recipient should have at least 10.0 (may be slightly more due to storage refunds) + Test.assert(recipientBalance >= 10.0, message: "Recipient should have at least 10 FLOW") +} +``` + +### Key points about account impersonation + +1. **Any account can be used**: Call `Test.getAccount(address)` with any mainnet address. +2. **No private keys needed**: Fork testing has built-in impersonation—you can sign transactions as any account. +3. **Real account state**: The account has its actual mainnet balance, storage, and capabilities. +4. **Mutations are local**: Changes only affect your test environment, not the real network. +5. **Test complex scenarios**: Impersonate whale accounts, protocol accounts, or any user to test edge cases. + +## Run all tests together + +Now that you have multiple test files with the `#test_fork` pragma, simply run: + +```zsh +flow test +``` + +That's it! The pragma handles all the fork configuration. This runs all `*_test.cdc` files in your project—both local tests and fork tests together. You will see: + +``` +Test results: "cadence/tests/FlowToken_test.cdc" +- PASS: testFlowTokenSupplyIsPositive + +Test results: "cadence/tests/TokenChecker_test.cdc" +- PASS: testCheckBalanceOnRealAccount +- PASS: testHasMinimumBalance +- PASS: testTransactionAsMainnetAccount +``` + +### Best Practices: In-File Configuration vs CLI Flags + +**Recommended:** Configure fork tests in your test file with `#test_fork` + +```cadence +#test_fork(network: "mainnet-fork", height: nil) +import Test +// Your tests... +``` + +Then run with: + +```bash +flow test +``` + +**Not recommended:** CLI flags (legacy approach) + +```bash +flow test --fork mainnet # Requires typing flags every time +``` + +Configuring fork tests in the file keeps the configuration with your test code, making tests self-documenting and easier to maintain. + +You can also run specific test files or change the network/block height in the pragma as needed. See the [Fork Testing Flags] reference for more options. + +## Mocking Mainnet Contracts in Tests + +Just like mocking dependencies in unit tests, you can **mock real mainnet contracts** by deploying modified versions—perfect for testing upgrades, bug fixes, or alternative implementations against real production state. + +Use `Test.deployContract()` to deploy your mock to any mainnet account address. Your mock takes precedence while other contracts continue using real mainnet versions. + +### Example + +```cadence +#test_fork(network: "mainnet-fork", height: nil) + +import Test + +access(all) fun setup() { + // Deploy mock FlowToken to the real mainnet address + let err = Test.deployContract( + name: "FlowToken", + path: "../contracts/FlowTokenModified.cdc", + arguments: [] + ) + Test.expect(err, Test.beNil()) +} + +access(all) fun testMockedFlowToken() { + // Test now uses mocked FlowToken + // All other contracts (FungibleToken, USDC, etc.) use real mainnet versions + + let scriptResult = Test.executeScript( + Test.readFile("../scripts/CheckBalance.cdc"), + [Address(0x1654653399040a61)] + ) + Test.expect(scriptResult, Test.beSucceeded()) +} +``` + +This validates your contract changes against real production state and integrations. + +## Pinning block heights for reproducibility + +For reproducible test results, pin your tests to a specific block height: + +```cadence +#test_fork(network: "mainnet-fork", height: 85229104) +``` + +This ensures your tests run against the same blockchain state every time, useful for: + +- Deterministic test results in CI/CD +- Reproducing historical bugs at a specific point in time +- Testing against known network state + +To use the latest state instead, use `height: nil`: + +```cadence +#test_fork(network: "mainnet-fork", height: nil) +``` + +Note that block heights are only available within the current spork (network upgrade period). See [Testing Smart Contracts] for more on managing pinned heights over time. + +## When to use fork testing + +Fork testing is most valuable for: + +- Integration testing with real onchain contracts and data. +- Pre-deployment validation before mainnet releases. +- Upgrade testing against production state. +- Reproducing issues at a specific block height. +- Testing interactions with high-value or protocol accounts. +- Validating contract behavior with real-world data patterns. + +For strategy, limitations, and best practices, see the guide: [Testing Smart Contracts]. + +## Conclusion + +In this tutorial, you learned how to use fork testing to validate your Cadence contracts against live Flow network state. You created tests that read from real mainnet contracts, deployed custom contracts that interact with production data, and executed transactions using account impersonation—all without the need deploy to a live network or bootstrap test accounts. + +Now that you have completed this tutorial, you can: + +- **Run Cadence tests against forked networks** with `#test_fork`. +- **Test contracts that depend on real mainnet contracts** without manual setup. +- **Use account impersonation** to execute transactions as any mainnet account. +- **Read from production blockchain state** in your test suite. +- **Pin tests to specific block heights** for historical debugging. +- **Integrate fork testing** into your development workflow. + +Fork testing bridges the gap between local unit tests and testnet deployments, which allows you to catch integration issues early and test against real-world conditions. Use it as part of your pre-deployment validation process, alongside emulator unit tests for determinism and isolation, and testnet deployments for final verification. + +### Next Steps + +- Explore additional assertions and helpers in the [Cadence Testing Framework]. +- Add more real-world tests that read from standard contracts like Flow NFT. +- Keep unit tests on the emulator for determinism and isolation; run forked integration tests selectively in CI. +- Review the [Fork Testing Flags] reference for advanced options. +- Learn about [Flow Networks] and public access nodes. + + + +[Flow CLI]: ../../../build/tools/flow-cli/index.md +[homebrew]: https://brew.sh +[installation guide]: ../../../build/tools/flow-cli/install.md +[Testing Smart Contracts]: ../../../build/cadence/smart-contracts/testing-strategy.md +[Dependency Manager]: ../../../build/tools/flow-cli/dependency-manager.md +[Fork Testing Flags]: ../../../build/tools/flow-cli/tests.md#fork-testing-flags +[Cadence Testing Framework]: https://cadence-lang.org/docs/testing-framework +[Flow Networks]: ../../../protocol/flow-networks/index.md +[Testing Strategy on Flow]: ../../../build/cadence/smart-contracts/testing-strategy.md +[Flow Emulator]: ../../../build/tools/emulator/index.md diff --git a/docs/build/getting-started/fcl-quickstart.md b/docs/blockchain-development-tutorials/cadence/getting-started/building-a-frontend-app.md similarity index 61% rename from docs/build/getting-started/fcl-quickstart.md rename to docs/blockchain-development-tutorials/cadence/getting-started/building-a-frontend-app.md index 842b97f815..18443d4613 100644 --- a/docs/build/getting-started/fcl-quickstart.md +++ b/docs/blockchain-development-tutorials/cadence/getting-started/building-a-frontend-app.md @@ -1,7 +1,7 @@ --- sidebar_position: 3 -sidebar_label: Simple Frontend -title: Building a Simple Frontend with "@onflow/react-sdk" +sidebar_label: Building a Frontend App +title: Building a Frontend App description: Learn how to build a Next.js frontend application using @onflow/react-sdk to interact with Flow smart contracts. Set up wallet authentication, read contract data, send transactions with kit's React hooks, and display transaction status updates. keywords: - '@onflow/react-sdk' @@ -20,31 +20,37 @@ keywords: - web3 frontend --- -# Simple Frontend with `@onflow/react-sdk` +# Building a Frontend App -Building on the `Counter` contract you deployed in [Step 1: Contract Interaction] and [Step 2: Local Development], this tutorial shows you how to create a simple Next.js frontend that interacts with the `Counter` smart contract deployed on your local Flow emulator. Instead of using FCL directly, you'll leverage [**@onflow/react-sdk**] to simplify authentication, querying, transactions, and to display real-time transaction status updates using convenient React hooks. +This tutorial builds on the `Counter` contract you deployed in [Cadence Environment Setup] and [Smart Contract Interaction]. It shows you how to create a simple `Next.js` frontend that interacts with the `Counter` smart contract deployed on your local Flow emulator. Rather than use FCL directly, you'll leverage [**@onflow/react-sdk**] to simplify authentication, querys, transactions, and to display real-time transaction status updates with convenient React hooks. ## Objectives -After finishing this guide, you will be able to: +After you complete this tutorial, you will be able to: -- Wrap your Next.js app with a Flow provider using [**@onflow/react-sdk**]. -- Read data from a Cadence smart contract (`Counter`) using kit's query hook. -- Send a transaction to update the smart contract's state using kit's mutation hook. -- Monitor a transaction's status in real time using kit's transaction hook. -- Authenticate with the Flow blockchain using kit's built-in hooks and the local [Dev Wallet]. +- Wrap your `Next.js` app with a Flow provider using [**@onflow/react-sdk**]. +- Read data from a Cadence smart contract (`Counter`) with kit's query hook. +- Send a transaction to update the smart contract's state with kit's mutation hook. +- Monitor a transaction's status in real time with kit's transaction hook. +- Authenticate with the Flow blockchain with kit's built-in hooks and the local [Dev Wallet]. ## Prerequisites -- Completion of [Step 1: Contract Interaction] and [Step 2: Local Development]. +- Completion of [Cadence Environment Setup] and [Smart Contract Interaction]. - [Flow CLI] installed. - Node.js and npm installed. -## Setting Up the Next.js App +## Set Up the Next.js app Follow these steps to set up your Next.js project and integrate [**@onflow/react-sdk**]. -### Step 1: Create a New Next.js App +:::tip + +You can visit this [React-sdk Demo] to see how the hooks and components are used. + +::: + +### Step 1: Create a new Next.js app Run the following command in your project directory: @@ -58,15 +64,15 @@ During setup, choose the following options: - **Use src directory**: **Yes** - **Use App Router**: **Yes** -This command creates a new Next.js project named `kit-app-quickstart` inside your current directory. We're generating the frontend in a subdirectory so we can next move it into our existing project structure from the previous steps (you can't create an app in a non-empty directory). +This command creates a new Next.js project named `kit-app-quickstart` inside your current directory. We will generate the frontend in a subdirectory so we can next move it into our current project structure from the previous steps (you can't create an app in a non-empty directory). -### Step 2: Move the Next.js App Up a Directory +### Step 2: Move the Next.js app up a directory Move the contents of the `kit-app-quickstart` directory into your project root. You can use the gui in your editor, or the console. :::warning -You'll want to consolidate both `.gitignore` files, keeping the contents of both in the file that ends up in the root. +You'll want to consolidate both `.gitignore` files, which keeps the contents of both in the file that ends up in the root. ::: @@ -86,7 +92,11 @@ Move-Item -Path .\kit-app-quickstart\.* -Destination . -Force Remove-Item -Recurse -Force .\kit-app-quickstart ``` -**Note:** When moving hidden files (those beginning with a dot) like `.gitignore`, be cautious not to overwrite any important files. +:::tip + +When you move hidden files (those that start with a dot) like `.gitignore`, be cautious not to overwrite any important files. + +::: ### Step 3: Install @onflow/react-sdk @@ -96,17 +106,17 @@ Install the kit library in your project: npm install @onflow/react-sdk ``` -This library wraps FCL internally and exposes a set of hooks for authentication, querying, sending transactions, and tracking transaction status. +This library wraps FCL internally and exposes a set of hooks for authentication, querys, to send transactions, and track transaction status. -## Configuring the Local Flow Emulator and Dev Wallet +## Configure the local Flow emulator and Dev Wallet :::warning -You should already have the Flow emulator running from the local development step. If it's not running, you can start it again — but note that restarting the emulator will clear all blockchain state, including any contracts deployed in [Step 2: Local Development]. +You should already have the Flow emulator running from the local development step. If it's not running, you can start it again — but when you restart the emulator, it will clear all blockchain state, which includes any contracts deployed in [Step 2: Local Development]. ::: -### Start the Flow Emulator (if not already running) +### Start the Flow emulator (if not already running) Open a new terminal window in your project directory and run: @@ -126,25 +136,25 @@ flow dev-wallet This will start the [Dev Wallet] on `http://localhost:8701`, which you'll use for authentication during development. -## Wrapping Your App with FlowProvider +## Wrap Your app with FlowProvider -[**@onflow/react-sdk**] provides a `FlowProvider` component that sets up the Flow Client Library configuration. In Next.js using the App Router, add or update your `src/app/layout.tsx` as follows: +[**@onflow/react-sdk**] provides a `FlowProvider` component that sets up the Flow Client Library configuration. In `Next.js`, use the App Router to add or update your `src/app/layout.tsx` as follows: ```tsx -"use client"; +'use client'; -import { FlowProvider } from "@onflow/react-sdk"; -import flowJson from "../flow.json"; +import { FlowProvider } from '@onflow/react-sdk'; +import flowJson from '../flow.json'; export default function RootLayout({ children, }: { - children: React.ReactNode + children: React.ReactNode; }) { return ( - - ) -} + ); +} ``` This configuration initializes the kit with your local emulator settings and maps contract addresses based on your `flow.json` file. For more information on Discovery configurations, refer to the [Wallet Discovery Guide]. -## Interacting With the Chain +## Interact With the chain -Now that we've set our provider, lets start interacting with the chain. +Now that we've set our provider, lets start to interact with the chain. -### Querying the Chain +### Query the chain First, use the kit's [`useFlowQuery`] hook to read the current counter value from the blockchain. @@ -197,12 +207,12 @@ This script fetches the counter value, formats it via the `NumberFormatter`, and :::info -- **Import Syntax:** The imports (`import "Counter"` and `import "NumberFormatter"`) don't include addresses because those are automatically resolved using the `flow.json` file configured in your `FlowProvider`. This keeps your Cadence scripts portable and environment-independent. +- **Import Syntax:** The imports (`import "Counter"` and `import "NumberFormatter"`) don't include addresses because those are automatically resolved with the `flow.json` file configured in your `FlowProvider`. This keeps your Cadence scripts portable and environment-independent. - **`enabled` Flag:** This controls whether the query should run automatically. Set it to `true` to run on mount, or pass a condition (e.g. `!!user?.addr`) to delay execution until the user is available. This is useful for queries that depend on authentication or other asynchronous data. ::: -### Sending a Transaction +### Send a transaction Next, use the kit's [`useFlowMutate`] hook to send a transaction that increments the counter. @@ -238,21 +248,19 @@ const handleIncrement = () => { #### Explanation -This sends a Cadence transaction to the blockchain using the `mutate` function. The transaction imports the `Counter` contract and calls its `increment` function. Authorization is handled automatically by the connected wallet during the `prepare` phase. Once submitted, the returned `txId` can be used to track the transaction's status in real time. +This sends a Cadence transaction to the blockchain with the `mutate` function. The transaction imports the `Counter` contract and calls its `increment` function. The connected wallet handles authorization automatically during the `prepare` phase. After it's submitted, you cna use the returned `txId` to track the transaction's status in real time. -### Subscribing to Transaction Status +### Subscribe to transaction status Use the kit's [`useFlowTransactionStatus`] hook to monitor and display the transaction status in real time. - ```tsx import { useFlowTransactionStatus } from '@onflow/react-sdk'; const { transactionStatus, error: txStatusError } = useFlowTransactionStatus({ - id: txId || "", + id: txId || '', }); - useEffect(() => { if (txId && transactionStatus?.status === 3) { refetch(); @@ -264,39 +272,39 @@ useEffect(() => { #### Explanation: -- `useFlowTransactionStatus(txId)` subscribes to real-time updates about a transaction's lifecycle using the transaction ID. +- `useFlowTransactionStatus(txId)` subscribes to real-time updates about a transaction's lifecycle with the transaction ID. - `transactionStatus.status` is a numeric code representing the state of the transaction: - `0`: **Unknown** – The transaction status is not yet known. - `1`: **Pending** – The transaction has been submitted and is waiting to be included in a block. - `2`: **Finalized** – The transaction has been included in a block, but not yet executed. - `3`: **Executed** – The transaction code has run successfully, but the result has not yet been sealed. - - `4`: **Sealed** – The transaction is fully complete, included in a block, and now immutable on-chain. -- We recommend calling `refetch()` when the status reaches **3 (Executed)** to update your UI more quickly after the transaction runs, rather than waiting for sealing. + - `4`: **Sealed** – The transaction is fully complete, included in a block, and now immutable onchain. +- We recommend that you call `refetch()` when the status reaches **3 (Executed)** to update your UI more quickly after the transaction runs, rather than waiting for sealing. - The `statusString` property gives a human-readable version of the current status you can display in the UI. -#### Why `Executed` is Recommended for UI Updates: +#### Why we recommend `Executed` for UI Updates: -Waiting for `Sealed` provides full on-chain confirmation but can introduce a delay — especially in local or test environments. Since most transactions (like incrementing a counter) don't require strong finality guarantees, you can typically refetch data once the transaction reaches `Executed` for a faster, more responsive user experience. +Waiting for `Sealed` provides full onchain confirmation but can introduce a delay — especially in local or test environments. Since most transactions (like incrementing a counter) don't require strong finality guarantees, you can typically refetch data after the transaction reaches `Executed` for a faster, more responsive user experience. However: -- If you're dealing with critical state changes (e.g., token transfers or contract deployments), prefer waiting for `Sealed`. +- If you experience critical state changes (for example, token transfers or contract deployments), wait for `Sealed`. - For non-critical UI updates, `Executed` is usually safe and significantly improves perceived performance. -### Integrating Authentication and Building the Complete UI +### Integrate authentication and build the complete UI -Finally, integrate the query, mutation, and transaction status hooks with authentication using `useFlowCurrentUser`. Combine all parts to build the complete page. +Finally, integrate the query, mutation, and transaction status hooks with authentication via `useFlowCurrentUser`. Combine all parts to build the complete page. ```tsx -"use client"; +'use client'; -import { useState, useEffect } from "react"; +import { useState, useEffect } from 'react'; import { useFlowQuery, useFlowMutate, useFlowTransactionStatus, useFlowCurrentUser, -} from "@onflow/react-sdk"; +} from '@onflow/react-sdk'; export default function Home() { const { user, authenticate, unauthenticate } = useFlowCurrentUser(); @@ -323,12 +331,10 @@ export default function Home() { error: txError, } = useFlowMutate(); - const { transactionStatus, error: txStatusError } = useFlowTransactionStatus({ - id: txId || "", + id: txId || '', }); - useEffect(() => { if (txId && transactionStatus?.status === 3) { // Transaction is executed @@ -365,7 +371,7 @@ export default function Home() {

Error: {error.message}

) : (
-

{(data as string) || "0"}

+

{(data as string) || '0'}

Current Count

)} @@ -373,31 +379,25 @@ export default function Home() { {user?.loggedIn ? (

Connected: {user.addr}

- + - - + + {transactionStatus?.statusString && transactionStatus?.status && ( -

Status: {transactionStatus.status >= 3 ? "Successful" : "Pending"}

- )} - - {txError && ( -

Error: {txError.message}

- )} - - {txStatusError && ( -

Status Error: {txStatusError.message}

+

+ Status: {transactionStatus.status >= 3 ? 'Successful' : 'Pending'} +

)} + + {txError &&

Error: {txError.message}

} + + {txStatusError &&

Status Error: {txStatusError.message}

}
) : ( - + )} ); @@ -408,16 +408,16 @@ In this complete page: - **Step 1** queries the counter value. - **Step 2** sends a transaction to increment the counter and stores the transaction ID. -- **Step 3** subscribes to transaction status updates using the stored transaction ID and uses a `useEffect` hook to automatically refetch the updated count when the transaction is sealed (status code 4). +- **Step 3** subscribes to transaction status updates with the stored transaction ID and uses a `useEffect` hook to automatically refetch the updated count when the transaction is sealed (status code 4). - **Step 4** integrates authentication via `useFlowCurrentUser` and combines all the pieces into a single user interface. :::tip -In this tutorial, we inlined Cadence code for simplicity. For real projects, we recommend storing Cadence in separate `.cdc` files, using the [Cadence VSCode extension], and importing them with the [`flow-cadence-plugin`](https://github.com/chasefleming/flow-cadence-plugin) for Next.js or Webpack projects. +In this tutorial, we inlined Cadence code for simplicity. For real projects, we recommend that you store Cadence in separate `.cdc` files, with the [Cadence VSCode extension], and import them with the [`flow-cadence-plugin`](https://github.com/chasefleming/flow-cadence-plugin) for Next.js or Webpack projects. ::: -## Running the App +## Run the app Start your development server: @@ -429,7 +429,7 @@ npm run dev If you have the Flow wallet browser extension installed, you might automatically log into the app. Normally this is desirable for your users, but you don't want to use it here. -Log out, and log back in selecting the Dev Wallet instead of the Flow Wallet. +Log out, and log back in. Select the Dev Wallet instead of the Flow Wallet. ::: @@ -444,26 +444,26 @@ Then visit [http://localhost:3000](http://localhost:3000) in your browser. You s - The current counter value displayed (formatted with commas using `NumberFormatter`). - A **Log In** button that launches the kit Discovery UI with your local [Dev Wallet]. - Once logged in, your account address appears with options to **Log Out** and **Increment Count**. -- When you click **Increment Count**, the transaction is sent; its status updates are displayed in real time below the action buttons, and once the transaction is sealed, the updated count is automatically fetched. +- When you click **Increment Count**, the transaction is sent; its status updates are displayed in real time below the action buttons, and after the transaction is sealed, the updated count is automatically fetched. -## Wrapping Up +## Conclusion -By following these steps, you've built a simple Next.js dApp that interacts with a Flow smart contract using [**@onflow/react-sdk**]. In this guide you learned how to: +When you follow these steps, you've built a simple `Next.js` dApp that interacts with a Flow smart contract with [**@onflow/react-sdk**]. In this guide you learned how to: - Wrap your application in a `FlowProvider` to configure blockchain connectivity. -- Use kit hooks such as `useFlowQuery`, `useFlowMutate`, `useFlowTransactionStatus`, and `useFlowCurrentUser` to manage authentication, query on-chain data, submit transactions, and monitor their status. +- Use kit hooks such as `useFlowQuery`, `useFlowMutate`, `useFlowTransactionStatus`, and `useFlowCurrentUser` to manage authentication, query onchain data, submit transactions, and monitor their status. - Integrate with the local Flow emulator and Dev Wallet for a fully functional development setup. For additional details and advanced usage, refer to the [@onflow/react-sdk documentation] and other Flow developer resources. - -[Step 1: Contract Interaction]: contract-interaction.md -[Step 2: Local Development]: ./flow-cli.md -[Wallet Discovery Guide]: ../../tools/clients/fcl-js/discovery.md -[`useFlowQuery`]: ../../tools/react-sdk#useflowquery -[`useFlowMutate`]: ../../tools/react-sdk#useflowmutate -[Dev Wallet]: ../../tools/flow-dev-wallet -[@onflow/react-sdk documentation]: ../../tools/react-sdk/index.mdx -[**@onflow/react-sdk**]: ../../tools/react-sdk/index.mdx -[Flow CLI]: ../../tools/flow-cli/install.md -[Cadence VSCode extension]: ../../tools/vscode-extension +[React-sdk Demo]: https://react-sdk-demo-git-master-onflow.vercel.app/ +[Cadence Environment Setup]: ./cadence-environment-setup.md +[Smart Contract Interaction]: ./smart-contract-interaction.md +[Wallet Discovery Guide]: ../../../build/tools/clients/fcl-js/discovery.md +[`useFlowQuery`]: ../../../build/tools/react-sdk#useflowquery +[`useFlowMutate`]: ../../../build/tools/react-sdk#useflowmutate +[Dev Wallet]: ../../../build/tools/flow-dev-wallet +[@onflow/react-sdk documentation]: ../../../build/tools/react-sdk +[**@onflow/react-sdk**]: ../../../build/tools/react-sdk +[Flow CLI]: ../../../build/tools/flow-cli/install.md +[Cadence VSCode extension]: ../../../build/tools/vscode-extension diff --git a/docs/blockchain-development-tutorials/cadence/getting-started/cadence-environment-setup.md b/docs/blockchain-development-tutorials/cadence/getting-started/cadence-environment-setup.md new file mode 100644 index 0000000000..63cfac4f58 --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/getting-started/cadence-environment-setup.md @@ -0,0 +1,437 @@ +--- +sidebar_position: 1 +sidebar_label: Cadence Environment Setup +title: Cadence Environment Setup +description: Learn how to set up your complete Flow development environment, deploy your first smart contract, and master the fundamentals of blockchain development with Cadence on the Flow emulator. +keywords: + - Flow development + - Flow CLI + - smart contracts + - local development + - Flow emulator + - contract deployment + - Cadence programming + - blockchain development + - Counter contract + - testing + - VSCode extension +--- + +# Cadence Environment Setup + +This comprehensive tutorial will guide you through how to set up your complete development environment, deploy your first smart contract, and learn the fundamentals of Flow development. You'll work hands-on with the Flow CLI, local emulator, and a real smart contract to build practical skills from day one. + +Flow is a blockchain built for the next generation of apps, games, and digital assets. With its unique multi-role architecture and resource-oriented programming language Cadence, Flow allows developers to create secure, composable, and scalable applications. This tutorial focuses on getting you productive with Flow's developer tools as quickly as possible. + +## What you'll learn + +After you complete this tutorial, you'll be able to: + +- **Set up a complete Flow development environment** with CLI tools and VSCode integration. +- **Create and manage Flow projects** with the Flow CLI and understand project structure. +- **Deploy and interact with smart contracts** on the local Flow emulator. +- **Execute scripts and transactions** to read from and modify blockchain state. +- **Understand Flow's account model** and how contracts are deployed to account storage. +- **Navigate the Flow ecosystem** and know where to find help and resources. + +## What you'll build + +You'll work with a `Counter` contract, a simple but comprehensive example that demonstrates core Flow development patterns. This contract maintains a count value and provides functions to increment, decrement, and read the current count. By the end of this tutorial, you'll have: + +- A fully functional local Flow development environment. +- A deployed Counter contract that runs on your local emulator. +- Scripts to query the contract's state. +- Transactions to modify the contract's state. +- Knowledge of how to extend this foundation for more complex applications. + +**Time Commitment:** Approximately 30-45 minutes + +**Prerequisites:** + +- Basic command line familiarity +- Code editor (VSCode recommended) +- `Node.js` installed (for future frontend development) + +--- + +### Install Flow CLI + +The [Flow Command Line Interface] (CLI) is a set of tools that developers can use to interact with the Flow blockchain. Developers can manage accounts, send transactions, deploy smart contracts, run the emulator, and more. This quickstart will get you familiar with its main concepts and functionality. + +The first thing you'll need to do is install the Flow CLI. If you have [homebrew] installed, run: + +```zsh +brew install flow-cli +``` + +**For other operating systems,** refer to the [installation guide] for detailed instructions. + +**Verify Installation:** + +```zsh +flow version +``` + +You will see output showing your Flow CLI version. + +### Install VSCode extension + +Install the [Flow Cadence VSCode Extension] from the marketplace. This extension provides: + +- Syntax highlighting for Cadence. +- Code completion and IntelliSense. +- Error checking and diagnostics. +- Integrated development tools. + +## Create your first project + +Navigate to your desired development directory and create a new Flow project: + +```zsh +flow init +``` + +When prompted: + +1. **Project name:** Enter your preferred project name. +2. Select `Basic Cadence project (no dependencies)`. + +The `flow init` command creates: + +- **`flow.json`**: Central configuration file that contains accounts, contracts, deployments, and network settings. +- **`emulator-account.pkey`**: Private key for the default emulator account. +- **`cadence/`**: Directory structure for your Cadence code: + - `contracts/`: Smart contract files + - `scripts/`: Read-only blockchain queries + - `transactions/`: State-changing operations + - `tests/`: Contract test files + +Navigate into your project directory: + +```zsh +cd your-flow-project-name +``` + +:::info + +For additional details on how `flow.json` is configured, review the [configuration docs]. + +::: + +### Start the Flow emulator + +The emulator is a local version of the Flow blockchain that you can use to test your contracts and scripts. It's a great way to develop and test your contracts locally - before you try them on the `testnet` or `mainnet`. + +Before we deploy, let's open a new terminal window and run the emulator. From the root of your project directory, where your `emulator-account.pkey` and `flow.json` files are located, run: + +```zsh +flow emulator start +``` + +Keep this terminal running. The emulator provides: + +- Local blockchain environment. +- Fast transaction processing. +- No real-world costs. +- Complete Flow feature set. + +## Your first contract + +Now let's examine, deploy, and interact with the Counter contract that was created in your project. + +### Examine the Counter contract + +Open `cadence/contracts/Counter.cdc` in your editor. Let's break down this contract: + +```cadence +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 + } + + // Public function to increment the counter + access(all) fun increment() { + self.count = self.count + 1 + emit CounterIncremented(newCount: self.count) + } + + // Public function to decrement the counter + access(all) fun decrement() { + self.count = self.count - 1 + emit CounterDecremented(newCount: self.count) + } + + // Public function to get the current count + view access(all) fun getCount(): Int { + return self.count + } +} +``` + +**Key components:** + +- **Contract Declaration**: `access(all) contract Counter` creates a public contract named Counter. +- **State Variable**: `access(all) var count: Int` stores the counter value, accessible to everyone. +- **Events**: `CounterIncremented` and `CounterDecremented` notify listeners when changes occur. +- **Initializer**: `init()` sets the initial count to 0 when the contract is deployed. +- **Public Functions**: + - `increment()`: Increases count by 1 and emits an event + - `decrement()`: Decreases count by 1 and emits an event + - `getCount()`: Returns the current count (read-only, marked with `view`) + +### Create and configure deployment account + +When you create 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 automatically created `emulator-account`, but for this example, lets also create a new account on the emulator to deploy it to. + +:::info + +**Reminder**: On Flow Cadence, contracts are deployed to the storage of the account that deploys them. + +::: + +Leave your emulator running, and open a second terminal. Run the following command: + +```zsh +flow accounts create +``` + +When prompted: + +1. **Account name:** Enter `test-account` +2. **Network:** Select `Emulator` + +This adds the new account to your `flow.json` configuration file. + +After you've created you accounts, then you can view all your accounts on the with the Flow CLI with: + +```zsh +📋 Account Status Across Networks + +This shows which networks your configured accounts are accessible on: +🌐 Network 🟢 Local (running) 🔴 Local (stopped) ✓ Found ✗ Error +───────────────────────────────────────────────────── + +🟢 emulator + ✓ default (f3fcd2c1a78f5eee): 0.00100000 FLOW + ✓ emulator-account (f8d6e0586b0a20c7): 999999999.99300000 FLOW + ✓ test-account (e03daebed8ca0615): 0.00100000 FLOW + +🌐 mainnet + No accounts found + +🌐 testnet + No accounts found + +🟢 testing + ✓ default (f3fcd2c1a78f5eee): 0.00100000 FLOW + ✓ emulator-account (f8d6e0586b0a20c7): 999999999.99300000 FLOW + ✓ test-account (e03daebed8ca0615): 0.00100000 FLOW + + +💡 Tip: To fund testnet accounts, run: flow accounts fund +``` + +This is a great tool to visualize your different accounts and balances while you develop.. + +### Configure contract deployment + +To deploy the `Counter` contract to the emulator, you'll need to add it to your project configuration. To do this, run: + +```zsh +flow config add deployment +``` + +Follow the prompts: + +1. **Network:** Select `emulator` +2. **Account:** Select `test-account` +3. **Contract:** Select `Counter` +4. **Deploy more contracts:** Select `no` + +This configures your `flow.json` to deploy the Counter contract to your test account on the emulator. + +### Deploy the contract + +To deploy the `Counter` contract to the emulator, run: + +```zsh +flow project deploy +``` + +You'll see output similar to: + +```zsh +Deploying 1 contracts for accounts: test-account + +Counter -> 0x179b6b1cb6755e31 (a98c155fe7afc8eb2af5551748759b08a80a0ae85d1b09f92f1afc293c61ca98) + +🎉 All contracts deployed successfully +``` + +That's it! You've just deployed your first contract to the Flow Emulator. + +### Verify deployment with a script + +Scripts are used to read data from the Flow blockchain. There is no state modification. Let's verify the deployment by reading the counter value. Run the included script: + +```zsh +flow scripts execute cadence/scripts/GetCounter.cdc +``` + +You should see: + +```zsh +Result: 0 +``` + +This confirms your contract is deployed and functional. The counter starts at zero (0), as defined in the contract's `init()` function. + +If we wanted to generate a new script, we could run: + +```zsh +flow generate script ScriptName +``` + +:::info + +For more information about generating Cadence files, see the [Generating Cadence Boilerplate] documentation. + +**You'll usually want to use these commands instead of adding files manually!** + +::: + +:::tip + +To learn more about writing scripts, check out the docs for [basic scripts]. + +::: + +### Execute transactions + +Now let's increment the counter with a transaction: + +```zsh +flow transactions send cadence/transactions/IncrementCounter.cdc +``` + +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. The command would look like this: + +```zsh +flow transactions send cadence/transactions/IncrementCounter.cdc --signer test-account +``` + +The transaction output shows detailed information including: + +- Transaction ID and block information. +- Status confirmation (`✅ SEALED`). +- Events emitted (including `CounterIncremented`). + +```zsh +Transaction ID: 9cc7ac4d3d5239016965aba89b9692d3401a48a090d1ad1a8d9ef9cfca685e6e + +Block ID b8537860b0fc9ca8b3195b121e762502f9a220874b605d6a810998e8b62321a3 +Block Height 3 +Status ✅ SEALED +ID 9cc7ac4d3d5239016965aba89b9692d3401a48a090d1ad1a8d9ef9cfca685e6e +Payer f8d6e0586b0a20c7 +Authorizers [f8d6e0586b0a20c7] + +Proposal Key: + Address f8d6e0586b0a20c7 + Index 0 + Sequence 1 + +No Payload Signatures + +Envelope Signature 0: f8d6e0586b0a20c7 +Signatures (minimized, use --include signatures) + +Events: + Index 0 + Type A.179b6b1cb6755e31.Counter.CounterIncremented + Tx ID 9cc7ac4d3d5239016965aba89b9692d3401a48a090d1ad1a8d9ef9cfca685e6e + Values + - newCount (Int): 1 + + + +Code (hidden, use --include code) + +Payload (hidden, use --include payload) + +Fee Events (hidden, use --include fee-events) +``` + +Run the script to check the counter again. You'll see that it has incremented: + +```zsh +flow scripts execute cadence/scripts/GetCounter.cdc +``` + +```zsh +Result: 1 +``` + +:::tip + +To learn more about writing transactions, read the docs for [basic transactions]. + +::: + +## Conclusion + +You've successfully established a solid foundation for building on Flow. Let's recap what you've accomplished and learned. Through this hands-on tutorial, you've successfully built a complete Flow development foundation: + +✅ **Complete Flow development environment** + +- Flow CLI installed and configured for project management. +- Local Flow emulator running and ready for development. +- Project creation and management workflow with `flow init`. + +✅ **Smart contract deployment skills** + +- Counter contract successfully deployed to your local emulator. +- Account creation and contract deployment configuration mastered. + +✅ **Blockchain interactions** + +- Scripts to query contract state (read blockchain data). +- Transactions to modify contract state (write to blockchain). +- Real-time interaction with blockchain data through CLI commands. + +### Resources for continued learning + +As you continue your Flow development journey: + +- **[Flow Discord Community]**: Connect with other developers, get help, and share your projects. +- **[Cadence Language Reference]**: Deep dive into Flow's programming language features and best practices. +- **[Flow GitHub]**: Explore open source tools, examples, and contribute to the ecosystem. + +The foundation you've built today will serve you well as you explore Flow's capabilities and build applications that take advantage of blockchain's unique properties: permanence, transparency, and decentralization. + +Welcome to the Flow developer community—you're ready to build the future of digital experiences! + + + +[Flow Command Line Interface]: ../../../build/tools/flow-cli/index.md +[installation guide]: ../../../build/tools/flow-cli/install +[Flow Cadence VSCode Extension]: https://marketplace.visualstudio.com/items?itemName=onflow.cadence +[`flow.json`]: ../../../build/tools/flow-cli/flow.json/configuration.md +[Generating Cadence Boilerplate]: https://developers.flow.com/build/tools/flow-cli/generate +[basic scripts]: https://developers.flow.com/build/cadence/basics/scripts +[basic transactions]: https://developers.flow.com/build/cadence/basics/transactions +[tests documentation]: https://developers.flow.com/build/tools/flow-cli/tests +[homebrew]: https://brew.sh/ +[configuration docs]: ../../../build/tools/flow-cli/flow.json/configuration.md +[Flow Discord Community]: https://discord.com/invite/flow +[Cadence Language Reference]: https://cadence-lang.org +[Flow GitHub]: https://github.com/onflow diff --git a/docs/blockchain-development-tutorials/cadence/getting-started/imgs/flow-wallet-icons.png b/docs/blockchain-development-tutorials/cadence/getting-started/imgs/flow-wallet-icons.png new file mode 100644 index 0000000000..a8ee31c0e4 Binary files /dev/null and b/docs/blockchain-development-tutorials/cadence/getting-started/imgs/flow-wallet-icons.png differ diff --git a/docs/blockchain-development-tutorials/cadence/getting-started/imgs/provider.png b/docs/blockchain-development-tutorials/cadence/getting-started/imgs/provider.png new file mode 100644 index 0000000000..3e405d64da Binary files /dev/null and b/docs/blockchain-development-tutorials/cadence/getting-started/imgs/provider.png differ diff --git a/docs/blockchain-development-tutorials/cadence/getting-started/index.md b/docs/blockchain-development-tutorials/cadence/getting-started/index.md new file mode 100644 index 0000000000..cea8654cf9 --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/getting-started/index.md @@ -0,0 +1,99 @@ +--- +title: Getting Started with Cadence +description: Learn the fundamentals of Flow blockchain development with Cadence +sidebar_position: 1 +keywords: + - Flow development + - Cadence programming + - Smart contracts + - Flow CLI + - Flow emulator + - Blockchain development + - Counter contract + - Testnet deployment + - Mainnet deployment + - Frontend development + - Flow SDK + - Production deployment +--- + +# Getting Started With Cadence + +The Cadence is designed for the next generation of apps, games, and digital assets. This comprehensive tutorial series will guide you from development environment setup to production-ready application deployment on Flow's mainnet as a complete Counter application that demonstrates all essential Flow development patterns. + +
+ +
+ +## What you'll learn + +In this tutorial series, you'll discover how to: + +- Set up a complete Flow development environment with CLI tools and local emulator. +- Build and deploy smart contracts with Cadence. +- Integrate external dependencies and work with Flow's composable ecosystem. +- Create transactions and implement comprehensive testing strategies. +- Build interactive frontend applications with @onflow/react-sdk. +- Deploy applications to testnet and mainnet with production best practices. +- Implement monitoring, security, and maintenance for live blockchain applications. + +## What you'll build + +Throughout these tutorials, you'll build a complete **Counter Application** that demonstrates the core aspects of Flow development: + +- **Smart Contracts**: counter contract with increment/decrement functionality. +- **External Dependencies**: integration with NumberFormatter for enhanced display. +- **Frontend Interface**: react-based web application with wallet authentication. +- **Production Deployment**: live application accessible on Flow's public networks. + +By the end, you'll have a fully functional blockchain application and the skills to build your own Flow projects. + +## Environment setup + +Learn how to set up your Flow development environment and deploy your first smart contract. This foundational tutorial covers CLI installation, project creation, contract deployment, and basic blockchain interaction patterns with the local Flow emulator. + +Tutorial: [Cadence Environment Setup] + +## Smart contract interaction + +Gain advanced Flow development skills including dependency management, sophisticated transaction patterns, and comprehensive testing strategies. Learn to integrate external contracts, handle complex state changes, and implement test-driven development workflows. + +Tutorial: [Smart Contract Interaction] + +## Build a frontend app + +Create a `Next.js` frontend application that interacts with your Flow smart contracts via `@onflow/react-sdk`. Implement wallet authentication, real-time data queries, transaction submission, and status monitoring for a complete user experience. + +Tutorial: [Building a Frontend App] + +## Production deployment + +To take your application live, deploy to Flow's testnet and mainnet networks. Learn security best practices, production configuration, monitoring strategies, and maintenance practices you can use to manage live blockchain applications. + +Tutorial: [Production Deployment] + +## Next steps + +After you complete these tutorials, you'll have the fundamental skills needed for Flow development. You can explore our other tutorial series to expand your blockchain development expertise: + +- [Cross-VM Apps] - Build applications that integrate Flow EVM and Cadence +- [Native VRF] - Implement verifiable random functions in your applications +- [Token Launch] - Create and launch tokens on Flow + + + +[Cadence Environment Setup]: ./cadence-environment-setup.md +[Smart Contract Interaction]: ./smart-contract-interaction.md +[Building a Frontend App]: ./building-a-frontend-app.md +[Production Deployment]: ./production-deployment.md +[Cross-VM Apps]: ../../cross-vm-apps/introduction.md +[Native VRF]: ../../native-vrf/index.md +[Token Launch]: ../../tokens/index.md diff --git a/docs/blockchain-development-tutorials/cadence/getting-started/production-deployment.md b/docs/blockchain-development-tutorials/cadence/getting-started/production-deployment.md new file mode 100644 index 0000000000..3530f3528d --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/getting-started/production-deployment.md @@ -0,0 +1,399 @@ +--- +sidebar_position: 4 +sidebar_label: Production Deployment +title: Production Deployment +description: Learn how to deploy your Flow application to production networks. Deploy contracts to testnet and mainnet, configure your frontend for live networks, and implement production best practices for monitoring and maintenance. +keywords: + - production deployment + - Flow testnet + - Flow mainnet + - contract deployment + - testnet faucet + - production security + - network configuration + - mainnet deployment + - Flow CLI + - production monitoring + - live deployment + - blockchain production +--- + +# Production Deployment + +You've developed locally with the emulator, integrated external dependencies, built sophisticated transactions, implemented comprehensive testing, and created a frontend interface. Now it's time to take your application live and deploy it to Flow's public networks. + +This tutorial will guide you through deployment of your Counter application to both testnet and mainnet, which ensures that your contracts and frontend work seamlessly in production environments. You'll learn the essential practices for how to manage live blockchain applications, from security considerations to monitoring and maintenance. + +## What you'll learn + +After you complete this tutorial, you'll be able to: + +- **Deploy contracts to Flow testnet** with proper account setup and funding. +- **Configure your application** for different network environments (emulator, testnet, mainnet). +- **Deploy to mainnet** with security best practices and production considerations. +- **Update frontend configuration** to work with live networks. +- **Implement monitoring and maintenance** practices for production applications. +- **Understand the deployment pipeline** from development to production. + +**Prerequisites:** + +- Completed all previous tutorials ([Environment Setup], [Smart Contract Interaction], [Building a Frontend App]). +- Counter contract and frontend app working locally. +- Flow CLI installed and configured. + +## Deploy to testnet + +Testnet is Flow's public test network that mirrors mainnet functionality without using real FLOW tokens. It's the perfect environment to test your application in a live blockchain environment before you commit to mainnet deployment. + +### Understanding Flow networks + +Flow has several networks for different purposes: + +- **Emulator**: Local development environment (what you currently use). +- **Testnet**: Public test network with free test tokens. +- **Mainnet**: Production network with real Flow tokens. + +Each network has its own: + +- Access nodes and APIs. +- Account addresses and contract deployments. +- Token economics (free on testnet, real value on mainnet). + +### Create a testnet account + +First, you'll need a testnet account to deploy your contracts. You can create one with the Flow CLI: + +```zsh +flow accounts create --network testnet +``` + +When prompted: + +1. **Account name**: Enter `testnet-account` +2. **Select "Testnet" Network** + +This creates a new account on testnet and adds it to your `flow.json` configuration. The CLI will show you the account address and save the private key locally. + +### Fund your testnet account + +To deploy contracts and send transactions on testnet, you need Flow tokens. Flow provides a faucet service to get free testnet tokens. + +1. Visit the [Flow Testnet Faucet]. +2. Enter your testnet account address. +3. Complete any required verification (captcha, and so on). +4. Request tokens (you'll receive 1000 FLOW tokens). + +This command automatically requests tokens from the testnet faucet for your account. + +```zsh +flow accounts fund --network testnet testnet-account +``` + +**Verify funding:** + +Check your account balance: + +```zsh +flow accounts list +``` + +You will see your account details with a balance of Flow tokens. + +### Configure testnet deployment + +Update your `flow.json` to include testnet deployment configuration. The `NumberFormatter` contract already exists on testnet, so you only need to deploy your Counter contract. + +```zsh +flow config add deployment +``` + +Follow the prompts: + +1. **Network**: `testnet` +2. **Account**: `testnet-account` +3. **Contract**: `Counter` +4. **Deploy more contracts**: `yes` +5. **Contract**: `NumberFormatter` + +Your `flow.json` now includes a testnet deployment section: + +```json +{ + "deployments": { + "emulator": { + "default": ["Counter"], + "emulator-account": ["NumberFormatter"] + }, + "testnet": { + "testnet-account": ["Counter", "NumberFormatter"] + } + } +} +``` + +### Deploy Counter contract to testnet + +Deploy your Counter contract to the public testnet: + +```zsh +flow project deploy --network testnet +``` + +You will see output similar to: + +```zsh +Deploying 2 contracts for accounts: testnet-account + +Counter -> 0x9942a81bc6c3c5b7 (d8fe130e5b2212a5c7b3c34fe6e74ede80c750bc4c57e57788e81b247dcd7fe0) +NumberFormatter -> 0x9942a81bc6c3c5b7 (9a550aeefa5ede62cb95f0549084b2ab7abf3a493cf853d50c1c377a7be733b2) + +🎉 All contracts deployed successfully +``` + +### Test your testnet deployment + +Verify your contract works on testnet with this script: + +```zsh +flow scripts execute cadence/scripts/GetCounter.cdc --network testnet +``` + +You should see: + +```zsh +Result: "0" +``` + +Test a transaction to increment the counter: + +```zsh +flow transactions send cadence/transactions/IncrementCounter.cdc --network testnet --signer testnet-account +``` + +Run the script again to verify the increment worked: + +```zsh +flow scripts execute cadence/scripts/GetCounter.cdc --network testnet +``` + +```zsh +Result: "1" +``` + +Perfect! Your Counter contract is now live on testnet and works correctly. + +### Update frontend for testnet + +Now update your `Next.js` application to connect to testnet instead of the emulator. + +**Update `src/app/layout.tsx`:** + +```tsx +'use client'; + +import { FlowProvider } from '@onflow/react-sdk'; +import flowJson from '../flow.json'; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + {children} + + + + ); +} +``` + +**Key changes:** + +- `accessNodeUrl`: changed from localhost to Flow's testnet REST API. +- `flowNetwork`: changed from 'emulator' to 'testnet'. +- `discoveryWallet`: updated to use testnet wallet discovery. + +### Test your testnet frontend + +Start your frontend application: + +```bash +npm run dev +``` + +Visit `http://localhost:3000` and you will see: + +1. **Counter value**: displays the current count from your testnet contract. +2. **Connect Wallet**: connect with various Flow wallets (not just Dev Wallet). +3. **Increment functionality**: transactions are sent to the live testnet. +4. **Real transaction costs**: small amounts of testnet Flow are used for compute units, the Flow Cadence equivalence of gas. + +**Important**: When you connect your wallet, make sure to: + +- Switch your wallet to Testnet network. +- Use an account that has testnet Flow tokens. +- Confirm you're interacting with the correct contract address. + +## Deploy to mainnet + +Mainnet deployment is the final step in your application's journey. Unlike testnet, mainnet uses real Flow tokens and serves real users, so additional security considerations and best practices are essential. + +### Create a mainnet account + +For mainnet, you'll need to acquire Flow tokens through exchanges or other means, as there's no faucet. + +**Option 1: Use Flow Wallet** + +1. Download and install [Flow Wallet]. +2. Create a new wallet and securely store your recovery phrase. +3. Purchase Flow tokens from a supported exchange. +4. Transfer tokens to your Flow Wallet. + +**Option 2: Use Flow CLI** + +```zsh +flow accounts create --network mainnet +``` + +When prompted: + +1. **Account name**: Enter `mainnet-account` +2. **Select "Mainnet" Network** + +### Acquire FLOW tokens + +You can purchase Flow tokens from major exchanges like [Coinbase], [Moonpay], and [Binance]. + +To obtain Flow directly from the Flow Wallet, click "Buy" in your account. + +![flow-wallet-icons](./imgs/flow-wallet-icons.png) + +Then, click on a provider to purchase FLOW. + +![provider](./imgs/provider.png) + +### Configure mainnet deployment + +Add mainnet deployment configuration to your `flow.json`: + +```zsh +flow config add deployment --network mainnet +``` + +Follow the prompts: + +1. **Network**: `mainnet` +2. **Account**: `mainnet-account` +3. **Contract**: `Counter` +4. **Deploy more contracts**: `yes` +5. **Contract**: `NumberFormatter` + +Your `flow.json` will now include mainnet configuration: + +```json +{ + "dependencies": { + "NumberFormatter": { + "source": "testnet://8a4dce54554b225d.NumberFormatter", + "aliases": { + "mainnet": "1654653399040a61", + "testnet": "8a4dce54554b225d" + } + } + }, + "deployments": { + "emulator": { + "default": ["Counter"], + "emulator-account": ["NumberFormatter"] + }, + "testnet": { + "testnet-account": ["Counter", "NumberFormatter"] + }, + "mainnet": { + "mainnet-account": ["Counter", "NumberFormatter"] + } + } +} +``` + +### Deploy to mainnet + +Deploy your Counter contract to mainnet: + +```zsh +flow project deploy --network mainnet +``` + +**⚠️ Important**: This deployment costs real FLOW tokens and you can't undo it. + +You will see output similar to: + +```zsh +Deploying 2 contracts for accounts: mainnet-account + +Counter -> 0xABC123DEF456789 (contract deployed successfully) +NumberFormatter -> 0x123456789ABC (contract deployed successfully) + +🎉 All contracts deployed successfully +``` + +### Production frontend configuration + +Create a production build of your frontend configured for mainnet: + +**Update `src/app/layout.tsx` for production:** + +```tsx +'use client'; + +import { FlowProvider } from '@onflow/react-sdk'; +import flowJson from '../flow.json'; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + {children} + + + + ); +} +``` + +Build your production frontend: + +```bash +npm run build +``` + + + +[Flow Wallet]: https://wallet.flow.com/ +[Coinbase]: https://www.coinbase.com/en-in/how-to-buy/flow +[Moonpay]: https://www.moonpay.com/buy/flow +[Binance]: https://www.binance.com/en-IN/how-to-buy/flow +[Flow Testnet Faucet]: https://faucet.flow.com/ diff --git a/docs/blockchain-development-tutorials/cadence/getting-started/smart-contract-interaction.md b/docs/blockchain-development-tutorials/cadence/getting-started/smart-contract-interaction.md new file mode 100644 index 0000000000..93ecb06576 --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/getting-started/smart-contract-interaction.md @@ -0,0 +1,502 @@ +--- +sidebar_position: 2 +sidebar_label: Smart Contract Interaction +title: Smart Contract Interaction +description: Master advanced Flow development skills including external dependencies, sophisticated transactions, and comprehensive testing strategies. Learn to integrate contracts and implement test-driven development workflows. +keywords: + - Flow dependencies + - contract interaction + - Cadence transactions + - NumberFormatter + - dependency manager + - transaction anatomy + - smart contract testing + - test-driven development + - Flow CLI + - external contracts + - blockchain transactions + - Flow development +--- + +# Smart Contract Interaction + +Building on your local development setup from the previous tutorial, you'll now master advanced Flow development skills that every professional developer needs. This tutorial focuses on how to work with external dependencies, build sophisticated transactions, and establish robust testing practices. + +Flow's composability is one of its greatest strengths, becuase contracts can easily import and use functionality from other contracts. You'll learn to leverage this power while you build reliable, well-tested applications that interact seamlessly with the broader Flow ecosystem. + +## What you'll learn + +After you complete this tutorial, you'll be able to: + +- **Manage external dependencies** with Flow's dependency manager and integrate third-party contracts. +- **Build sophisticated transactions** that interact with multiple contracts and handle complex state changes. +- **Master transaction anatomy** and understand how Cadence transactions work under the hood. +- **Implement comprehensive testing** strategies including edge cases and error conditions. +- **Apply test-driven development** workflows to ensure code quality and reliability. +- **Handle transaction monitoring** and error management in production scenarios. + +## What you'll build + +Building on your Counter contract, you'll enhance it with external dependencies and create a comprehensive testing suite. By the end of this tutorial, you'll have: + +- **Enhanced Counter app** that uses the NumberFormatter contract for better display. +- **Complex transactions** that demonstrate advanced interaction patterns. +- **Comprehensive test suite** that covers normal operations, edge cases, and error conditions. +- **Professional workflow** for you to develop, test, and deploy contract interactions. + +**Prerequisites:** + +- Completed Environment Setup tutorial. +- Flow CLI, emulator running, and Counter contract deployed. +- Basic understanding of Cadence syntax. + +## Manage dependencies + +In addition to creating your own contracts, you can also install contracts that you previously deployed to the network with the [Dependency Manager]. This is useful for interacting with contracts that are part of the Flow ecosystem or that other developers deployed. + +Flow's dependency manager allows you to: + +- Install contracts deployed on any Flow network (mainnet, testnet, emulator). +- Automatically manage contract addresses across different environments. +- Keep your code portable and environment-independent. + +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`] from `testnet` that has a function to format numbers. + +### Install NumberFormatter contract + +The [`NumberFormatter`] contract provides utilities for formatting numbers with commas, which makes large numbers more readable. Let's install it from testnet: + +```zsh +flow dependencies install testnet://8a4dce54554b225d.NumberFormatter +``` + +When prompted: + +1. **Account to deploy to:** Select `emulator-account` (this will deploy it locally for development). +2. **Alias for mainnet:** To skip this, press Enter. + +This command: + +- Downloads the NumberFormatter contract from testnet and any of its dependencies. +- Adds it to your `imports/` directory. +- Configures deployment settings in [`flow.json`]. +- Sets up automatic address resolution. + +### Configure dependencies in flow.json + +Open your `flow.json` file and view the new sections: + +```json +{ + . + . + . + "dependencies": { + "NumberFormatter": { + "source": "testnet://8a4dce54554b225d.NumberFormatter", + "hash": "dc7043832da46dbcc8242a53fa95b37f020bc374df42586a62703b2651979fb9", + "aliases": { + "testnet": "8a4dce54554b225d" + } + } + }, + . + . + . + "deployments": { + "emulator": { + "emulator-account": [ + "NumberFormatter" + ] + } + } +} +``` + +This configuration: + +- Maps the `NumberFormatter` dependency to its testnet source. +- Sets up deployment to your emulator account. +- Allows automatic address resolution in your code. + +### Deploy external dependencies + +Now we can deploy the `NumberFormatter` contract to the emulator: + +```zsh +flow project deploy +``` + +You will see output like: + +```zsh +Deploying 1 contracts for accounts: emulator-account + +NumberFormatter -> 0xf8d6e0586b0a20c7 (66e6c4210ae8263370fc3661f148f750175bb4cf2e80637fb42eafe2d6c5b385) + +🎉 All contracts deployed successfully +``` + +### Integrate external contract + +Now let's update your `GetCounter.cdc` script to use the NumberFormatter. Open `cadence/scripts/GetCounter.cdc` and update it: + +```cadence +import "Counter" +import "NumberFormatter" + +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 +} +``` + +**Key points:** + +- **Import syntax**: `import "Counter"` and `import "NumberFormatter"` don't require addresses. +- **Contract interaction**: We call `NumberFormatter.formatWithCommas()` just like any other function. +- **Return type change**: The script now returns a `String` instead of an `Int`. + +### Test the integration + +Run your updated script: + +```zsh +flow scripts execute cadence/scripts/GetCounter.cdc +``` + +You will see: + +```zsh +Result: "1" +``` + +The number is now formatted as a string. Let's create a more impressive example and add a transaction that increments by 1000. + +### Create a bulk increment transaction + +Generate a new transaction to demonstrate the NumberFormatter's power: + +```zsh +flow generate transaction IncrementBy1000 +``` + +Open `cadence/transactions/IncrementBy1000.cdc` and replace the content with: + +```cadence +import "Counter" + +transaction { + prepare(acct: &Account) { + // Authorization handled automatically + } + + execute { + // Increment the counter 1000 times + var i = 0 + while i < 1000 { + Counter.increment() + i = i + 1 + } + + // Retrieve the new count and log it + let newCount = Counter.getCount() + log("New count after incrementing by 1000: ".concat(newCount.toString())) + } +} +``` + +Execute the transaction: + +```zsh +flow transactions send cadence/transactions/IncrementBy1000.cdc --signer test-account +``` + +Now run your formatted script to see the NumberFormatter in action: + +```zsh +flow scripts execute cadence/scripts/GetCounter.cdc +``` + +Result: + +```zsh +Result: "1,001" +``` + +Perfect! The NumberFormatter automatically adds commas to make large numbers readable. + +:::info + +**The Power of Composability**: Notice what just happened—you enhanced your Counter contract's functionality **without modifying the original contract**. This is the power of Flow's composability: you can extend functionality by combining contracts, which allows rapid development and code reuse. Even more importantly, we did this **without the need for access or permission.** + +::: + +## Build transactions + +Transactions are the foundation of blockchain state changes. Unlike scripts (which only read data), transactions can modify contract state, transfer tokens, and emit events. Let's master advanced transaction patterns. + +### Understand transaction anatomy + +Every Cadence transaction has the same basic structure: + +```cadence +import "OtherContract" + +transaction { + // Optional: Declare variables available throughout the transaction + let initialCount: Int + + // This phase has access to account storage and capabilities + // Used for authorization and accessing private data + prepare(acct: &Account) { + } + + // This phase contains the main transaction logic + // No access to account storage, only to data from prepare phase + execute { + } + + // Optional: Conditions that must be true after execution + // Used for verification and ensuring transaction success + post { + } +} +``` + +### Transaction phases explained + +1. **Import Phase**: declare contract dependencies. +2. **Parameter Declaration**: define inputs the transaction accepts. +3. **Variable Declaration**: declare transaction-scoped variables. +4. **Prepare Phase**: access account storage and capabilities (authorized). +5. **Execute Phase**: main logic execution (no storage access). +6. **Post Phase**: verify transaction success conditions. + +#### Transaction with parameters + +Create a transaction that accepts a custom increment value: + +```zsh +flow generate transaction IncrementByAmount +``` + +Open `cadence/transactions/IncrementByAmount.cdc`: + +```cadence +import "Counter" + +transaction(amount: Int) { + + // Store initial value + let initialCount: Int + + prepare(acct: &Account) { + // Verify the account is authorized to make this change + log("Account ".concat(acct.address.toString()).concat(" is incrementing by ").concat(amount.toString())) + + prepare(acct: &Account) { + self.initialCount = Counter.getCount() // Capture initial state + log("Account".concat(acct.address.toString()).concat(" is incrementing by").concat(amount.toString())) + } + + execute { + // Validate input + if amount <= 0 { + panic("Amount must be positive") + } + + // Increment the specified number of times + var i = 0 + while i < amount { + Counter.increment() + i = i + 1 + } + + let newCount = Counter.getCount() + log("Counter incremented by ".concat(amount.toString()).concat(", new value: ").concat(newCount.toString())) + } + + post { + // Verify the counter increased correctly + Counter.getCount() == (self.initialCount + amount): "Counter must equal initial count plus increment amount" + } + } +} +``` + +Execute with a parameter: + +```zsh +flow transactions send cadence/transactions/IncrementByAmount.cdc --network emulator --signer test-account +``` + +## Test your code + +Testing is crucial for smart contract development. Flow provides powerful testing capabilities built into the CLI that allow comprehensive test coverage and test-driven development workflows. + +Execute the test suite: + +```zsh +flow test +``` + +You will see output that confirms the tests pass: + +```zsh +Test results: "Counter_test.cdc" +- PASS: testContract + +All tests passed +``` + +### Understand current tests + +Open `cadence/tests/Counter_test.cdc` to see the existing test: + +```cadence +import Test + +access(all) let account = Test.createAccount() + +access(all) fun testContract() { + let err = Test.deployContract( + name: "Counter", + path: "../contracts/Counter.cdc", + arguments: [] + ) + + Test.expect(err, Test.beNil()) +} +``` + +This basic test: + +1. **Creates a test account** with `Test.createAccount()`. +2. **Deploys the Counter contract** to the test environment. +3. **Verifies deployment succeeded** by checking that no error occurred. + +### Test integration with dependencies + +Test the NumberFormatter integration: + +```cadence +import Test + +access(all) let account = Test.createAccount() + +access(all) fun testNumberFormatterLogic() { + // Test NumberFormatter logic inline without contract deployment + // Test small number (under 1000) - should have no comma + let smallNumberScript = Test.executeScript( + "access(all) fun formatWithCommas(number: Int): String { let isNegative = number < 0; let absNumber = number < 0 ? -number : number; let numberString = absNumber.toString(); var formatted = \"\"; var count = 0; let numberLength = numberString.length; var i = numberLength - 1; while i >= 0 { let digit = numberString.slice(from: i, upTo: i + 1); formatted = digit.concat(formatted); count = count + 1; if count % 3 == 0 && i != 0 { formatted = \",\".concat(formatted) }; i = i - 1 }; if isNegative { formatted = \"-\".concat(formatted) }; return formatted }; access(all) fun main(): String { return formatWithCommas(number: 123) }", + [] + ) + Test.expect(smallNumberScript, Test.beSucceeded()) + let smallResult = smallNumberScript.returnValue! as! String + Test.expect(smallResult, Test.equal("123")) + + // Test large number (over 999) - should have comma + let largeNumberScript = Test.executeScript( + "access(all) fun formatWithCommas(number: Int): String { let isNegative = number < 0; let absNumber = number < 0 ? -number : number; let numberString = absNumber.toString(); var formatted = \"\"; var count = 0; let numberLength = numberString.length; var i = numberLength - 1; while i >= 0 { let digit = numberString.slice(from: i, upTo: i + 1); formatted = digit.concat(formatted); count = count + 1; if count % 3 == 0 && i != 0 { formatted = \",\".concat(formatted) }; i = i - 1 }; if isNegative { formatted = \"-\".concat(formatted) }; return formatted }; access(all) fun main(): String { return formatWithCommas(number: 1234) }", + [] + ) + Test.expect(largeNumberScript, Test.beSucceeded()) + let largeResult = largeNumberScript.returnValue! as! String + Test.expect(largeResult, Test.equal("1,234")) +} +``` + +The `Formatter_test.cdc` test validates that number formatting with commas works correctly by testing two scenarios: numbers under 1,000 (which should have no commas) and numbers over 999 (which should have commas). The test is constructed with two main assertions - first testing that 123 formats as "123" without commas, and second testing that 1234 formats as "1,234" with a comma. + +### Run your enhanced test suite + +Execute the complete test suite with your new comprehensive tests: + +```zsh +flow test +``` + +You should see output like: + +```zsh +Running tests... + +Test results: "cadence/tests/Formatter_test.cdc" +- PASS: testNumberFormatterLogic +Test results: "cadence/tests/Counter_test.cdc" +- PASS: testContract + +All tests passed +``` + +:::tip + +For a more detailed guide on Cadence testing patterns and advanced techniques, check out the [tests documentation]. + +::: + +--- + +## Conclusion + +Through this tutorial, you've accomplished: + +✅ **Dependency management** + +- Successfully integrated the NumberFormatter contract from testnet. +- Learned about Flow's dependency management system and automatic address resolution. +- Demonstrated contract composability by enhancing functionality without modifying source code. +- Configured multi-contract deployments across different environments. + +✅ **Transaction development** + +- Understood transaction anatomy including prepare, execute, and post phases. +- Implemented proper input validation and error handling patterns. + +✅ **Testing** + +- Implemented test coverage for contract functionality +- Created integration tests that verify multi-contract interactions + +### What you've learned + +You have learned how to use Flow's dependency management system to install and integrate external contracts (like NumberFormatter), understand the structure of Cadence transactions including their prepare, execute, and post phases, and implement basic testing for contract functionality. You can now work with multi-contract applications and understand how contracts can be composed together to extend functionality. + +### Next steps + +With these skills, you're ready to: + +- Build frontend applications that interact with your smart contracts. +- Deploy contracts to live networks (testnet and mainnet). +- Explore advanced Flow patterns and ecosystem contracts. +- Contribute to the growing Flow developer community. + +You've made significant progress in becoming a proficient Flow developer! + +### Resources for continued learning + +Continue your Flow mastery with these advanced resources: + +- **[Flow Discord Community]**: Connect with other developers building sophisticated Flow applications. +- **[Cadence Language Reference]**: Master advanced language features including resources, capabilities, and access control. +- **[Flow GitHub]**: Explore production contract examples and contribute to the ecosystem. + + + +[tests documentation]: ../../../build/tools/flow-cli/tests.md +[Flow Discord Community]: https://discord.gg/flow-blockchain +[Flow Documentation]: https://developers.flow.com +[Cadence Language Reference]: https://cadence-lang.org +[Flow GitHub]: https://github.com/onflow +[Flow DevEX]: https://flowdevx.com +[Dependency Manager]: https://developers.flow.com/build/tools/flow-cli/dependency-manager +[`NumberFormatter`]: https://contractbrowser.com/A.8a4dce54554b225d.NumberFormatter +[`flow.json`]: https://developers.flow.com/build/tools/flow-cli/flow.json/configuration diff --git a/docs/blockchain-development-tutorials/cadence/index.md b/docs/blockchain-development-tutorials/cadence/index.md new file mode 100644 index 0000000000..52eb0786e6 --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/index.md @@ -0,0 +1,109 @@ +--- +title: Cadence Tutorials +description: Learn Cadence development through practical tutorials covering account management, mobile development, and advanced Flow features. +sidebar_position: 5 +keywords: + - Cadence + - Flow development + - account management + - mobile development + - hybrid custody + - account linking + - blockchain tutorials + - smart contracts + - Flow tutorials + - native applications +--- + +# Cadence tutorials + +Master Cadence development on Flow through comprehensive tutorials that cover essential concepts and practical implementations. These tutorials guide you through how to build real-world applications with Flow's unique features like account linking, mobile integration, and advanced account management patterns. + +## What you'll learn + +In this tutorial series, you'll discover how to: + +- Implement Flow's unique account linking and hybrid custody models. +- Build native mobile applications with Flow integration. +- Create progressive onboarding experiences for mainstream users. +- Manage complex account relationships and permissions. +- Leverage Flow's native features in mobile environments. +- Build secure, user-friendly blockchain applications. + +# Cadence development tutorials + +## Account Management + +Learn about Flow's revolutionary Account Linking system that allow shared ownership and progressive onboarding experiences. These tutorials cover the hybrid custody model, parent-child account relationships, and how to implement walletless onboarding that seamlessly transitions users to self-custody. + +- **[Account Linking Overview]** - Understand Flow's unique account linking concepts and hybrid custody model. +- **[Building with Child Accounts]** - Create walletless applications with progressive onboarding flows. +- **[Parent Account Management]** - Implement parent account functionality and account delegation. +- **[Account Linking with Dapper]** - Integrate with Dapper Wallet's account linking system. + +## Mobile development + +Discover how to build native mobile applications that leverage Flow's blockchain capabilities. These tutorials cover mobile SDKs, secure key management, wallet integration, and how to create rich user experiences on iOS and Android platforms. + +- **[Mobile Development Overview]** - Learn about Flow's mobile development capabilities and ecosystem. +- **[iOS Quickstart]** - Build your first iOS app with Flow integration. +- **[React Native Integration]** - Create cross-platform mobile apps with React Native and Flow. +- **[Walletless Mobile Apps]** - Implement progressive web apps with walletless onboarding. + +## Testing + +Learn how to test Cadence smart contracts with a focus on fork testing, which allows you to run tests against real on-chain state from Flow mainnet or testnet. + +- **[Fork Testing]** - Run Cadence tests against a forked mainnet with real contracts and production data without deploying to live networks. + +## Key features covered + +### Account Linking & hybrid custody + +- **Progressive onboarding**: Start users with custodial accounts, transition to self-custody. +- **Shared ownership**: Allow multiple parties to control and access accounts. +- **Flexible permissions**: Fine-grained access control through capabilities and entitlements. +- **Seamless transitions**: Move from custodial to non-custodial without losing assets. + +### Mobile-first development + +- **Native integration**: Build truly native mobile experiences with blockchain functionality. +- **Secure key management**: Leverage device security features for key storage. +- **Wallet integration**: Connect with popular Flow wallets and WalletConnect. +- **Rich user experiences**: Create smooth, Web2-like experiences in Web3 apps. + +### Flow-specific advantages + +- **Account abstraction**: Built-in multi-signature and sponsored transactions. +- **Resource safety**: Cadence's resource-oriented programming prevents common mobile app vulnerabilities. +- **Fast finality**: Near-instant transaction confirmation for responsive mobile UIs. +- **Low costs**: Turn on micro-transactions and frequent interactions in mobile apps. + +## Next steps + +After you complete these tutorials, you'll be equipped to build sophisticated Cadence applications that leverage Flow's unique capabilities. Consider exploring our other tutorial series: + +- **[Flow Actions]** - Build composable DeFi workflows with standardized interfaces. +- **[Cross-VM Apps]** - Create applications that span both Cadence and Flow EVM. +- **[Native VRF]** - Implement verifiable random functions in your applications. +- **[Use AI to Build on Flow]** - Enhance development with AI-powered tools. + +## Conclusion + +Flow's Cadence offers unparalleled capabilities for building user-friendly blockchain applications. The combination of account linking, mobile-first development tools, and resource-oriented programming creates opportunities to build mainstream-ready Web3 applications. These tutorials provide the foundation for creating applications that can onboard millions of users while maintaining the security and decentralization principles of blockchain technology. + + + +[Account Linking Overview]: ./account-management/index.md +[Building with Child Accounts]: ./account-management/child-accounts.md +[Parent Account Management]: ./account-management/parent-accounts.md +[Account Linking with Dapper]: ./account-management/account-linking-with-dapper.md +[Mobile Development Overview]: ./mobile/index.md +[iOS Quickstart]: ./mobile/ios-quickstart.md +[React Native Integration]: ./mobile/react-native-quickstart.md +[Walletless Mobile Apps]: ./mobile/walletless-pwa.md +[Fork Testing]: ./fork-testing/index.md +[Flow Actions]: ../forte/flow-actions/index.md +[Cross-VM Apps]: ../cross-vm-apps/index.md +[Native VRF]: ../native-vrf/index.md +[Use AI to Build on Flow]: ../use-AI-to-build-on-flow/index.md diff --git a/docs/build/guides/mobile/resources/collection.png b/docs/blockchain-development-tutorials/cadence/mobile/imgs/collection.png similarity index 100% rename from docs/build/guides/mobile/resources/collection.png rename to docs/blockchain-development-tutorials/cadence/mobile/imgs/collection.png diff --git a/docs/build/guides/mobile/resources/connect.png b/docs/blockchain-development-tutorials/cadence/mobile/imgs/connect.png similarity index 100% rename from docs/build/guides/mobile/resources/connect.png rename to docs/blockchain-development-tutorials/cadence/mobile/imgs/connect.png diff --git a/docs/build/guides/mobile/resources/initialize.png b/docs/blockchain-development-tutorials/cadence/mobile/imgs/initialize.png similarity index 100% rename from docs/build/guides/mobile/resources/initialize.png rename to docs/blockchain-development-tutorials/cadence/mobile/imgs/initialize.png diff --git a/docs/build/guides/mobile/resources/monster_maker_logo.png b/docs/blockchain-development-tutorials/cadence/mobile/imgs/monster_maker_logo.png similarity index 100% rename from docs/build/guides/mobile/resources/monster_maker_logo.png rename to docs/blockchain-development-tutorials/cadence/mobile/imgs/monster_maker_logo.png diff --git a/docs/build/guides/mobile/resources/pwa_link_account_thumbnail.png b/docs/blockchain-development-tutorials/cadence/mobile/imgs/pwa_link_account_thumbnail.png similarity index 100% rename from docs/build/guides/mobile/resources/pwa_link_account_thumbnail.png rename to docs/blockchain-development-tutorials/cadence/mobile/imgs/pwa_link_account_thumbnail.png diff --git a/docs/build/guides/mobile/resources/pwa_mint_balloon_thumbnail.png b/docs/blockchain-development-tutorials/cadence/mobile/imgs/pwa_mint_balloon_thumbnail.png similarity index 100% rename from docs/build/guides/mobile/resources/pwa_mint_balloon_thumbnail.png rename to docs/blockchain-development-tutorials/cadence/mobile/imgs/pwa_mint_balloon_thumbnail.png diff --git a/docs/build/guides/mobile/resources/pwa_prompt.jpeg b/docs/blockchain-development-tutorials/cadence/mobile/imgs/pwa_prompt.jpeg similarity index 100% rename from docs/build/guides/mobile/resources/pwa_prompt.jpeg rename to docs/blockchain-development-tutorials/cadence/mobile/imgs/pwa_prompt.jpeg diff --git a/docs/build/guides/mobile/resources/pwa_youtube_thumbnail.png b/docs/blockchain-development-tutorials/cadence/mobile/imgs/pwa_youtube_thumbnail.png similarity index 100% rename from docs/build/guides/mobile/resources/pwa_youtube_thumbnail.png rename to docs/blockchain-development-tutorials/cadence/mobile/imgs/pwa_youtube_thumbnail.png diff --git a/docs/build/guides/mobile/resources/xcode_setup.png b/docs/blockchain-development-tutorials/cadence/mobile/imgs/xcode_setup.png similarity index 100% rename from docs/build/guides/mobile/resources/xcode_setup.png rename to docs/blockchain-development-tutorials/cadence/mobile/imgs/xcode_setup.png diff --git a/docs/blockchain-development-tutorials/cadence/mobile/index.md b/docs/blockchain-development-tutorials/cadence/mobile/index.md new file mode 100644 index 0000000000..a82a3c973a --- /dev/null +++ b/docs/blockchain-development-tutorials/cadence/mobile/index.md @@ -0,0 +1,88 @@ +--- +title: Mobile Development on Flow +sidebar_position: 4 +description: Discover Flow's mobile development capabilities for building native blockchain applications. Learn about Flow's unique features for mobile apps, including secure key management, wallet integration, and progressive onboarding. +keywords: + - Flow mobile + - mobile development + - blockchain apps + - native applications + - mobile SDK + - secure enclave + - wallet integration + - WalletConnect + - account linking + - mobile security + - Flow features + - mobile wallets + - Cadence mobile + - user experience + - blockchain mobile +--- + +# Mobile Development on Flow + +When you build mobile native applications that interact with the blockchain, it allows a much richer end user experience and provides access to OS capabilities. With Flow Mobile, developers can build native applications for iOS and Android with SDKs and mobile wallets. + +## Why Flow + +Millions of users with Flow accounts explore the ecosystem and look for applications. Most of these users purchased Flow NFTs and are comfortable with web3 principles. + +In addition to the current user base, developers can tap into smart contracts deployed on the Flow blockchain. These contracts, which includes their onchain state, provide unique possibilities to build experiences that enrich currently-used applications. + +The following key capabilities make Flow a standout choice for mobile applications: + +- On-device key encryption via Secure Enclave & Keychain. +- Mobile wallet compatibility and support for WalletConnect 2.0. +- Simple, progressive onboarding experience with postponed account linking. +- Seamless in-app experience with onchain interactions without constant signing requests. +- Account flexibility enabling secure account recovery and sharing. + +## Why Flow Mobile + +### Proven + +Flow is built with mainstream adoption in mind. Mobile applications can leverage the best-in-class user experiences millions of users have enjoyed on the web, through applications like NBA TopShot or NFL AllDay. + +### Best-in-class UX + +Flow's Client Library makes it very intuitive to sign up and sign in with their wallet of choice. For transaction signing, Flow offers human readable security, so users get a clear understanding of what they approve. An increased sense of trust for Flow applications is the outcome. + +Furthermore, Flow's powerful account model allows for seamless user flows of onchain operations. Apps can perform transactions on behalf of the users (with their approval) in the background, without the need to switch between apps. The account model also allows apps to pay for transactions to postpone fiat on-ramps to get them to experience the value of an application before they commit to buy tokens. + +Last, but not least, developers can leverage progressive web3 onboarding, in which you can use any identity provider authenticate users, but don't have to deal with keys. Developers can create Flow accounts for the users and link them to a wallet at a later point in time. + +### Security first + +Flow's mobile SDKs use on-device key encryption via Apple's Secure Enclave and Android's Keystore. The flexible account model makes it possible for an account to have multiple keys with different weights, which allows secure social recovery, account sharing, and much more. + +## Smart contract language inspired by mobile languages + +Cadence, Flow's smart contract language, will look and feel very familiar to mobile languages developers are already familiar with. Cadence was inspired by Move, Swift, and Kotlin. This reduces the ramp-up period to develop mobile applications leveraging onchain logic. + +## What is available + +Developers can leverage the following features to get productive quickly: + +- Swift & Kotlin FCL SDKs to authenticate and interact with the Flow blockchain (query + execute scripts). +- FCL-compatible mobile wallets. +- User authentication with WalletConnect 2.0. +- Basic mobile sample application (MonsterMaker). + +## Guides + +**[iOS Development]** - Learn native iOS development on Flow through the Monster Maker sample project, which demonstrates wallet integration, transaction signing, and NFT management. The tutorial covers FCL Swift SDK integration, WalletConnect 2.0 for wallet connectivity, and essential blockchain interactions like querying and mutating data. + +**[React Native Development]** - Build cross-platform mobile dApps using React Native and Flow Client Library (FCL). This guide walks through how to set up authentication, query the blockchain, and execute transactions while interacting with the Profile Contract on Flow's testnet to create and edit user profiles. + +**[Build a Walletless Mobile App (PWA)]** - Create an accessible Progressive Web App with seamless onboarding with Magic integration for walletless authentication. The tutorial covers how to build a balloon inflation game that demonstrates Magic SDK integration, hybrid custody features, and account linking to transition from custodial to non-custodial ownership. + +## Conclusion + +Flow Mobile empowers developers to create native blockchain applications that deliver best-in-class user experiences and maintain the security and flexibility that mainstream adoption demands. Whether you build with native SDKs or create Progressive Web Apps, Flow's mobile development capabilities provide the tools needed to bring web3 to millions of users through intuitive, secure, and feature-rich mobile experiences. + + + +[iOS Development]: ./ios-quickstart.md +[React Native Development]: ./react-native-quickstart.md +[Build a Walletless Mobile App (PWA)]: ./walletless-pwa.md diff --git a/docs/build/guides/mobile/ios-quickstart.md b/docs/blockchain-development-tutorials/cadence/mobile/ios-quickstart.md similarity index 67% rename from docs/build/guides/mobile/ios-quickstart.md rename to docs/blockchain-development-tutorials/cadence/mobile/ios-quickstart.md index 12df8bd8e6..467c159d3a 100644 --- a/docs/build/guides/mobile/ios-quickstart.md +++ b/docs/blockchain-development-tutorials/cadence/mobile/ios-quickstart.md @@ -1,7 +1,7 @@ --- title: IOS Development sidebar_label: IOS Development -sidebar_position: 3 +sidebar_position: 1 description: Learn how to build native iOS applications on Flow blockchain using the Monster Maker sample project. Understand wallet integration, transaction signing, and NFT management in mobile apps. keywords: - iOS development @@ -21,48 +21,48 @@ keywords: - blockchain mobile --- -# Overview +# IOS Development -The following documentation aims to educate you on building a native mobile application on Flow. It first presents Monster Maker, a starter project we've built to represent simple Flow mobile concepts. Next it presents various developer resources related to building mobile native Flow applications. +The following tutorial aims to educate you on how to build a native mobile application on Flow. It first presents Monster Maker, a starter project we've built to represent simple Flow mobile concepts. Next, it presents various developer resources related to building mobile native Flow applications. -# Monster Maker +## Monster Maker -![monster_maker_logo.png](resources/monster_maker_logo.png) +![monster_maker_logo.png](./imgs/monster_maker_logo.png) -Monster Maker is a native iOS app that allows users to connect a wallet, sign a transaction to mint an NFT (a monster) and display their collection of NFTs (their monsters) within the app. It's meant to be a lightweight sample project to exemplify how to build a mobile native Flow project. If you're looking to build a native mobile application for Flow, exploring the Monster Maker code base first or even building off of it is a great way to get started. +Monster Maker is a native iOS app that allows users to connect a wallet, sign a transaction to mint an NFT (a monster) and display their collection of NFTs (their monsters) within the app. It's meant to be a lightweight sample project to exemplify how to build a mobile native Flow project. If want to build a native mobile application for Flow, explore the Monster Maker code base first, or you can even build off of it! -## Github Repo +## Github repo The Monster Maker Github Repo can be found here: https://github.com/onflow/monster-maker -## Building to Device +## Build to device -Before you run Monster Maker on your device, please make sure you have installed the [Xcode14](https://apps.apple.com/au/app/xcode/id497799835?mt=12) from Mac App Store. Once you clone the repo, open the [MonsterMaker.xcodeproj](https://github.com/onflow/monster-maker/tree/main/iOS/MonsterMaker.xcodeproj) under the iOS folder. +Before you run Monster Maker on your device, make sure you've installed the [Xcode14] from Mac App Store. After you clone the repo, open the [MonsterMaker.xcodeproj] under the iOS folder. -Xcode should automatically setup the project for you. If you do see any error related to dependencies, run `Xcode Menu -> File -> Packages -> Reset Package Cache` to resolve the issue. +Xcode automatically sets up the project for you. If you see any errors related to dependencies, run `Xcode Menu -> File -> Packages -> Reset Package Cache` to resolve the issue. -In the meantime, you can choose a simulator or your iPhone to run. For more detail here is the [official doc](https://developer.apple.com/documentation/xcode/running-your-app-in-simulator-or-on-a-device). -For run in real device, there are a few steps to deal with signing: +In the meantime, you can choose a simulator or your iPhone to run. For more detail, read the [official doc]. +For run in real device, there are a few steps to deal with for signing: -1. Add your apple account to the Xcode which can be accessed from `Xcode Menu -> Settings -> Add account`. -2. Change the Team to your Personal Apple account from the **Signing & Capabilities** under the project target menu. For more detail, please check the screenshot below. +1. Add your apple account to the Xcode which you can access from `Xcode Menu -> Settings -> Add account`. +2. Change the Team to your Personal Apple account from the **Signing & Capabilities** under the project target menu. For more detail, check the screenshot below. - ![XCode Target Setup](resources/xcode_setup.png) + ![XCode Target Setup](./imgs/xcode_setup.png) -## Connecting to a Wallet +## Connect to a wallet -To connect with wallets, there is native wallet discovery in the app. Once you click on connect, it will bring out the list of the wallets which support `HTTP/POST` or `WC/RPC` method. +To connect with wallets, there is native wallet discovery in the app. After you click connect, it brings out the list of the wallets which support `HTTP/POST` or `WC/RPC` method. -### FCL Config +### FCL config -To make sure, the wallet can recognise your dApp, there is a few field you will need to config before connect to a wallet. The account proof config is optional. In addition, you will need to create a project id from [walletconnect](https://cloud.walletconnect.com/app) cloud before you can connect to the `WC/RPC` compatible wallet such as [Flow Wallet](https://wallet.flow.com/). +To make sure the wallet can recognise your dApp, there are a few fields you need to configure before you connect to a wallet. The account proof config is optional. In addition, you'll need to create a project id from [walletconnect] cloud before you can connect to the `WC/RPC` compatible wallet such as [Flow Wallet]. ```swift import FCL @@ -98,15 +98,15 @@ fcl.config ### Open wallet discovery -![In Monster Maker, the Connect button triggers opening of Wallet Discovery](resources/connect.png) +![In Monster Maker, the Connect button triggers opening of Wallet Discovery](./imgs/connect.png) -In Monster Maker, the Connect button triggers opening of Wallet Discovery +In Monster Maker, click `Connect` to open Wallet Discovery -For the wallet support `HTTP/POST`, it will use webview to show the following actions. +For the wallet support `HTTP/POST`, it uses webview to show the following actions. -For the wallet support `WC/RPC`, it will use deep-link to the wallet for actions. +For the wallet support `WC/RPC`, it uses deep-link to the wallet for actions. -You can open the native wallet discovery to make the selection, but also you can connect to the specific wallet as well. +You can open the native wallet discovery to make the selection, but you can also connect to the specific wallet. Here is the code snippet of it: @@ -121,13 +121,13 @@ try fcl.changeProvider(provider: provider, env: .testnet) try await fcl.authenticate() ``` -## Signing a Transaction +## Sign a transaction -![In Monster Maker, Initializing the NFT collection with the Initialize button triggers a transaction.](resources/initialize.png) +![In Monster Maker, Initializing the NFT collection with the Initialize button triggers a transaction.](./imgs/initialize.png) -In Monster Maker, Initializing the NFT collection with the Initialize button triggers a transaction. +In Monster Maker, click `Initialize` to initialize the NFT colelction. This triggers a transaction. -Similar to what we have on fcl-js, native sdk also use `query` and `mutate` for on-chain interactions. To request a signature from user, you can simply use `fcl.mutate` method. By default, the user will be the payer, proposer and authorizer, if you want to add custom authorizer please refer to the code from [Server](https://github.com/onflow/monster-maker/blob/main/server/pages/api/signAsMinter/index.ts) and [iOS](https://github.com/onflow/monster-maker/blob/main/iOS/MonsterMaker/Flow/MintHelper.swift) end. +Similar to what we have on fcl-js, native sdk also use `query` and `mutate` for onchain interactions. To request a signature from user, you can simply use `fcl.mutate` method. By default, the user is the payer, proposer and authorizer. If you want to add custom authorizer refer to the code from [Server] and [iOS] end. ```swift guard let user = fcl.currentUser else { @@ -157,9 +157,9 @@ print("txId -> \(txId)") ## View NFT -![The View page in Monster Maker exemplifies showing Monster Maker NFTs held by the connected wallet](resources/collection.png) +![The View page in Monster Maker exemplifies showing Monster Maker NFTs held by the connected wallet](./imgs/collection.png) -The View page in Monster Maker exemplifies showing Monster Maker NFTs held by the connected wallet +The View page in Monster Maker exemplifies showing Monster Maker NFTs held by the connected wallet. During development, you always can query your NFT with `fcl.query`. Here is an example: @@ -253,7 +253,7 @@ let nftList = try await fcl.query(script: cadenceScript, .decode([NFTModel].self) ``` -# External Resources +# External resources **FCL Swift** @@ -269,13 +269,26 @@ https://github.com/Outblock/fcl-android **FCL Wallet Connect 2.0** -One of the easiest ways to connect to a wallet via a mobile native dApp is through Flow's new support for Wallet Connect 2.0. This is the pattern that Monster Maker uses to connect to the [Flow Wallet](https://wallet.flow.com/). For more information on FCL Wallet Connect 2.0, check out this page: +One of the easiest ways to connect to a wallet via a mobile native dApp is through Flow's new support for Wallet Connect 2.0. This is the pattern that Monster Maker uses to connect to the [Flow Wallet]. For more information on FCL Wallet Connect 2.0, check out this page: -[FCL Wallet Connect](../../../tools/clients/fcl-js/wallet-connect.md) +[FCL Wallet Discovery] -**How to Build a Native iOS Dapp** +**How to build a native iOS dapp** -The Agile Monkeys has written a very comprehensive guide on how to build a native mobile application on iOS and interface with fcl-swift. Found here: +The Agile Monkeys wrote a very comprehensive guide on how to build a native mobile application on iOS and interface with fcl-swift, which you can view with the link below: -[How to Build a Native iOS Dapper](https://dev.to/theagilemonkeys/how-to-buid-a-native-ios-dapp-that-uses-the-flow-blockchain-as-the-backend-n9k) -[Source Code](https://github.com/jfsagasti/FlowNotes) +[How to Build a Native iOS Dapper] +[Source Code] + + + +[Xcode14]: https://apps.apple.com/au/app/xcode/id497799835?mt=12 +[MonsterMaker.xcodeproj]: https://github.com/onflow/monster-maker/tree/main/iOS/MonsterMaker.xcodeproj +[official doc]: https://developer.apple.com/documentation/xcode/running-your-app-in-simulator-or-on-a-device +[walletconnect]: https://cloud.walletconnect.com/app +[Flow Wallet]: https://wallet.flow.com/ +[Server]: https://github.com/onflow/monster-maker/blob/main/server/pages/api/signAsMinter/index.ts +[iOS]: https://github.com/onflow/monster-maker/blob/main/iOS/MonsterMaker/Flow/MintHelper.swift) +[FCL Wallet Discovery]: ../../../build/tools/clients/fcl-js/discovery.md +[How to Build a Native iOS Dapper]: https://dev.to/theagilemonkeys/how-to-buid-a-native-ios-dapp-that-uses-the-flow-blockchain-as-the-backend-n9k +[Source Code]: https://github.com/jfsagasti/FlowNotes \ No newline at end of file diff --git a/docs/build/guides/mobile/react-native-quickstart.md b/docs/blockchain-development-tutorials/cadence/mobile/react-native-quickstart.md similarity index 60% rename from docs/build/guides/mobile/react-native-quickstart.md rename to docs/blockchain-development-tutorials/cadence/mobile/react-native-quickstart.md index cb1e5b5955..e7dd5e8cb7 100644 --- a/docs/build/guides/mobile/react-native-quickstart.md +++ b/docs/blockchain-development-tutorials/cadence/mobile/react-native-quickstart.md @@ -1,7 +1,7 @@ --- title: React Native Development sidebar_label: React Native Development -sidebar_position: 4 +sidebar_position: 2 description: Learn how to build decentralized applications using React Native and Flow Client Library (FCL). Follow this guide to set up authentication, query the blockchain, and execute transactions in a React Native app. keywords: - React Native @@ -21,26 +21,30 @@ keywords: - mobile development --- +# React Negative Development + **Last Updated:** January 11th 2022 -> **Note**: This page will walk you through a very bare bones project to get started building a web3 dapp using the Flow Client Library (FCL). If you are looking for a clonable repo, Flow community members have created quickstart templates for different JavaScript frameworks (e.g. [Next.js](https://github.com/muttoni/fcl-nextjs-quickstart), [SvelteKit](https://github.com/muttoni/fcl-sveltekit-quickstart), [Nuxt](https://github.com/bluesign/nuxt3-fcl)). You can consult the complete list [here](https://github.com/ph0ph0/Get-The-Flow-Down#fcl). +:::info + +This page will walk you through a very bare bones project to get started building a web3 dapp with the Flow Client Library (FCL). If you want a clonable repo, Flow community members created quickstart templates for different JavaScript frameworks (for example, [Next.js], [SvelteKit], [Nuxt]. You can consult the complete list [here]. -## Introduction +::: -FCL-JS is the easiest way to start building decentralized applications. FCL (aka Flow Client Library) wraps much of the logic you'd have to write yourself on other blockchains. Follow this quick start and you'll have a solid overview of how to build a shippable dapp on Flow. +FCL-JS is the easiest way to start to build decentralized applications. Flow Client Library (FCL) wraps much of the logic you'd have to write yourself on other blockchains. Follow this quick start and you'll have a solid overview of how to build a shippable dapp on Flow. -We're going to make an assumption that you know or understand React; however, the concepts should be easy to understand and transfer to another framework. While this tutorial will make use of Cadence (Flow's smart contract language), you do not need to know it. Instead, we recommend later diving into [learning the Cadence language](https://cadence-lang.org/docs/language/) once you've gotten the core FCL concepts down. +We're going to make an assumption that you know or understand React; however, the concepts should be easy to understand and transfer to another framework. While this tutorial uses Cadence (Flow's smart contract language), you do not need to know it. Instead, we recommend that you later [learn the Cadence language] after you've gotten the core FCL concepts down. -In this tutorial, we are going to interact with an existing smart contract on Flow's testnet known as the [Profile Contract](https://testnet.flowdiver.io/contract/A.ba1132bc08f82fe2.Profile). Using this contract, we will create a new profile and edit the profile information, both via a wallet. In order to do this, the FCL concepts we'll cover are: +In this tutorial, we are going to interact with an current smart contract on Flow's testnet known as the [Profile Contract]. With this contract, we will create a new profile and edit the profile information, both via a wallet. To do this, the FCL concepts we'll cover are: -- [Installation](#installation) -- [Configuration](#configuration) -- [Authentication](#authentication) -- [Querying the Blockchain](#querying-the-blockchain) -- [Initializing an Account](#initializing-an-account) -- [Mutating the Blockchain](#mutating-the-blockchain) +- [Installation] +- [Configuration] +- [Authentication] +- [Query the Blockchain] +- [Initialize an Account] +- [Mutate the Blockchain] -And if you ever have any questions we're always happy to help on [Discord](https://discord.gg/flowblockchain). There are also links at the end of this article for diving deeper into building on Flow. +If you ever have any questions, we're always happy to help on [Discord](https://discord.gg/flowblockchain). There are also links at the end of this article for diving deeper into how to build on Flow. ## Installation @@ -57,19 +61,23 @@ Next, install FCL so we can use it in our app. npm install @onflow/fcl@alpha @react-native-async-storage/async-storage expo-web-browser --save ``` -Now run the app using the following command in your terminal. +Now run the app with the following command in your terminal. ```sh npm run start ``` -You should now see your app running. +Your app is now running. ## Configuration -Now that your app is running, you can configure FCL. Within the main project directory, create a folder called `flow` and create a file called `config.js`. This file will contain configuration information for FCL, such as what Access Node and wallet discovery endpoint to use (e.g. testnet or a local emulator). Add the following contents to the file: +Now that your app is running, you can configure FCL. Within the main project directory, create a folder called `flow` and create a file called `config.js`. This file contains configuration information for FCL, such as what Access Node and wallet discovery endpoint to use (such as testnet or a local emulator). Add the following contents to the file: + +:::info -**Note**: These values are required to use FCL with your app. +These values are required to use FCL with your app. + +::: > **Create file:** `./flow/config.js` @@ -84,16 +92,16 @@ config({ }); ``` -📣 **Tip**: It's recommend to replace these values with environment variables for easy deployments across different environments like development/production or Testnet/Mainnet. +📣 **Tip**: We recommend that you replace these values with environment variables for easy deployments across different environments like development/production or Testnet/Mainnet. -- The `accessNode.api` key specifies the address of a Flow access node. Flow provides these, but in the future access to Flow may be provided by other 3rd parties, through their own access nodes. +- The `accessNode.api` key specifies the address of a Flow access node. Flow provides these, but in the future, third parties ay provide access to Flow through their own access nodes. - `discovery.wallet` and `discovery.authn.endpoint` are addresses that point 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` and `discovery.authn.endpoint`. -> Learn more about [configuring Discovery](../../../tools/clients/fcl-js/discovery.md) or [setting configuration values](../../../tools/clients/fcl-js/packages-docs/fcl/index.md#setting-configuration-values). +> Learn more about [how to configure Discovery] or [how to set configuration values]. -> If you are running a Wallet Discovery locally and want to use it in the React Native app, change `https://fcl-discovery.onflow.org/` to `http://:/` +> If you run a Wallet Discovery locally and want to use it in the React Native app, change `https://fcl-discovery.onflow.org/` to `http://:/` > For Example: -> using local [Wallet Discovery](../../../tools/clients/fcl-js/discovery.md) and local [Dev Wallet](../../../tools/flow-dev-wallet/index.md): +> use local [Wallet Discovery] and local [Dev Wallet]: > > ```javascript ./flow/config.js > import { config } from "@onflow/fcl"; @@ -106,7 +114,7 @@ config({ > }) > ``` -The main screen for React Native apps is located in `./App.js` or in `./App.tsx`. So let's finish configuring our dapp by going in the root directory and importing the config file into the top of our `App.js` file. We'll then swap out the default component in `App.js` to look like this: +The main screen for React Native apps is located in `./App.js` or in `./App.tsx`. So, to finish configuring our dApp, let's go into the root directory and import the config file into the top of our `App.js` file. We'll then swap out the default component in `App.js` to look like this: > **Replace file:** `./App.js` @@ -134,15 +142,15 @@ const styles = StyleSheet.create({ }); ``` -Now we're ready to start talking to Flow! +Now we're ready to talk to Flow! ## Authentication -To authenticate a user, you'll need to render a `ServiceDiscovery` component provided by `fcl-react-native`. Alternatively you can build your own component using `useServiceDiscovery`. +To authenticate a user, you'll need to render a `ServiceDiscovery` component provided by `fcl-react-native`. Alternatively, you can build your own component with `useServiceDiscovery`. -Unauthenticate is as simple as calling `fcl.unauthenticate()`. Once authenticated, FCL sets an object called `fcl.currentUser` which exposes methods for watching changes in user data, signing transactions, and more. +To unauthenticate, you can simply call `fcl.unauthenticate()`. After you're authenticated, FCL sets an object called `fcl.currentUser` which exposes methods to watch for changes in user data, signing transactions, and more. -Let's add in a few components and buttons buttons for sign up/login and also subscribe to changes on the `currentUser`. When the user is updated (which it will be after authentication), we'll set the user state in our component to reflect this. To demonstrate user authenticated sessions, we'll conditionally render a component based on if the user is or is not logged in. +Let's add in a few components and buttons for sign up, login, and to subscribe to changes on the `currentUser`. When the user updates (which happens after authentication), we'll set the user state in our component to reflect this. To demonstrate user authenticated sessions, we'll conditionally render a component based on if the user is or is not logged in. This is what your file should look like now: @@ -192,11 +200,11 @@ const styles = StyleSheet.create({ }); ``` -You should now be able to log in or sign up a user and unauthenticate them. Upon logging in or signing up your users will see a popup where they can choose between wallet providers. Let's select the [Blocto wallet](https://blocto.portto.io/) for this example to create an account. 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. +You can now log in or sign up a user and unauthenticate them. After your users log in or sign up, they'll see a popup where they can choose between wallet providers. Let's select the [Blocto wallet] for this example to create an account. After you authenticate, you'll see the component change and the user's wallet address appear if you've completed this properly. -## Querying the Blockchain +## Query the blockchain -One of the main things you'll often need to do when building a dapp is query the Flow blockchain and the smart contracts deployed on it for data. Since smart contracts will live on both Testnet and Mainnet, let's put the account address where the smart contract lives into the configuration (remember, it's recommended that you change this later to use environment variables). Let's also give it a key of `Profile` and prefix it with `0x` so that the final key is `0xProfile`. The prefix is important because it tells FCL to pull the corresponding addresses needed from the configuration value. +One of the main things you'll often need to do when you build a dApp is query the Flow blockchain and the smart contracts deployed on it for data. Since smart contracts will live on both testnet and mainnet, let's put the account address where the smart contract lives into the configuration (remember, we recommend that you change this later to use environment variables). Let's also give it a key of `Profile` and prefix it with `0x` so that the final key is `0xProfile`. The prefix is important because it tells FCL to pull the corresponding addresses needed from the configuration value. > **Replace file:** `./flow/config.js` @@ -212,16 +220,16 @@ config({ }); ``` -If you want to see the on chain smart contract we'll be speaking with next, you can view the [Profile Contract](https://testnet.flowdiver.io/contract/A.ba1132bc08f82fe2.Profile) source code but again for this tutorial it's not necessary you understand it. +If you want to see the on chain smart contract that we'll speak with next, you can view the [Profile Contract] source code but again, for this tutorial, it's not necessary you understand it. **First, lets query the contract to see what the user's profile name is.** -A few things need to happen in order to do that: +A few things need to happen to do that: 1. We need to import the contract and pass it the user's account address as an argument. -2. Execute the script using `fcl.query`. +2. Execute the script with `fcl.query`. 3. Set the result of the script to the app state in React so we can display the profile name in our browser. -4. Display "No Profile" if one was not found. +4. Display "No Profile" if one wasn't found. Take a look at the new code. We'll explain each new piece as we go. Remember, the cadence code is a separate language from JavaScript used to write smart contracts, so you don't need to spend too much time trying to understand it. (Of course, you're more than welcome to, if you want to!) @@ -294,7 +302,7 @@ const styles = StyleSheet.create({ }); ``` -A few things happened. In our `AuthedState` component, we added a button to send a query for the user's profile name and a `Text` to display the result above it. The corresponding `useState` initialization can be seen at the top of the component. +A few things happened. In our `AuthedState` component, we added a button to send a query for the user's profile name and a `Text` to display the result above it. The corresponding `useState` initialization appears at the top of the component. The other thing we did is build out the actual query inside of `sendQuery` method. Let's take a look at it more closely: @@ -311,21 +319,21 @@ await fcl.query({ }); ``` -Inside the query you'll see we set two things: `cadence` and `args`. Cadence is Flow's smart contract language we mentioned. For this tutorial, when you look at it you just need to notice that it's importing the `Profile` contract from the account we named `0xProfile` earlier in our config file, then also taking an account address, and reading it. That's it until you're ready to [learn more Cadence](https://cadence-lang.org/docs). +Inside the query, you'll see we set two things: `cadence` and `args`. Cadence is Flow's smart contract language we mentioned. For this tutorial, when you look at it, you just need to notice that it imports the `Profile` contract from the account we named `0xProfile` earlier in our config file, then also takies an account address, and reads it. That's it until you're ready to [learn more Cadence]. -In the `args` section, we are simply passing it our user's account address from the user we set in state after authentication and giving it a type of `Address`. For more possible types, [see this reference](../../../tools/clients/fcl-js/packages-docs/types/index.md). +In the `args` section, we simply pass it our user's account address from the user we set in state after authentication and give it a type of `Address`. For more possible types, [see this reference]. -Go ahead and click the "Send Query" button. You should see "No Profile." That's because we haven't initialized the account yet. +Go ahead and click "Send Query". You will see "No Profile." That's because we haven't initialized the account yet. -## Initializing an Account +## Initialize an account -For the Profile contract to store a Profile in a user's account, it does so by initializing what is called a "resource." A resource is an ownable piece of data and functionality that can live in the user's account storage. This paradigm is known is as "resource-oriented-programming", a principle that is core to Cadence and differentiates its ownership model from other smart contract languages, [read more here](https://cadence-lang.org/docs/#intuiting-ownership-with-resources). Cadence makes it so that resources can only exist in one place at any time, they must be deliberately created, cannot be copied, and if desired, must be deliberately destroyed. +For the Profile contract to store a Profile in a user's account, it initializes what is called a "resource." A resource is an ownable piece of data and functionality that can live in the user's account storage. This paradigm is known is as "resource-oriented-programming", a principle that is core to Cadence and differentiates its ownership model from other smart contract languages, [read more here]. Cadence makes it so that resources can only exist in one place at any time, they must be deliberately created, cannot be copied, and if desired, must be deliberately destroyed. -> There's a lot more to resources in Cadence than we'll cover in this guide, so if you'd like to know more, check out [this Cadence intro](https://cadence-lang.org/docs). +> There's a lot more to resources in Cadence than we'll cover in this guide, so if you'd like to know more, check out [this Cadence intro]. -To do this resource initialization on an account, we're going to add another function called `initAccount`. Inside of that function, we're going to add some Cadence code which says, _"Hey, does this account have a profile? If it doesn't, let's add one."_ We do that using something called a "transaction." Transactions occur when you want to change the state of the blockchain, in this case, some data in a resource, in a specific account. And there is a cost (transaction fee) in order to do that; unlike a query. +To do this resource initialization on an account, we'll add another function called `initAccount`. Inside of that function, we'll add some Cadence code which says, _"Hey, does this account have a profile? If it doesn't, let's add one."_ We do that with something called a "transaction." Transactions occur when you want to change the state of the blockchain, in this case, some data in a resource, in a specific account. And there is a cost (transaction fee) in order to do that; unlike a query. -That's where we jump back into FCL code. Instead of `query`, we use `mutate` for transactions. And because there is a cost, we need to add a few fields that tell Flow who is proposing the transaction, who is authorizing it, who is paying for it, and how much they're willing to pay for it. Those fields — not surprisingly — are called: `proposer`, `authorizer`, `payer`, and `limit`. For more information on these signatory roles, check out [this doc](../../basics/transactions.md#signer-roles). +That's where we jump back into FCL code. Instead of `query`, we use `mutate` for transactions. And because there is a cost, we need to add a few fields that tell Flow who proposes the transaction, who authorizes it, who pays for it, and how much they want to pay for it. Those fields — not surprisingly — are called: `proposer`, `authorizer`, `payer`, and `limit`. For more information on these signatory roles, check out this [signer roles] doc. Let's take a look at what our account initialization function looks like: @@ -361,13 +369,13 @@ const initAccount = async () => { }; ``` -You can see the new fields we talked about. You'll also notice `fcl.authz`. That's shorthand for "use the current user to authorize this transaction", (you could also write it as `fcl.currentUser.authorization`). If you want to learn more about transactions and signing transactions, you can [view the docs here](../../basics/transactions.md). For this example, we'll keep it simple with the user being each of these roles. +You can see the new fields we talked about. You'll also notice `fcl.authz`. That's shorthand for "use the current user to authorize this transaction", (you could also write it as `fcl.currentUser.authorization`). If you want to learn more about transactions and signing transactions, you can [view the docs here]. For this example, we'll keep it simple with the user as each of these roles. -You'll also notice we are awaiting a response with our transaction data by using the syntax `fcl.tx(transactionId).onceExecuted()`. This will return when the transaction has been executed by an execution node ("soft-finality"). If you want to wait until the transaction is sealed ("hard-finality"), you can use `onceSealed()` instead. +You'll also notice that we await a response with our transaction data with the syntax `fcl.tx(transactionId).onceExecuted()`. This returns when an execution node completes the transaction ("soft-finality"). If you want to wait until the transaction is sealed ("hard-finality"), you can use `onceSealed()` instead. -To learn more about the transaction lifecycle, check out [this doc](../../basics/transactions.md#transaction-lifecycle). +To learn more about the transaction lifecycle, check out [this doc]. -Now your `index.js` file should look like this (we also added a button for calling the `initAccount` function in the `AuthedState`): +Now your `index.js` file looks like this (we also added a button to call the `initAccount` function in the `AuthedState`): > **Replace file:** `./App.js` @@ -467,13 +475,13 @@ const styles = StyleSheet.create({ }); ``` -Press the "Init Account" button you should see the wallet ask you to approve a transaction. After approving, you will see a transaction response appear in your console (make sure to have that open). It may take a few moments. With the transaction result printed, you can use the `transactionId` to look up the details of the transaction using a [block explorer](https://testnet.flowscan.io/). +Press "Init Account," and the wallet asks you to approve a transaction. After you approve it, you will see a transaction response appear in your console (make sure to have that open). It may take a few moments. With the transaction result printed, you can use the `transactionId` to look up the details of the transaction with a [block explorer]. -## Mutating the Blockchain +## Mutate the blockchain Now that we have the profile initialized, we are going to want to mutate it some more. In this example, we'll use the same smart contract provided to change the profile name. -To do that, we are going to write another transaction that adds some Cadence code which lets us set the name. Everything else looks the same in the following code except for one thing: we'll subscribe to the status changes instead of waiting for it to be sealed after the mutate function returns. +To do that, we will write another transaction that adds some Cadence code which lets us set the name. Everything else looks the same in the following code except for one thing: we'll subscribe to the status changes instead of waiting for it to be sealed after the mutate function returns. It looks like this: @@ -638,24 +646,66 @@ const styles = StyleSheet.create({ }); ``` -Now if you click the "Execute Transaction" button you'll see the statuses update next to "Transaction Status." When you see "4" that means it's sealed! Status code meanings [can be found here](../../../tools/clients/fcl-js/packages-docs/types/index.md). -If you query the account profile again, "Profile Name:" should now display "Flow Developer". +Now if you click "Execute Transaction," you'll see the statuses update next to "Transaction Status." When you see "4" that means it's sealed! Status code meanings [can be found here]. + +If you query the account profile again, "Profile Name:" will now display "Flow Developer". -That's it! You now have a shippable Flow dapp that can auth, query, init accounts, and mutate the chain. This is just the beginning. There is so much more to know. We have a lot more resources to help you build. To dive deeper, here are a few good places for taking the next steps: +That's it! You now have a shippable Flow dapp that can auth, query, init accounts, and mutate the chain. This is just the beginning. There is so much more to know. We have a lot more resources to help you build. To dive deeper, here are a few good places to take the 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.flow.com/post/flow-blockchain-cadence-programming-language-resources-assets) +- [Cadence Playground Tutorials] +- [Cadence Hello World Video] +- [Why Cadence?] **Full Stack NFT Marketplace Example** -- [Beginner Example: CryptoDappy](https://github.com/bebner/crypto-dappy) +- [Beginner Example: CryptoDappy] **More FCL** -- [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) +- [More on Scripts] +- [More on Transactions] +- [User Signatures] +- [Proving Account Ownership] + + + + +[Next.js]: https://github.com/muttoni/fcl-nextjs-quickstart +[SvelteKit]: https://github.com/muttoni/fcl-sveltekit-quickstart +[Nuxt]: https://github.com/bluesign/nuxt3-fcl. +[here]: https://github.com/ph0ph0/Get-The-Flow-Down#fcl +[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.flow.com/post/flow-blockchain-cadence-programming-language-resources-assets +[Beginner Example: CryptoDappy]: https://github.com/bebner/crypto-dappy +[More on Scripts]: ../../../build/tools/clients/fcl-js/scripts.md +[More on Transactions]: ../../../build/tools/clients/fcl-js/transactions.md +[User Signatures]: ../../../build/tools/clients/fcl-js/user-signatures.md +[Proving Account Ownership]: ../../../build/tools/clients/fcl-js/proving-authentication.mdx +[can be found here]: ../../../build/tools/clients/fcl-js/packages-docs/types/index.md +[block explorer]: https://testnet.flowscan.io/ +[this doc]: ../../../build/cadence/basics/transactions.md#transaction-lifecycle +[view the docs here]: ../../../build/cadence/basics/transactions.md +[signer roles]: ../../../build/cadence/basics/transactions.md#signer-roles +[this Cadence intro]: https://cadence-lang.org/docs +[read more here]: https://cadence-lang.org/docs/#intuiting-ownership-with-resources +[learn more Cadence]: https://cadence-lang.org/docs +[see this reference]: ../../../build/tools/clients/fcl-js/packages-docs/types/index.md +[Profile Contract]: https://testnet.flowdiver.io/contract/A.ba1132bc08f82fe2.Profile +[Blocto wallet]: https://blocto.portto.io/ +[Wallet Discovery]: ../../../build/tools/clients/fcl-js/discovery.md +[Dev Wallet]: ../../../build/tools/flow-dev-wallet/index.md +[how to configure Discovery]: ../../../build/tools/clients/fcl-js/discovery.md +[how to set configuration values]: ../../../build/tools/clients/fcl-js/packages-docs/fcl/index.md#setting-configuration-values +[learn the Cadence language]: https://cadence-lang.org/docs/language/ +[Profile Contract]: https://testnet.flowdiver.io/contract/A.ba1132bc08f82fe2.Profile +[Installation]: #installation +[Configuration]: #configuration +[Authentication]: #authentication +[Query the Blockchain]: #query-the-blockchain +[Initialize an Account]: #initialize-an-account +[Mutate the Blockchain]: #mutate-the-blockchain +[Discord]: https://discord.gg/flowblockchain +[create-expo-app]: https://docs.expo.dev/get-started/create-a-project/ diff --git a/docs/build/guides/mobile/walletless-pwa.md b/docs/blockchain-development-tutorials/cadence/mobile/walletless-pwa.md similarity index 59% rename from docs/build/guides/mobile/walletless-pwa.md rename to docs/blockchain-development-tutorials/cadence/mobile/walletless-pwa.md index 6529ce2a3e..ca183efea8 100644 --- a/docs/build/guides/mobile/walletless-pwa.md +++ b/docs/blockchain-development-tutorials/cadence/mobile/walletless-pwa.md @@ -1,7 +1,7 @@ --- title: Build a Walletless Mobile App (PWA) sidebar_label: Build a Walletless Mobile App (PWA) -sidebar_position: 2 +sidebar_position: 3 description: Learn how to create a Progressive Web App (PWA) on Flow blockchain with walletless onboarding. Build accessible mobile dApps using Magic integration, account linking, and hybrid custody features. keywords: - PWA @@ -21,31 +21,31 @@ keywords: - user experience --- -# Overview +# Build a Walletless Mobile App (PWA) -In this tutorial, we delve into the intricacies of crafting an accessible Progressive Web App (PWA) on the Flow blockchain, tackling the challenge of mobile mainstream accessibility in web3. Recognizing the complexity of current onboarding processes, we will guide you through a streamlined approach, featuring a seamless walletless mobile login to alleviate the often daunting task for new users. +In this tutorial, we delve into the intricacies of how to craft an accessible Progressive Web App (PWA) on the Flow blockchain, and tackle the challenge of mobile mainstream accessibility in web3. We recognize the complexity of current onboarding processes, so we'll guide you through a streamlined approach, which features a seamless walletless mobile login to alleviate the often daunting task for new users. -### Understanding Progressive Web Apps (PWAs) +### Understand PWAs -Progressive Web Apps (PWAs) have garnered attention recently, with platforms like [friend.tech](http://friend.tech/) leading the way in popularity. PWAs blur the lines between web pages and mobile applications, offering an immersive, app-like experience directly from your browser. You can easily add a shortcut to your home screen, and the PWA operates just like a native application would. Beyond these capabilities, PWAs also boast offline functionality and support for push notifications, among many [other features](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps). +PWAs have garnered attention recently, and platforms like [friend.tech] lead the way in popularity. PWAs blur the lines between web pages and mobile applications, and offer an immersive, app-like experience directly from your browser. You can easily add a shortcut to your home screen, and the PWA operates just like a native application would. Beyond these capabilities, PWAs also boast offline functionality and support for push notifications, among many [other features]. -### ****Exploring Walletless Onboarding**** +### ****Explore walletless onboarding**** -Walletless onboarding is a groundbreaking feature that enables users to securely interact with decentralized applications (dApps) in a matter of seconds, all without the traditional necessity of creating a blockchain wallet. This method effectively simplifies the user experience, abstracting the complexities of blockchain technology to facilitate swift and straightforward app access. For a deeper dive into walletless onboarding and its integration with Flow, feel free to explore the following resource: [Flow Magic Integration](https://flow.com/post/flow-magic-integration). +Walletless onboarding is a groundbreaking feature that allows users to securely interact with decentralized applications (dApps) in a matter of seconds, all without the traditional need to create a blockchain wallet. This method effectively simplifies the user experience; it abstracts the complexities of blockchain technology to facilitate swift and straightforward app access. For a deeper dive into walletless onboarding and its integration with Flow, feel free to explore the following resource: [Flow Magic Integration]. -# Detailed Steps +# Detailed steps -To effectively follow this tutorial, the developer requires a few essential libraries and integrations. Additionally, there is a ready-made flow scaffold called [FCL PWA](https://github.com/bshahid331/flow-pwa-scaffold) that contains the completed tutorial code, providing a solid foundation for you to build your Progressive Web App (PWA)! +To effectively follow this tutorial, the developer requires a few essential libraries and integrations. Additionally, there is a ready-made flow scaffold called [FCL PWA] that contains the completed tutorial code, providing a solid foundation for you to build your PWA! ## **Dependencies** -1. **Magic Account**: Start by setting up an app on magic.link, during which you will obtain an API key crucial for further steps. -2. **Magic SDK**: Essential for integrating Magic's functionality in your project, and can be found [here](https://www.npmjs.com/package/magic-sdk). -3. **Magic Flow SDK**: This SDK enables Magic's integration with Flow. You can install it from [this link](https://www.npmjs.com/package/@magic-ext/flow/v/13.3.0). -4. **Flow Client Library ([FCL](https://developers.flow.com/tooling/fcl-js))**: As the JavaScript SDK for the Flow blockchain, FCL allows developers to create applications that seamlessly interact with the Flow blockchain and its smart contracts. -5. **React**: Our project will be built using the React framework. +1. **Magic Account**: To start, set up an app on magic.link, where you'll obtain an API key crucial for further steps. +2. **Magic SDK**: Essential to integrate Magic's functionality in your project, and you can find it [here]. +3. **Magic Flow SDK**: This SDK allows Magic's integration with Flow. You can install it from [this link]. +4. **Flow Client Library ([FCL])**: As the JavaScript SDK for the Flow blockchain, FCL allows developers to create applications that seamlessly interact with the Flow blockchain and its smart contracts. +5. **React**: We'll build our project with the React framework. -### ****Setting up PWA and Testing Locally**** +### ****Set up up PWA and testing locally**** Initiate the creation of a new React app, opting for the PWA template with the following command: @@ -55,19 +55,19 @@ npx create-react-app name-of-our-PWA-app --template cra-template-pwa Ensure that **`serviceWorkerRegistration.register()`** in **`index.js`** is appropriately configured to support offline capabilities of your PWA. -Proceed to build your application using your preferred build tool. In this example, we will use Yarn: +Proceed to build your application with your preferred build tool. In this example, we will use Yarn: ```bash yarn run build ``` -Following the build, you can serve your application locally using: +After the build, you can serve your application locally with: ```bash npx serve -s build ``` -To thoroughly test your PWA, especially on a mobile device, it's highly recommended to use a tool like **`ngrok`**. Start **`ngrok`** and point it to the local port your application is running on: +To thoroughly test your PWA, especially on a mobile device, we strongly recommend that you use a tool like **`ngrok`**. Start **`ngrok`** and point it to the local port on which your application runs: ```bash ngrok http 3000 @@ -75,10 +75,9 @@ ngrok http 3000 Grab the generated link, and you can now access and test your PWA directly on your mobile device! - You can now grab the link and go to it on your mobile device to test the PWA! -### Integrating with Magic +### Integrate with Magic Proceed to install the Magic-related dependencies in your project. Ensure you add your Magic app's key as an environment variable for secure access: @@ -87,7 +86,7 @@ yarn add magic-sdk @magic-ext/flow @onflow/fcl ``` -Let's create a helper file, **`magic.js`**, to manage our Magic extension setup. Ensure that your environment variable with the Magic API key is correctly set before proceeding. +Let's create a helper file, **`magic.js`**, to manage our Magic extension setup. Ensure that your environment variable with the Magic API key is correctly set before you proceed. ```js import { Magic } from "magic-sdk"; @@ -105,15 +104,15 @@ const magic = new Magic(process.env.REACT_APP_MAGIC_KEY, { export default magic; ``` -Anytime you need to interface with chain you will use this magic instance. +Anytime you need to interface with chain, you will use this magic instance. -### ****React Context and Provider for User Data**** +### ****React context and provider for user data**** **`currentUserContext.js`** -This file creates a React context that will be used to share the current user's data across your application. +This file creates a React context that you'll use to share the current user's data across your application. -**React Context**: It is created using **`React.createContext()`** which provides a way to pass data through the component tree without having to pass props down manually at every level. +**React Context**: It is created with **`React.createContext()`** which provides a way to pass data through the component tree without the need to pass props down manually at every level. ```js import React from "react"; @@ -125,12 +124,12 @@ export default CurrentUserContext; **`currentUserProvider.js`** -This file defines a React provider component that uses the context created above. This provider component will wrap around your application's components, allowing them to access the current user's data. +This file defines a React provider component that uses the context created above. This provider component will wrap around your application's components, which allows them to access the current user's data. -- **useState**: To create state variables for storing the current user's data and the loading status. -- **useEffect**: To fetch the user's data from Magic when the component mounts. -- **magic.user.isLoggedIn**: Checks if a user is logged in. -- **magic.user.getMetadata**: Fetches the user's metadata. +- **useState**: creates state variables to store the current user's data and the loading status. +- **useEffect**: fetches the user's data from Magic when the component mounts. +- **magic.user.isLoggedIn**: checks if a user is logged in. +- **magic.user.getMetadata**: fetches the user's metadata. ```js import React, { useState, useEffect } from "react"; @@ -172,12 +171,12 @@ const CurrentUserProvider = ({ children }) => { export default CurrentUserProvider; ``` -### **Logging in the User** +### **Log in the user** -This part shows how to log in a user using Magic's SMS authentication. +This part shows how to log in a user with Magic's SMS authentication. -- **magic.auth.loginWithSMS**: A function provided by Magic to authenticate users using their phone number. -- **setCurrentUser**: Updates the user's data in the context. +- **magic.auth.loginWithSMS**: A function that Magic provides to authenticate users with their phone number. +- **setCurrentUser**: updates the user's data in the context. ```js import magic from "./magic"; @@ -194,12 +193,12 @@ const login = async (phoneNumber) => { }; ``` -### **Scripts/Transactions with Flow** +### **Scripts and transactions with Flow** -This example shows how to interact with the Flow blockchain using FCL and Magic for authorization. +This example shows how to interact with the Flow blockchain with FCL and Magic for authorization. -- **fcl.send**: A function provided by FCL to send transactions or scripts to the Flow blockchain. -- **AUTHORIZATION_FUNCTION**: The authorization function provided by Magic for signing transactions. +- **fcl.send**: A function that FCL provides to send transactions or scripts to the Flow blockchain. +- **AUTHORIZATION_FUNCTION**: The authorization function that Magic provides to sign transactions. ```js import * as fcl from "@onflow/fcl"; @@ -232,13 +231,13 @@ const transactionExample = async (currentUser) => { ### ****Account Linking with Flow**** -Now we can unlock the real power of Flow. Lets say you have another Flow account and you want to link the "magic" account as a child account so that you can take full custody of whatever is in the magic account you can do this via Hybird Custody. +Now we can unlock the real power of Flow. Lets say you have another Flow account and you want to link the "magic" account as a child account so that you can take full custody of whatever is in the magic account. You can do this via Hybird Custody. You can view the hybrid custody repo and contracts here: https://github.com/onflow/hybrid-custody -We will maintain two accounts within the app. The child(magic) account form earlier and new non custodial FCL flow account. I won't go over how to log in with FCL here and use it but you can do the normal process to obtain the parent account. +We will maintain two accounts within the app. The child(magic) account from earlier and new non custodial FCL flow account. We won't go over how to log in with FCL here and use it, but you can do the normal process to obtain the parent account. -One you have the parent account and child(magic) account logged in you can link the account by using the following transaction. +After you log in to the parent account and child(magic) account, you can link the account with the following transaction: ```cadence #allowAccountLinking @@ -315,11 +314,11 @@ transaction(parentFilterAddress: Address?, childAccountFactoryAddress: Address, } ``` -:::note -For the sake of this example, well use some pre defined factory and filter implementations. You can find them on the repo but on testnet we can use 0x1055970ee34ef4dc and 0xe2664be06bb0fe62 for the factory and filter address respectively. 0x1055970ee34ef4dc provides NFT capabilities and 0xe2664be06bb0fe62 which is the AllowAllFilter. These generalized implementations likely cover most use cases, but you'll want to weigh the decision to use them according to your risk tolerance and specific scenario +:::info +For the sake of this example, well use some pre defined factory and filter implementations. You can find them on the repo, but on testnet we can use 0x1055970ee34ef4dc and 0xe2664be06bb0fe62 for the factory and filter address respectively. 0x1055970ee34ef4dc provides NFT capabilities and 0xe2664be06bb0fe62 which is the AllowAllFilter. These generalized implementations likely cover most use cases, but you'll want to weigh the decision to use them according to your risk tolerance and specific scenario. ::: -Now, for viewing all parent accounts linked to a child account and removing a linked account, you can follow similar patterns, using Cadence scripts and transactions as required. +Now, to view all parent accounts linked to a child account and remove a linked account, you can follow similar patterns, and use Cadence scripts and transactions as required. ```cadence import HybridCustody from 0x294e44e1ec6993c6 @@ -336,7 +335,7 @@ access(all) fun main(child: Address): [Address] { } ``` -and finally to remove a linked account you can run the following cadence transaction +Finally, to remove a linked account, you can run the following cadence transaction: ```js await fcl.send([ @@ -365,62 +364,74 @@ await fcl.send([ ]); ``` -# Video Guide +# Video guide -[![Video Title](resources/pwa_youtube_thumbnail.png)](https://www.youtube.com/watch?v=1ZmvfBFdCxY "Video Title") +[![Video Title](./imgs/pwa_youtube_thumbnail.png)](https://www.youtube.com/watch?v=1ZmvfBFdCxY "Video Title") -# **Sample Flow PWA: Balloon Inflation Game** +# **Sample Flow PWA: balloon inflation game** -## **Game Overview** +## **Game overview** This PWA game revolves around inflating a virtual balloon, with a twist! The players engage with the balloon, witnessing its growth and color transformation, all while being cautious not to pop it. The ultimate goal is to mint the balloon's state as an NFT to commemorate their achievement. -You can view the game [here](https://flow-inflation.vercel.app/). Visit this on your mobile device(for iOS use Safari). +You can view the game [here]. Visit this on your mobile device(for iOS use Safari). The full code for this game can be found here: https://github.com/onflow/inflation -![pwa_prompt](resources/pwa_prompt.jpeg) +![pwa_prompt](./imgs/pwa_prompt.jpeg) -[![pwa_mint_balloon_thumbnail](resources/pwa_mint_balloon_thumbnail.png)](https://drive.google.com/file/d/15ojzoRTtTN6gQXVN3STMa3-JOZ0b6frw/view) +[![pwa_mint_balloon_thumbnail](./imgs/pwa_mint_balloon_thumbnail.png)](https://drive.google.com/file/d/15ojzoRTtTN6gQXVN3STMa3-JOZ0b6frw/view) -[![pwa_link_account_thumbnail](resources/pwa_link_account_thumbnail.png)](https://drive.google.com/file/d/1FZzoLmd5LLGBbO4enzk8LpV1Uwbgc-Ry/view) +[![pwa_link_account_thumbnail](./imgs/pwa_link_account_thumbnail.png)](https://drive.google.com/file/d/1FZzoLmd5LLGBbO4enzk8LpV1Uwbgc-Ry/view) -### **Key Game Features:** +### **Key game features:** -1. **Balloon Inflation**: +1. **Balloon inflation**: - As the player inflates the balloon, it expands and changes color. - - A hidden inflation threshold is set; surpassing this limit will result in the balloon bursting. -2. **NFT Minting**: - - Satisfied with their balloon's size, players have the option to mint it into an NFT, creating a permanent token of their accomplishment. -3. **Balloon Collection**: + - A hidden inflation threshold is set. If a player exceeds this limit, the ballon bursts. +2. **NFT minting**: + - Satisfied with their balloon's size, players have the option to mint it into an NFT, which creates a permanent token of their accomplishment. +3. **Balloon collection**: - Post-minting, players can view and showcase their collection of balloon NFTs. -4. **Account Linking and Custody**: +4. **Account linking and custody**: - Players initially interact with the game in a walletless fashion via Magic. - When ready to claim full ownership of their balloon NFTs, they can link their Magic account to a non-custodial FCL wallet of their choice. ## **Integration with Flow and Magic** -The entire game is crafted upon the previously discussed setup, ensuring a seamless and user-friendly experience. +The entire game is crafted upon the previously discussed setup, which ensures a seamless and user-friendly experience. -### **Playing the Game:** +### **Play the game:** -- **Walletless Interaction**: Users can jump right into the game, inflating the balloon and enjoying the gameplay without any blockchain wallet setup. -- **Inflation and Visuals**: The balloon's size and color change in real-time, providing instant visual feedback to the player. +- **Walletless interaction**: Users can jump right into the game, inflate the balloon and enjoy the gameplay without any blockchain wallet setup. +- **Inflation and visuals**: The balloon's size and color change in real-time, which provides instant visual feedback to the player. -### **Minting and Viewing NFTs:** +### **Mint and view NFTs:** -- **Magic Login for Minting**: To mint their balloon as an NFT, players log in using Magic, embracing a walletless experience. -- **Viewing NFT Collection**: Post-minting, players can easily access and view their collection of balloon NFTs. +- **Magic login for minting**: To mint their balloon as an NFT, players log in with Magic and embrace a walletless experience. +- **View NFT Collection**: Post-minting, players can easily access and view their collection of balloon NFTs. -### **Taking Custody with Account Linking:** +### **Take custody with Account Linking:** -- **Secure Custody**: Players wishing to secure their balloon NFTs can utilize Account Linking to connect their Magic account to their personal non-custodial FCL wallet. -- **Full Ownership**: This step ensures that players have complete control and custody over their digital assets. +- **Secure custody**: Players who want to secure their balloon NFTs can use Account Linking to connect their Magic account to their personal non-custodial FCL wallet. +- **Full ownership**: This step ensures that players have complete control and custody over their digital assets. ## **Conclusion** -The balloon inflation game stands as a testament to the seamless integration of Flow, Magic, and PWA technology, creating a user-friendly blockchain game that is accessible, engaging, and secure. Players can enjoy the game, mint NFTs, and take full ownership of their digital assets with ease and convenience. \ No newline at end of file +The balloon inflation game stands as a testament to the seamless integration of Flow, Magic, and PWA technology, and creates a user-friendly blockchain game that is accessible, engaging, and secure. Players can enjoy the game, mint NFTs, and take full ownership of their digital assets with ease and convenience. + + + +[here]: https://flow-inflation.vercel.app/ +[Flow Magic Integration]: https://flow.com/post/flow-magic-integration +[FCL PWA]: https://github.com/bshahid331/flow-pwa-scaffold +[here]: https://www.npmjs.com/package/magic-sdk). +[this link]: https://www.npmjs.com/package/@magic-ext/flow/v/13.3.0 +[FCL]: https://developers.flow.com/tooling/fcl-js +[Flow Magic Integration]: https://flow.com/post/flow-magic-integration +[friend.tech]: http://friend.tech/ +[other features]: https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps). \ No newline at end of file diff --git a/docs/tutorials/cross-vm-apps/add-to-wagmi.md b/docs/blockchain-development-tutorials/cross-vm-apps/add-to-wagmi.md similarity index 81% rename from docs/tutorials/cross-vm-apps/add-to-wagmi.md rename to docs/blockchain-development-tutorials/cross-vm-apps/add-to-wagmi.md index 784ae98d19..42e3e37b58 100644 --- a/docs/tutorials/cross-vm-apps/add-to-wagmi.md +++ b/docs/blockchain-development-tutorials/cross-vm-apps/add-to-wagmi.md @@ -1,7 +1,7 @@ --- title: Update Existing wagmi App description: Learn how to integrate Flow Cadence with your existing wagmi/RainbowKit app to enable batch transactions and other Cadence features. -sidebar_position: 1 +sidebar_position: 2 keywords: - hybrid apps - cross-vm apps @@ -21,11 +21,11 @@ keywords: - supercharge your EVM app with Cadence --- -# Add Flow Cadence to Your wagmi App +# Add Flow Cadence to your wagmi app -This tutorial demonstrates how to enhance your existing wagmi/RainbowKit application with Flow Cadence capabilities. By integrating the Flow Client Library (FCL) with your EVM stack, you can unlock powerful features like batch transactions with a single signature. +This tutorial demonstrates how to enhance your current wagmi/RainbowKit application with Flow Cadence capabilities. When you integrate the Flow Client Library (FCL) with your EVM stack, you can unlock powerful features like batch transactions with a single signature. -## Video Overview +## Video overview
-### Funding the COA +### Fund the COA -Next, we fund the COA with enough FLOW to cover the mint cost. This is done by withdrawing FLOW from the signer's -FlowToken Vault and depositing it into the COA. +Next, we fund the COA with enough FLOW to cover the mint cost. To do this, withdraw FLOW from the signer's FlowToken Vault and deposit it into the COA. ```cadence /* Fund COA with cost of mint */ @@ -488,8 +421,8 @@ let fundingVault <- sourceVault.withdraw(amount: self.mintCost) as! @FlowToken.V self.coa.deposit(from: <-fundingVault) ``` -Taking a look at the full transaction, we can see an explicit check that the COA has enough FLOW to cover the mint cost -before proceeding into the transaction's `execute` block. +When we take a look at the full transaction, we can see an explicit check that the COA has enough FLOW to cover the mint cost +before it proceedes into the transaction's `execute` block. ```cadence pre { @@ -499,22 +432,17 @@ pre { } ``` -This isn't absolutely necessary as successive steps would fail on this condition, but helps provide enhanced error -messages in the event of insufficient funds. +This isn't absolutely necessary as successive steps would fail on this condition, but helps provide enhanced error messages in the event of insufficient funds. -You can run the above block in a transaction here which will move 1 FLOW from your account's Cadence FLOW balance to -your account's EVM balance, depositing it directly to your pre-configured COA: [`fund_coa.cdc`] +You can run the above block in a transaction here which will move one FLOW from your account's Cadence FLOW balance to your account's EVM balance and deposit it directly to your pre-configured COA: [`fund_coa.cdc`] -After running the linked transaction, you can check your COA's FLOW balance with the script below, just enter your COA's -EVM address (which you can get from the previous script). The resulting balance should be 1.0 (unless you've funded your -COA prior to this walkthrough). +After you run the linked transaction, you can check your COA's FLOW balance with the script below, just enter your COA's EVM address (which you can get from the previous script). The balance should be 1.0 (unless you've funded your COA prior to this walkthrough). -### Setting our EVM Contract Targets +### Setting our EVM contract argets -The last step in our transaction's `prepare` block is to deserialize the provided WFLOW and ERC721 contract addresses -from hex strings to EVM addresses. +The last step in our transaction's `prepare` block is to deserialize the provided WFLOW and ERC721 contract addresses from hex strings to EVM addresses. ```cadence /* Set the WFLOW contract address */ @@ -529,11 +457,9 @@ self.wflowAddress = EVM.addressFromString(wflowAddressHex) self.erc721Address = EVM.addressFromString(maybeMintERC721AddressHex) ``` -### Wrapping FLOW as WFLOW +### Wrap FLOW as WFLOW -Next, we're on to the first EVM interaction - wrapping FLOW as WFLOW. This is done by encoding the `deposit()` function -call and setting the call value to the mint cost. The COA then calls the WFLOW contract with the encoded calldata, gas -limit, and value. +Next, we're on to the first EVM interaction - to wrap FLOW as WFLOW. To do this, encode the `deposit()` function call and set the call value to the mint cost. The COA then calls the WFLOW contract with the encoded calldata, gas limit, and value. ```cadence /* Wrap FLOW in EVM as WFLOW */ @@ -555,45 +481,37 @@ assert( ) ``` -Setting the value of the call transmits FLOW along with the call to the contract, accessible in solidity as `msg.value`. +When you set the value of the call, it transmits FLOW along with the call to the contract, accessible in solidity as `msg.value`. :::tip You'll notice a general pattern among all EVM calls in this transaction: -1. Encoding the calldata -2. Calling the contract -3. Asserting the call was successful +1. Encodes the calldata. +2. Calls the contract. +3. Asserts the call was successful. -Here we're just interested in a successful call, but we could access return data if it were expected and relevant for -our Cadence transaction. This returned data is accessible from the `data` field on the `EVM.Result` object returned from -`coa.call(...)`. This data would then be decoded using `EVM.decodeABI(...)`. More on this in later guides. +Here we're just interested in a successful call, but we could access return data if it were expected and relevant for our Cadence transaction. This returned data is accessible from the `data` field on the `EVM.Result` object returned from `coa.call(...)`. This data would then be decoded with `EVM.decodeABI(...)`. More on this in later guides. ::: You can run the above code as a transaction here: [`wrap_flow.cdc`] -After running the transaction, your COA should have a WFLOW balance of 1.0 WFLOW. Confirm your WFLOW balance by running -the script below, providing your Flow account address, the WFLOW address of `0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e` -and your COA's EVM address (retrieved from a previous script): +After you run the transaction, your COA should have a WFLOW balance of 1.0 WFLOW. To confirm your WFLOW balance, run the script below, and provide your Flow account address, the WFLOW address of `0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e` and your COA's EVM address (retrieved from a previous script): -Since Solidity does not support decimal precision, the returned balance will look like a large number. In the case of -WFLOW, we can recover the decimals by shifting the decimal place 18 digits to the left. Your account should have `1` -WFLOW or `1000000000000000000` as returned. +Since Solidity does not support decimal precision, the returned balance will look like a large number. In the case of WFLOW, to recover the decimals, shift the decimal place 18 digits to the left. Your account should have `1` WFLOW or `1000000000000000000` as returned. :::warning -Note that the number of places to shift varies by ERC20 implementation -- the default value is 18, but it's not safe to -assume this value. You can check a token's decimal places by calling `ERC20.decimals()(uint8)`. +The number of places to shift varies by ERC20 implementation -- the default value is 18, but it's not safe to assume this value. To check a token's decimal places, call `ERC20.decimals()(uint8)`. ::: -### Approving the ERC721 Contract +### Approve the ERC721 contract -Once the FLOW is wrapped as WFLOW, we approve the ERC721 contract to move the mint amount. This is done by encoding the -`approve(address,uint256)` calldata and calling the WFLOW contract with the encoded calldata. +After the FLOW is wrapped as WFLOW, we approve the ERC721 contract to move the mint amount. To do this, encode the `approve(address,uint256)` calldata and call the WFLOW contract with the encoded calldata. ```cadence /* Approve the ERC721 address for the mint amount */ @@ -616,23 +534,19 @@ assert( ) ``` -You can run this approval using the transaction, passing the WFLOW address of -`0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e` and MaybeMintERC721 address of `0x2E2Ed0Cfd3AD2f1d34481277b3204d807Ca2F8c2` +You can run this approval with the transaction. Pass the WFLOW address of `0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e` and MaybeMintERC721 address of `0x2E2Ed0Cfd3AD2f1d34481277b3204d807Ca2F8c2` : [`approve_maybe_mint_erc721.cdc`] -The linked transaction will perform the approval step, authorizing the ERC721 to transfer WFLOW to cover the mint cost -when `mint()` is called. Confirm the contract allowance by running the script below. Pass your Flow address, WFLOW +The linked transaction will perform the approval step, which authorizes the ERC721 to transfer WFLOW to cover the mint cost when `mint()` is called. To confirm the contract allowance, run the script below. Pass your Flow address, WFLOW address, ERC721 address, and your COA's EVM address. -The result is the amount of your WFLOW balance the ERC721 is allowed to transfer, which after the transaction should be -`1` WFLOW, or `1000000000000000000` as returned. +The result is the amount of your WFLOW balance the ERC721 is allowed to transfer, which after the transaction should be `1` WFLOW, or `1000000000000000000` as returned. -### Minting the ERC721 Token +### Mint the ERC721 token -Finally, we attempt to mint the ERC721 token. This is done by encoding the `mint()` calldata and calling the ERC721 -contract with the encoded calldata. If the mint fails, the entire transaction is reverted. +Finally, we attempt to mint the ERC721 token. To do this, encode the `mint()` calldata and call the ERC721 contract with the encoded calldata. If the mint fails, the entire transaction is reverted. ```cadence /* Attempt to mint ERC721 */ @@ -653,55 +567,42 @@ assert( ) ``` -You can run the minting transaction here, passing the ERC721 address of `0x2E2Ed0Cfd3AD2f1d34481277b3204d807Ca2F8c2`: +You can run the minting transaction here. Pass the ERC721 address of `0x2E2Ed0Cfd3AD2f1d34481277b3204d807Ca2F8c2`: [`mint.cdc`] -Again, this transaction may fail. But if you executed all the prior stepwise transactions according to the walkthrough, -you can try again until the mint succeeds. Recall that you can view your transaction details using Cadence [Flowscan] -which will also let you view the embedded EVM transactions in the `EVM` tab. Try it out, and see if you can figure out -how to get your minted NFT's URI with the script below. +Again, this transaction may fail. But if you executed all the prior stepwise transactions according to the walkthrough, you can try again until the mint succeeds. Recall that you can view your transaction details with Cadence [Flowscan] which will also let you view the embedded EVM transactions in the `EVM` tab. Try it out, and see if you can figure out how to get your minted NFT's URI with the script below. ### Recap -All of the stepwise transactions you just executed are compiled in the first Cadence transaction we ran. Hopefully, -going through the process step by step illuminates the power and flexibility of Cadence, allowing you to write -transactions as simple or as complex as you want. +All of the stepwise transactions you just executed are compiled in the first Cadence transaction we ran. Hopefully, going through the process step by step illuminates the power and flexibility of Cadence and allows you to write transactions as simple or as complex as you want. -While lengthy transactions can be intimidating and even a bit verbose at times, the flexibility afforded by the language -means you are only limited by your imagination. Cadence transactions allow you to support the most streamlined of -experiences, incorporating as many contracts as needed to support your use case. +While lengthy transactions can be intimidating and even a bit verbose at times, the flexibility afforded by the language means you are only limited by your imagination. Cadence transactions allow you to support the most streamlined of experiences and incorporate as many contracts as needed to support your use case. ## Conclusion -In this guide, we've demonstrated how to batch EVM transactions using Cadence, allowing you to conditionally execute -multiple EVM transactions in a single Cadence transaction. While this guide focused on relatively simple EVM operations, -the principles can be applied to much more complex and interesting applications. +In this guide, we've demonstrated how to batch EVM transactions using Cadence, which allows you to conditionally execute multiple EVM transactions in a single Cadence transaction. While this guide focused on relatively simple EVM operations, the principles can be applied to much more complex and interesting applications. In the process, you learned how to: -- Read and write from smart contract functions on EVM Flowscan -- Run a Cadence transaction from the browser using [Flow Runner] -- Execute batched EVM transactions via a COA in a Cadence transaction -- Condition final transaction execution on success of all EVM transactions -- Inspect multiple EVM transactions embedded in a Cadence transaction with [Flowscan] block explorer +- Read and write from smart contract functions on EVM Flowscan. +- Run a Cadence transaction from the browser with [Flow Runner]. +- Execute batched EVM transactions via a COA in a Cadence transaction. +- Condition final transaction execution on success of all EVM transactions. +- Inspect multiple EVM transactions embedded in a Cadence transaction with [Flowscan] block explorer. -The biggest takeaway here isn't the specific actions taken in this walkthrough, but the overarching concept that you can -use **Cadence as an orchestration layer** to **extend existing EVM contracts**, creating unique user experiences with -the power **to differentiate your Web3 application**. +The biggest takeaway here isn't the specific actions taken in this walkthrough, but the overarching concept that you can use **Cadence as an orchestration layer** to **extend existing EVM contracts**, which allows you to create unique user experiences with the power **to differentiate your Web3 application**. -With these basics in hand, you're ready to start building more complex applications that leverage the power of Cadence -and the Flow blockchain. How will you use these features to build Web3's next killer app? +With these basics in hand, you're ready to build more complex applications that leverage the power of Cadence and the Flow blockchain. How will you use these features to build Web3's next killer app? -## Further Reading +## Further reading -Now that you've experienced the power of Cadence and EVM interactions firsthand, we recommend checking out the following -guides to deepen your understanding: +Now that you've experienced the power of Cadence and EVM interactions firsthand, we recommend you check out the following guides to deepen your understanding: -- [How Flow EVM Works] - Learn more about the Flow EVM and how it differs from traditional EVM platforms -- [Interacting with COAs] - Get a fuller picture of how Cadence interacts with EVM contracts via Cadence-owned accounts -- [Cadence Transactions] - Learn more about the Cadence transaction model +- [How Flow EVM Works] - Learn more about the Flow EVM and how it differs from traditional EVM platforms. +- [Interacting with COAs] - Get a fuller picture of how Cadence interacts with EVM contracts via Cadence-owned accounts. +- [Cadence Transactions] - Learn more about the Cadence transaction model. Ready to level up your Cadence skills? Take a look at [these Cadence tutorials]. @@ -728,9 +629,9 @@ Ready to level up your Cadence skills? Take a look at [these Cadence tutorials]. [Flowscan Cadence]: https://testnet.flowscan.io/ [resource]: https://cadence-lang.org/docs/solidity-to-cadence#resources [entitlement]: https://cadence-lang.org/docs/language/access-control#entitlements -[How Flow EVM Works]: ../../evm/how-it-works.md +[How Flow EVM Works]: ../../build/evm/how-it-works.md [Interacting with COAs]: ./interacting-with-coa.md -[Cadence Transactions]: ../../build/basics/transactions.md +[Cadence Transactions]: ../../build/cadence/basics/transactions.md [these Cadence tutorials]: https://cadence-lang.org/docs/tutorial/first-steps [`setup_coa.cdc`]: https://run.dnz.dev/snippet/4ec75e1f4165fa05 [`fund_coa.cdc`]: https://run.dnz.dev/snippet/0e7370601bd9123b diff --git a/docs/tutorials/cross-vm-apps/direct-calls.md b/docs/blockchain-development-tutorials/cross-vm-apps/direct-calls.md similarity index 56% rename from docs/tutorials/cross-vm-apps/direct-calls.md rename to docs/blockchain-development-tutorials/cross-vm-apps/direct-calls.md index e127d59348..07398e7ac1 100644 --- a/docs/tutorials/cross-vm-apps/direct-calls.md +++ b/docs/blockchain-development-tutorials/cross-vm-apps/direct-calls.md @@ -1,14 +1,16 @@ --- title: Direct Calls from Cadence to Flow EVM sidebar_label: Direct Calls to Flow EVM -sidebar_position: 5 +sidebar_position: 4 --- -Direct calls from Cadence to Flow EVM are essential for enabling Cadence smart contracts to interact seamlessly with the EVM environment hosted on the Flow blockchain. These calls facilitate a range of functionalities including state queries and transaction initiations, allowing Cadence contracts to leverage EVM-based tools and assets. +# Direct Calls from Cadence to Flow EVM -## Making Direct Calls +Direct calls from Cadence to Flow EVM are essential to allow Cadence smart contracts to interact seamlessly with the EVM environment hosted on the Flow blockchain. These calls facilitate a range of functionalities including state queries and transaction initiations, allowing Cadence contracts to leverage EVM-based tools and assets. -### Accessing Flow EVM +## Make direct calls + +### Access Flow EVM To interact with Flow EVM, Cadence contracts must first import `EVM` from its service address: @@ -16,15 +18,15 @@ To interact with Flow EVM, Cadence contracts must first import `EVM` from its se import EVM from ``` -Next, create an `EVMAddress` with a sequence of 20 bytes representing the EVM address: +Next, create an `EVMAddress` with a sequence of 20 bytes that represents the EVM address: ```js let addr = EVM.EVMAddress(bytes: bytes) ``` -Once you have access to an `EVMAddress`, you can query various pieces of state information such as: +After you can access an `EVMAddress`, you can query various pieces of state information such as: -- `balance() EVM.Balance` provides the balance of the address. It returns a balance object rather than a basic type to avoid errors when converting from flow to atto-flow. +- `balance() EVM.Balance` provides the balance of the address. It returns a balance object rather than a basic type to avoid errors when it converts from flow to atto-flow. - `nonce() UInt64` retrieves the nonce associated with the address. - `code(): [UInt8]` fetches the code at the address; it returns the smart contract code if applicable, and is empty otherwise. @@ -51,9 +53,9 @@ fun main(addressHex: String): UFix64 { } ``` -### Sending Transactions to Flow EVM +### Send transactions to Flow EVM -To send transactions to Flow EVM, use the `run` function which executes RLP-encoded transactions. RLP (Recursive Length Prefix) encoding is used to efficiently encode data into a byte-array format, suitable for Ethereum-based environments. Here's an example of wrapping and sending a transaction: +To send transactions to Flow EVM, use the `run` function which executes RLP-encoded transactions. RLP (Recursive Length Prefix) encoding is used to efficiently encode data into a byte-array format, suitable for Ethereum-based environments. Here's an example of how to wrap and send a transaction: ```cadence import EVM from @@ -71,28 +73,28 @@ transaction(rlpEncodedTransaction: [UInt8], coinbaseBytes: [UInt8; 20]) { } ``` -Using `run` restricts an EVM block to a single EVM transaction, while a future `batchRun` will offer the capability to execute multiple EVM transactions in a batch. +When you `run`, it restricts an EVM block to a single EVM transaction, while a future `batchRun` will offer the capability to execute multiple EVM transactions in a batch. -### Handling Transaction Responses +### Handle transaction responses -Handling responses correctly is crucial to manage the state changes or errors that occur during `EVM` transactions: +It's crucial that your function handles responses correctly to manage the state changes or errors that occur during `EVM` transactions: -When calling `EVM.run`, it's important to understand that this method does not revert the outer Flow transaction. Developers must therefore carefully handle the response based on the `result.Status` of the EVM transaction execution. There are three main outcomes to consider: +When you call `EVM.run`, it's important to understand that this method does not revert the outer Flow transaction. Developers must therefore carefully handle the response based on the `result.Status` of the EVM transaction execution. There are three main outcomes to consider: -- `Status.invalid`: This status indicates that the transaction or call failed at the validation step, such as due to a nonce mismatch. Transactions with this status are not executed or included in a block, meaning no state change occurs. -- `Status.failed`: This status is assigned when the transaction has technically succeeded in terms of being processable, but the EVM reports an error as the outcome, such as running out of gas. Importantly, a failed transaction or call is still included in a block. Attempting to resubmit a failed transaction will result in an `invalid` status on the second try due to a now incorrect nonce. -- `Status.successful`: This status is given when the transaction or call is successfully executed and no errors are reported by the EVM. +- `Status.invalid`: This status indicates that the transaction or call failed at the validation step, such as due to a nonce mismatch. Transactions with this status are not executed or included in a block, which means no state change occurs. +- `Status.failed`: This status is assigned when the transaction has technically succeeded in terms of being processable, but the EVM reports an error as the outcome, such as running out of gas. Importantly, a failed transaction or call is still included in a block. Any attempt to resubmit a failed transaction results in an `invalid` status on the second try due to a now incorrect nonce. +- `Status.successful`: This status appears when the transaction or call is successfully executed and the EVM doesn't report errors. -For scenarios where transaction validity is critical, developers may choose to use the `mustRun` variation, which reverts the transaction in the case of a validation failure, providing an added layer of error handling. +For scenarios where transaction validity is critical, developers may choose to use the `mustRun` variation, which reverts the transaction in the case of a validation failure. This provides an added layer of error handling. -### Understanding Gas Usage in EVM Transactions +### Understanding gas usage in EVM transactions -Direct calls to Flow EVM require gas, it's important to understand how gas usage is calculated and billed. During the execution of methods that interact with the EVM: +Direct calls to Flow EVM require gas. It's important to understand how gas usage is calculated and billed. During the execution of methods that interact with the EVM: -- **Gas Aggregation**: The gas used by each call is aggregated throughout the transaction. -- **Gas Adjustment**: The total gas used is then adjusted based on a multiplier. This multiplier is determined by the network and can be adjusted by the service account to reflect operational costs and network conditions. -- **Payment of Gas Fees**: The adjusted total gas amount is added to the overall computation fees of the Flow transaction. These fees are paid by the transaction initiator, commonly referred to as the payer. +- **Gas Aggregation**: The gas that each call uses is aggregated throughout the transaction. +- **Gas Adjustment**: The total gas used is then adjusted based on a multiplier. This multiplier is determined by the network and the service account can adjust it to reflect operational costs and network conditions. +- **Payment of Gas Fees**: The adjusted total gas amount is added to the overall computation fees of the Flow transaction. The transaction initiator, commonly referred to as the payer, pays these fees. -## Keep Learning +## Keep learning For more information and a deeper dive into the `EVMAddress`, `Result`, and `Status` objects, see [the contract here](https://github.com/onflow/flow-go/blob/master/fvm/evm/stdlib/contract.cdc). diff --git a/docs/tutorials/cross-vm-apps/cadence-embedded-evm-txns.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/cadence-embedded-evm-txns.png similarity index 100% rename from docs/tutorials/cross-vm-apps/cadence-embedded-evm-txns.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/cadence-embedded-evm-txns.png diff --git a/docs/tutorials/cross-vm-apps/click-to-mint.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/click-to-mint.png similarity index 100% rename from docs/tutorials/cross-vm-apps/click-to-mint.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/click-to-mint.png diff --git a/docs/tutorials/cross-vm-apps/evm-embed-flowscan.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/evm-embed-flowscan.png similarity index 100% rename from docs/tutorials/cross-vm-apps/evm-embed-flowscan.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/evm-embed-flowscan.png diff --git a/docs/tutorials/cross-vm-apps/flow-runner-successful-output.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/flow-runner-successful-output.png similarity index 100% rename from docs/tutorials/cross-vm-apps/flow-runner-successful-output.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/flow-runner-successful-output.png diff --git a/docs/tutorials/cross-vm-apps/flowscan-connect.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/flowscan-connect.png similarity index 100% rename from docs/tutorials/cross-vm-apps/flowscan-connect.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/flowscan-connect.png diff --git a/docs/tutorials/cross-vm-apps/hybrid-app-demo.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/hybrid-app-demo.png similarity index 100% rename from docs/tutorials/cross-vm-apps/hybrid-app-demo.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/hybrid-app-demo.png diff --git a/docs/tutorials/cross-vm-apps/maybe-mint-in-metamask.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/maybe-mint-in-metamask.png similarity index 100% rename from docs/tutorials/cross-vm-apps/maybe-mint-in-metamask.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/maybe-mint-in-metamask.png diff --git a/docs/tutorials/cross-vm-apps/scores.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/scores.png similarity index 100% rename from docs/tutorials/cross-vm-apps/scores.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/scores.png diff --git a/docs/tutorials/cross-vm-apps/wflow-approve.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/wflow-approve.png similarity index 100% rename from docs/tutorials/cross-vm-apps/wflow-approve.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/wflow-approve.png diff --git a/docs/tutorials/cross-vm-apps/wflow-deposit-confirm.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/wflow-deposit-confirm.png similarity index 100% rename from docs/tutorials/cross-vm-apps/wflow-deposit-confirm.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/wflow-deposit-confirm.png diff --git a/docs/tutorials/cross-vm-apps/wflow-deposit.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/wflow-deposit.png similarity index 100% rename from docs/tutorials/cross-vm-apps/wflow-deposit.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/wflow-deposit.png diff --git a/docs/tutorials/cross-vm-apps/wflow-in-metamask-tokens.png b/docs/blockchain-development-tutorials/cross-vm-apps/imgs/wflow-in-metamask-tokens.png similarity index 100% rename from docs/tutorials/cross-vm-apps/wflow-in-metamask-tokens.png rename to docs/blockchain-development-tutorials/cross-vm-apps/imgs/wflow-in-metamask-tokens.png diff --git a/docs/blockchain-development-tutorials/cross-vm-apps/index.md b/docs/blockchain-development-tutorials/cross-vm-apps/index.md new file mode 100644 index 0000000000..e02c0ba187 --- /dev/null +++ b/docs/blockchain-development-tutorials/cross-vm-apps/index.md @@ -0,0 +1,56 @@ +--- +title: Cross-VM Apps +description: A series of tutorials on building cross-VM applications that integrate Flow EVM with Flow Cadence. +sidebar_position: 7 +keywords: + - hybrid apps + - cross-vm apps + - Flow EVM + - Flow Cadence + - tutorials + - COAs + - batched transactions + - VM bridge + - cross-VM bridge +--- + +# Cross-VM App tutorials + +This series covers how to build cross-VM applications that integrate Flow EVM with Flow Cadence, which combines new environments and unlocks new capabilities. Flow's unique architecture allows seamless interaction between Cadence smart contracts and EVM-compatible contracts, which allows developers to leverage the best features of both virtual machines in a single application. + +## Tutorials + +### [Batched Transactions] + +Learn to create hybrid applications with Flow Command Line (FCL), wagmi, and RainbowKit that connect simultaneously to Flow EVM and Flow Cadence. This comprehensive tutorial demonstrates how to build "Click to Mint," a game where users can mint ERC-20 tokens individually or batch 10 transactions with a single signature with Cadence's powerful multi-call functionality. You'll integrate traditional EVM development tools with Flow's advanced features while maintaining familiar wagmi/viem patterns. The tutorial covers project setup, wallet integration, smart contract interaction, and UI/UX improvements for cross-VM applications. + +### [Add Flow Cadence to Your wagmi App] + +Discover how to enhance your wagmi/RainbowKit applications. You can integrate Flow Cadence functionality and not rebuild them from scratch. This guide shows you how to add FCL to your current EVM-based dApp to allow advanced features like batched transactions, native randomness, and account abstraction. You'll learn to manage concurrent connections to both Flow EVM and Cadence environments and maintain your current user interface and development workflows. The tutorial provides step-by-step integration strategies and best practices for hybrid application architecture. + +### [Interacting with COAs] + +Master how to create and manage Cadence Owned Accounts (COAs), which allow Cadence smart contracts to control EVM accounts on Flow. This tutorial covers how to set up COAs, details their permissions model, and shows how to implement secure interactions between Cadence and EVM environments. You'll learn how to deploy and manage EVM contracts from Cadence, handle cross-VM asset transfers, and implement proper access controls for hybrid applications. + +### [Batched EVM Transactions] + +Explore advanced techniques for how to execute multiple EVM transactions atomically within a single Cadence transaction. This guide demonstrates how to batch complex EVM operations like multi-step DeFi protocols, NFT minting sequences, or arbitrage strategies and maintain transaction atomicity. You'll learn to handle transaction failures gracefully, optimize gas usage across batched calls, and implement error handling for complex multi-transaction workflows. + +### [Direct Calls to Flow EVM] + +Learn how Cadence smart contracts can directly interact with Flow EVM without the need to separate user transactions. This technical guide covers how to make direct calls from Cadence to query EVM state, execute EVM transactions programmatically, and handle responses and errors appropriately. You'll understand gas calculation models, transaction status handling, and best practices for how to integrate direct EVM calls into your Cadence contracts. + +### [Cross-VM Bridge] + +Explore the automated bridging of fungible and non-fungible tokens between Flow Cadence and Flow EVM environments. This comprehensive guide covers the Cross-VM Bridge protocol, which allows atomic movement of ERC-20, ERC-721, and Flow native tokens between virtual machines. You'll learn to onboard tokens to the bridge, implement custom token associations, handle bridging fees, and design tokens that work seamlessly across both Cadence and EVM environments. + +## Conclusion + +Cross-VM applications represent the future of blockchain development on Flow, which combines Cadence's innovative resource-oriented programming with EVM's ecosystem compatibility. These tutorials provide the foundation for you to build sophisticated applications that leverage both virtual machines, which allows developers to create unique experiences that wouldn't be possible on single-VM blockchains and maintain compatibility with current Ethereum tooling and user expectations. + +[Batched Transactions]: ./introduction.md +[Add Flow Cadence to Your wagmi App]: ./add-to-wagmi.md +[Interacting with COAs]: ./interacting-with-coa.md +[Batched EVM Transactions]: ./batched-evm-transactions.md +[Direct Calls to Flow EVM]: ./direct-calls.md +[Cross-VM Bridge]: ./vm-bridge.md diff --git a/docs/tutorials/cross-vm-apps/interacting-with-coa.md b/docs/blockchain-development-tutorials/cross-vm-apps/interacting-with-coa.md similarity index 77% rename from docs/tutorials/cross-vm-apps/interacting-with-coa.md rename to docs/blockchain-development-tutorials/cross-vm-apps/interacting-with-coa.md index c9055a9b9c..75e91af29e 100644 --- a/docs/tutorials/cross-vm-apps/interacting-with-coa.md +++ b/docs/blockchain-development-tutorials/cross-vm-apps/interacting-with-coa.md @@ -1,25 +1,22 @@ --- title: Interacting with COAs from Cadence sidebar_label: Interacting with COAs -sidebar_position: 4 +sidebar_position: 5 --- -[Cadence Owned Accounts (COAs)](../../evm/accounts.md#cadence-owned-accounts) are EVM accounts owned by a Cadence resource and -are used to interact with Flow EVM from Cadence. +# Interacting with COAs from Cadence -COAs expose two interfaces for interaction: one on the Cadence side and one on the EVM side. In this guide, we will -focus on how to interact with COAs with Cadence. +[Cadence Owned Accounts (COAs)] are EVM accounts that a Cadence resouce owns, and are used to interact with Flow EVM from Cadence. -In this guide we will walk through some basic examples creating and interacting with a COA in Cadence. Your specific -usage of the COA resource will depend on your own application's requirements (e.g. the COA resource may not live -directly in `/storage/evm` as in these examples, but may instead be a part of a more complex resource structure). +COAs expose two interfaces for interaction: one on the Cadence side and one on the EVM side. In this guide, we focuses on how to interact with COAs with Cadence. + +In this guide, we will walk through some basic examples that create and and interact with a COA in Cadence. Your specific usage of the COA resource will depend on your own application's requirements (for example, the COA resource may not live directly in `/storage/evm` as in these examples, but may instead be a part of a more complex resource structure). ## COA Interface -To begin, we can take a look at a simplified version of the `EVM` contract, highlighting parts specific to COAs. +To begin, we can take a look at a simplified version of the `EVM` contract, and highlight parts specific to COAs. -You can learn more about the `EVM` contract [here](../../build/core-contracts/13-evm.md) and the full contract code can -be found on [GitHub](https://github.com/onflow/flow-go/tree/master/fvm/evm/stdlib/contract.cdc). +You can learn more about the `EVM` contract [here] and find the full contract code on [GitHub]. ```cadence EVM.cdc access(all) @@ -80,14 +77,11 @@ contract EVM { } ``` -## Importing the EVM Contract +## Import the EVM contract -The `CadenceOwnedAccount` resource is a part of the `EVM` system contract, so to use any of these functions, you will -need to begin by importing the `EVM` contract into your Cadence code. +The `CadenceOwnedAccount` resource is a part of the `EVM` system contract, so to use any of these functions, you will need to import the `EVM` contract into your Cadence code. -To import the `EVM` contract into your Cadence code using the simple import syntax, you can use the following format -(learn more about configuring contracts in `flow.json` -[here](../../tools/flow-cli/flow.json/configuration.md#contracts)): +To import the `EVM` contract into your Cadence code with the simple import syntax, you can use the following format (learn more about how to configure contracts in `flow.json` [here]): ```cadence // This assumes you are working in the in the Flow CLI, FCL, or another tool that supports this syntax @@ -104,16 +98,14 @@ import EVM from 0x1234 // ... ``` -To find the deployment addresses of the `EVM` contract, you can refer to the [EVM contract -documentation](../../build/core-contracts/13-evm.md). +To find the deployment addresses of the `EVM` contract, you can refer to the [EVM contract documentation]. -## Creating a COA +## Create a COA To create a COA, we can use the `createCadenceOwnedAccount` function from the `EVM` contract. This function takes no -arguments and returns a new `CadenceOwnedAccount` resource which represents this newly created EVM account. +arguments and returns a new `CadenceOwnedAccount` resource which represents this newly-created EVM account. -For example, we can create this COA in a transaction, saving it to the user's storage and publishing a public capability -to its reference: +For example, we can create this COA in a transaction, save it to the user's storage, and publish a public capability to its reference: ```cadence create_coa.cdc import "EVM" @@ -135,11 +127,48 @@ transaction() { } ``` -## Getting the EVM Address of a COA +### Create a Cadence account and COA together + +It is possible to create a new Cadence account and COA within the same transaction. Another account will need to sign and pay for this transaction, but any account will do. A common process is to set up a backend service to handle this function. + +:::info + +During the singular transaction in which an account is created, the `AuthAccount` object for the newly-created account is present. As a result, the creating account can access and modify the new account's storage **only** during this transaction. + +::: + +First, you'll need to use the CLI to [generate keys] for the new account. Then, run the following transaction to create the Cadence Account and COA at one time. + +:::warning -To get the EVM address of a COA, you can use the `address` function from the `EVM` contract. This function returns the -EVM address of the COA as an `EVM.Address` struct. This struct is used to represent addresses within Flow EVM and can -also be used to query the balance, code, nonce, etc. of an account. +This is a very minimal example. You may wish to set up vaults and perform other actions during account creation. + +::: + +```cadence +import Crypto + +transaction(publicKeys: [Crypto.KeyListEntry]) { + prepare(signer: auth(BorrowValue) &Account) { + + let newAccount = Account(payer: signer) + + for key in publicKeys { + newAccount.keys.add(publicKey: key.publicKey, hashAlgorithm: key.hashAlgorithm, weight: key.weight) + } + + let coa <- EVM.createCadenceOwnedAccount() + let coaPath = /storage/evm + newAccount.storage.save(<-coa, to: coaPath) + let coaCapability = newAccount.capabilities.storage.issue<&EVM.CadenceOwnedAccount>(coaPath) + newAccount.capabilities.publish(coaCapability, at: /public/evm) + } +} +``` + +## Retrieve the EVM Address of a COA + +To get the EVM address of a COA, you can use the `address` function from the `EVM` contract. This function returns the EVM address of the COA as an `EVM.Address` struct. This struct is used to represent addresses within Flow EVM and you can also use it to query the balance, code, nonce, and so on of an account. For our example, we could query the address of the COA we just created with the following script: @@ -162,19 +191,17 @@ fun main(address: Address): EVM.EVMAddress { } ``` -If you'd prefer the hex representation of the address, you instead return using the `EVMAddress.toString()` function: +If you'd prefer the hex representation of the address, you instead return with the `EVMAddress.toString()` function: ```cadence return coa.address().toString() ``` -The above will return the EVM address as a string; however note that Cadence does not prefix hex strings with `0x`. +The above will return the EVM address as a string; however, Cadence does not prefix hex strings with `0x`. -## Getting the Flow Balance of a COA +## Retrieve the Flow balance of a COA -Like any other Flow EVM or Cadence account, COAs possess a balance of FLOW tokens. To get the current balance of our -COA, we can use the COA's `balance` function. It will return a `EVM.Balance` struct for the account - these are used to -represent balances within Flow EVM. +Like any other Flow EVM or Cadence account, COAs possess a balance of FLOW tokens. To get the current balance of our COA, we can use the COA's `balance` function. It will return a `EVM.Balance` struct for the account - these are used to represent balances within Flow EVM. This script will query the current balance of our newly created COA: @@ -211,16 +238,13 @@ fun main(addressHex: String): UFix64 { The above script is helpful if you already know the COA address and can provide the hex representation directly. -## Depositing and Withdrawing Flow Tokens +## Deposit and withdraw Flow tokens -Tokens can be seamlessly transferred between the Flow EVM and Cadence environment using the `deposit` and `withdraw` -functions provided by the COA resource. Anybody with a valid reference to a COA may deposit Flow tokens into a it, -however only someone with the `Owner` or `Withdraw` entitlements can withdraw tokens. +You can seamlessly transfer tokens between the Flow EVM and Cadence environment with the `deposit` and `withdraw` functions that the COA resource provides. Anybody with a valid reference to a COA may deposit Flow tokens into a it, however only someone with the `Owner` or `Withdraw` entitlements can withdraw tokens. -### Depositing Flow Tokens +### Deposit Flow tokens -The `deposit` function takes a `FlowToken.Vault` resource as an argument, representing the tokens to deposit. It will -transfer the tokens from the vault into the COA's balance. +The `deposit` function takes a `FlowToken.Vault` resource as an argument, which represents the tokens to deposit. It will transfer the tokens from the vault into the COA's balance. This transaction will withdraw Flow tokens from a user's Cadence vault and deposit them into their COA: @@ -256,18 +280,15 @@ transaction(amount: UFix64) { :::info -This is a basic example which only transfers tokens between a single user's COA & Flow account. It can be easily -modified to transfer these tokens between any arbitrary accounts. +This is a basic example which only transfers tokens between a single user's COA & Flow account. You can easily modify it to transfer these tokens between any arbitrary accounts. -You can also deposit tokens directly into other types of EVM accounts using the `EVM.EVMAddress.deposit` function. See -the [EVM contract documentation](../../build/core-contracts/13-evm.md) for more information. +You can also deposit tokens directly into other types of EVM accounts with the `EVM.EVMAddress.deposit` function. See the [EVM contract documentation] for more information. ::: -### Withdrawing Flow Tokens +### Withdraw Flow tokens -The `withdraw` function takes a `EVM.Balance` struct as an argument, representing the amount of Flow tokens to withdraw, -and returns a `FlowToken.Vault` resource with the withdrawn tokens. +The `withdraw` function takes a `EVM.Balance` struct as an argument, which represents the amount of Flow tokens to withdraw, and returns a `FlowToken.Vault` resource with the withdrawn tokens. We can run the following transaction to withdraw Flow tokens from a user's COA and deposit them into their Flow vault: @@ -308,20 +329,20 @@ transaction(amount: UFix64) { :::info -This is a basic example which only transfers tokens between a single user's COA & Flow account. It can be easily +This is a basic example which only transfers tokens between a single user's COA and Flow account. It can be easily modified to transfer these tokens between any arbitrary accounts. ::: ## Direct Calls to Flow EVM -To interact with smart contracts on the EVM, you can use the `call` function provided by the COA resource. This function +To interact with smart contracts on the EVM, you can use the `call` function the COA resource provides. This function takes the EVM address of the contract you want to call, the data you want to send, the gas limit, and the value you want to send. It will return a `EVM.Result` struct with the result of the call - you will need to handle this result in your Cadence code. This transaction will use the signer's COA to call a contract method with the defined signature and args at a given EVM -address, executing with the provided gas limit and value: +address, and executes with the provided gas limit and value: ```cadence call.cdc import "EVM" @@ -376,7 +397,7 @@ transaction(evmContractHex: String, signature: String, args: [AnyStruct], gasLim :::info Notice that the calldata is encoded in the scope of the transaction. While developers can encode the calldata -outside the scope of the transaction and pass the encoded data as an argument, doing so compromises the +outside the scope of the transaction and pass the encoded data as an argument, this compromises the human-readability of Cadence transactions. It's encouraged to either define transactions for each COA call and encoded the hardcoded EVM signature and arguments, @@ -385,10 +406,9 @@ more interpretable and therefore transparent transaction. ::: -### Transferring FLOW in EVM +### Transfer FLOW in EVM -Similar to transferring ETH and other native value in other EVMs, you'll want to call to the target EVM address with -empty calldata and providing the transfer value. +Similar to when you trasnfer ETH and other native value in other EVMs, you'll want to call to the target EVM address with empty calldata and provide the transfer value. ```cadence transfer_evm_flow.cdc import "EVM" @@ -437,8 +457,7 @@ transaction(to: String, amount: UInt) { ### Transfer ERC20 -Below is an example transaction demonstrating the common ERC20 transfer. A similar pattern can be used for other -arbitrary EVM calls. +Below is an example transaction that demonstrates the common ERC20 transfer. You can use a similar pattern for other arbitrary EVM calls. ```cadence erc20_transfer_from.cdc import "EVM" @@ -487,7 +506,7 @@ transaction(erc20AddressHex: String, to: String, amount: UInt256) { ### Transfer ERC721 -Following on from above, the example transaction below demonstrates a common ERC721 transfer. +The example transaction below demonstrates a common ERC721 transfer. ```cadence erc721_transfer.cdc import "EVM" @@ -533,12 +552,9 @@ transaction(erc721AddressHex: String, to: String, id: UInt256) { } ``` -#### Bulk Transfer ERC721 +#### Bulk transfer ERC721 -As covered in the [Batched EVM transactions walkthrough](./batched-evm-transactions.md), you can script multiple EVM -calls in a single Cadence transaction. Compared to the single ERC721 transfer, bulk sending multiple tokens isn't much -more code and allows for greater utility out of a single transaction. Below is an example of a bulk ERC721 token -transfer. +As covered in the [Batched EVM transactions walkthrough], you can script multiple EVM calls in a single Cadence transaction. Compared to the single ERC721 transfer, to bulk send multiple tokens isn't much more code and allows for greater utility out of a single transaction. Below is an example of a bulk ERC721 token transfer. ```cadence erc721_bulk_transfer.cdc import "EVM" @@ -591,12 +607,11 @@ transaction(erc721AddressHex: String, to: String, ids: [UInt256]) { } ``` -## Deploying a Contract to Flow EVM +## Deploy a contract to Flow EVM -To deploy a contract to the EVM, you can use the `deploy` function provided by the COA resource. This function takes the -contract code, gas limit, and value you want to send. It will return the EVM address of the newly deployed contract. +To deploy a contract to the EVM, you can use the `deploy` function that the COA resource provides. This function takes the contract code, gas limit, and value you want to send. It will return the EVM address of the newly deployed contract. -This transaction will deploy a contract with the given code using the signer's COA: +This transaction will deploy a contract with the given code with the signer's COA: ```cadence deploy_evm_contract.cdc import "EVM" @@ -623,11 +638,20 @@ transaction(bytecode: String) { } ``` -## More Information +## More information + +For more information about Cadence-owned Accounts, see [Flow EVM Accounts]. + +Other useful snippets to use when you interact with COAs can be found [here]. -For more information about Cadence Owned Accounts, see [Flow EVM Accounts](../../evm/accounts.md). +Check out the [Batched EVM Transactions walkthrough] for details on transaction batching with Cadence. -Other useful snippets for interacting with COAs can be found [here](https://fw-internal-doc.gitbook.io/evm). + -Check out the [Batched EVM Transactions walkthrough](./batched-evm-transactions.md) for details on transaction batching -using Cadence. +[Flow EVM Accounts]: ../../build/evm/accounts.md +[here]: https://fw-internal-doc.gitbook.io/evm +[Batched EVM Transactions walkthrough]: ./batched-evm-transactions.md +[EVM contract documentation]: ../../build/cadence/core-contracts/13-evm.md +[generate keys]: ../../build/tools/flow-cli/keys/generate-keys.md +[GitHub]: https://github.com/onflow/flow-go/tree/master/fvm/evm/stdlib/contract.cdc +[Cadence Owned Accounts (COAs)]: ../../build/evm/accounts.md#cadence-owned-accounts \ No newline at end of file diff --git a/docs/tutorials/cross-vm-apps/introduction.md b/docs/blockchain-development-tutorials/cross-vm-apps/introduction.md similarity index 80% rename from docs/tutorials/cross-vm-apps/introduction.md rename to docs/blockchain-development-tutorials/cross-vm-apps/introduction.md index 4da23fd775..500dff8b56 100644 --- a/docs/tutorials/cross-vm-apps/introduction.md +++ b/docs/blockchain-development-tutorials/cross-vm-apps/introduction.md @@ -1,7 +1,7 @@ --- title: Batched Tx From Scaffold description: Learn how to use FCL with wagmi and rainbowkit to create a cross-vm app - one that is simultaneously connected to Flow EVM and Flow Cadence. -sidebar_position: 0 +sidebar_position: 1 keywords: - hybrid apps - cross-vm apps @@ -22,51 +22,53 @@ keywords: - supercharge your EVM app with Cadence --- -Ever since the launch of Flow EVM, it's been possible to _supercharge_ your EVM apps by using Flow Cadence features and contracts. Some benefits, such as [native VRF] and inexpensive gas without compromising security are built in and either easy or automatic to use. Others, such as the ability to use [Cadence] to [structure and call EVM transactions], are powerful but complicated to configure and use. They also require developers to manage concurrent connections to both networks. +# Batched Tx From Scaffold + +Ever since we launched Flow EVM, you can _supercharge_ your EVM apps with Flow Cadence features and contracts. Some benefits, such as [native VRF] and inexpensive gas that won't compromise security, are built in and either easy to use or automatic. Others, such as the ability to use [Cadence] to [structure and call EVM transactions], are powerful but complicated to configure and use. They also require developers to manage concurrent connections to both networks. [FLIP 316] improves the [Flow Client Library (FCL)] to support cross-VM functionality between Flow EVM and Flow Cadence. For EVM developers, this means that you can use the familiar [wagmi], [viem], and [RainbowKit] stack you're used to, add FCL, and get features like **multi-call write** with one signature for users with a Cadence-compatible [wallet]. -In this tutorial, you'll learn how to create [Click to Mint], a simple game that allows players to mint an ERC-20 token by clicking a button. With the power of Flow, they can also click a button, and **complete 10 separate transactions with just one approval!** +In this tutorial, you'll learn how to create [Click to Mint], a simple game that allows players to click a button to mint an ERC-20 token. With the power of Flow, they can also click a button and **complete 10 separate transactions with just one approval!** -![Click to Mint](click-to-mint.png) +![Click to Mint](./imgs/click-to-mint.png) :::warning -The FCL functionality described in this tutorial is in alpha. Some steps may change. We'll keep the tutorial updated, but please [create an issue] or let us know on [Discord] if something isn't working for you. +The FCL functionality described in this tutorial is in alpha. Some steps may change. We'll keep the tutorial updated, but please [create an issue] or let us know on [Discord] if something doesn't ork for you. ::: ## Objectives -After completing this guide, you'll be able to: +After you complete this guide, you'll be able to: -- Build an app that seamlessly integrates Flow Cadence and Flow EVM connections -- Add Cadence features to your [Rainbowkit]/[wagmi]/[viem] app -- Utilize [Flow Client Library (FCL)] to enable multi-call contract writes to Flow EVM +- Build an app that seamlessly integrates Flow Cadence and Flow EVM connections. +- Add Cadence features to your [Rainbowkit]/[wagmi]/[viem] app. +- Use [Flow Client Library (FCL)] to turn on multi-call contract writes to Flow EVM. ## Prerequisites -### Next.js and Modern Frontend Development +### Next.js and modern frontend development -This tutorial uses [Next.js]. You don't need to be an expert, but it's helpful to be comfortable with development using a current React framework. You'll be on your own to select and use a package manager, manage Node versions, and other frontend environment tasks. If you don't have your own preference, you can just follow along with us and use [npm]. +This tutorial uses [Next.js]. You don't need to be an expert, but it's helpful to be comfortable with development with a current React framework. You'll be on your own to select and use a package manager, manage Node versions, and other frontend environment tasks. If you don't have your own preference, you can just follow along with us and use [npm]. -### Solidity and Cadence Smart Contract Development +### Solidity and Cadence smart contract development -Apps using the hybrid approach can interact with both [Cadence] and [Solidity] smart contracts. You don't need to be an expert in either of these, but it's helpful to be familiar with how smart contracts work in at least one of these languages. +Apps that use the hybrid approach can interact with both [Cadence] and [Solidity] smart contracts. You don't need to be an expert in either of these, but it's helpful to be familiar with how smart contracts work in at least one of these languages. -### Onchain App Frontends +### Onchain app frontends -We're assuming you're familiar with [wagmi], [viem], and [RainbowKit]. If you're coming from the Cadence, you might want to take a quick look at the getting started guides for these platforms. They're all excellent and will rapidly get you up to speed on how the EVM world commonly connects their apps to their contracts. +We assume you're familiar with [wagmi], [viem], and [RainbowKit]. If you come from the Cadence, you might want to take a quick look at the getting started guides for these platforms. They're all excellent and will rapidly get you up to speed on how the EVM world commonly connects their apps to their contracts. -## Getting Started +## Get started -For this tutorial, we'll be starting from a fork of the [FCL + RainbowKit + Wagmi Integration Demo] built by the team. +For this tutorial, we'll start from a fork of the [FCL + RainbowKit + Wagmi Integration Demo] that the team built. Fork the repo so you can push your work freely to your own copy, then follow the setup instructions. -## Project Overview +## Project overview Open the cross-vm app scaffold in your editor, run it, and view the site in your browser: @@ -76,7 +78,7 @@ npm run dev You'll see: -![Hybrid App Demo](hybrid-app-demo.png) +![Hybrid App Demo](./imgs/hybrid-app-demo.png) Connect with a Cadence-compatible [wallet]. @@ -86,7 +88,7 @@ In a production app, you'll want to manage this process carefully. Non-Cadence E ::: -## Send Batch Transactions +## Send batch transactions The first demo built into this scaffold is **multi-call contract write**. @@ -100,15 +102,15 @@ Click `Send Batch Transaction Example` and approve the transaction. You'll see t :::tip -Currently, the Flow wallet sponsors all gas for all transactions signed with the wallet on both testnet **and mainnet!** +Currently, the Flow wallet sponsors the fees for the compute units (equivalent of gas) for all transactions signed with the wallet on both testnet **and mainnet!** ::: -### Cadence Parent Transaction +### Cadence parent transaction -The first line is the transaction id of the Flow Cadence transaction that calls **both** of the EVM transactions. Search for it in [Testnet Cadence Flowscan]. +The first line is the transaction ID of the Flow Cadence transaction that calls **both** of the EVM transactions. Search for it in [Testnet Cadence Flowscan]. -Cadence transactions are more complicated than those in Solidity contracts. Rather than being restricted to running functions present on the contract, they can run arbitrary code as long as the caller has access to all of the resources required by the transaction. +Cadence transactions are more complicated than those in Solidity contracts. Rather than being restricted to run functions present on the contract, they can run arbitrary code as long as the caller has access to all of the resources the transaction requires. You can see the code of the transaction in the `Script` tab, but we've included it here for convenience: @@ -153,19 +155,19 @@ transaction(calls: [{String: AnyStruct}], mustPass: Bool) { } ``` -In this case, it's checking that the caller of the Cadence transaction has permission to control to the EVM account, which is built in for [Cadence Owned Accounts]. The `execute` phase then iterates through the EVM transactions and uses the Cadence accounts own permissions to sign the EVM transactions. +In this case, it checks that the caller of the Cadence transaction has permission to control to the EVM account, which is built in for [Cadence Owned Accounts]. The `execute` phase then iterates through the EVM transactions and uses the Cadence accounts own permissions to sign the EVM transactions. The loop also handles a check for the optional flag to cancel all of the transactions if any one of them fails. **In other words, you could set up a 20 transaction arbitrage attempt and unwind everything if it fails at any step!** -### EVM Child Transactions +### EVM child transactions -The next two lines show the transaction hashes for the EVM transactions. You can view this in [Testnet EVM Flowscan] by searching for the transaction hashes, the same as any other. +The next two lines show the transaction hashes for the EVM transactions. To view this in [Testnet EVM Flowscan], search for the transaction hashes, the same as any other. Look up both transactions. -The first is calling the `deposit()` function to wrap FLOW and move it to EVM. +The first calls the `deposit()` function to wrap FLOW and move it to EVM. -The second is calling the ERC-20 `approve()` function to give another address the authority to spend those tokens. +The second calls the ERC-20 `approve()` function to give another address the authority to spend those tokens. For the demo, the code for this is hard-coded into `src/app/page.tsx`: @@ -212,7 +214,7 @@ const calls: EVMBatchCall[] = [ It's called with the `useBatchTransaction` hook via the `sendBatchTransaction(calls)` function. -## Code Evaluator +## Code evaluator The demo also has an embedded code evaluator that you can use to experiment with snippets of code from `fcl` or `wagmi`. @@ -232,15 +234,15 @@ return block.height; Returns the current Cadence VM block number. -## Calling Your Own Contract +## Call your own contract Next, we'll update the starter to connect to and call functions in our own contract. For this, we'll use a simple [Button Clicker Contract]. You can deploy your own copy, or use the one deployed at [`0xA7Cf2260e501952c71189D04FAd17c704DFB36e6`]. -## Set Up Contract Imports +## Set Up contract imports :::info -The following steps assume deployment with Hardhat Ignition. If you are using a different deployment method, import the contract address and abi as appropriate. +The following steps assume deployment with Hardhat Ignition. If you use a different deployment method, import the contract address and abi as appropriate. ::: @@ -260,9 +262,9 @@ export const clickToken = { }; ``` -## Build Traditional Functionality +## Build traditional functionality -This isn't a wagmi tutorial, so we'll give you some components to speed up the process. Add a folder called `components` inside `src` and add the following files. +This isn't a wagmi tutorial, so we'll give you some components to speed up the process. Add a folder called `components` inside `src` and add the following files: `TheButton.tsx` @@ -520,9 +522,9 @@ return ( You'll now see the button and scoreboard from the contract. Test it out and earn a few points! -![scores](scores.png) +![scores](./imgs/scores.png) -## Supercharge your EVM App With Cadence +## Supercharge your EVM app With Cadence Now let's supercharge it. With the power of Cadence, you can use multi-call write and give your users way more tokens with a single click and single signature! @@ -541,7 +543,7 @@ const calls: EVMBatchCall[] = [ ]; ``` -Try clicking the `Send Batch Transaction Example` button again. You'll have to **manually refresh** the page when the EVM transaction hash appears to see the score update. We haven't wired in the query invalidation yet. +Click `Send Batch Transaction Example` again. You'll have to **manually refresh** the page when the EVM transaction hash appears to see the score update. We haven't wired in the query invalidation yet. Next, use some JavaScript to put 10 copies of the transaction call into the array: @@ -554,19 +556,19 @@ const calls: EVMBatchCall[] = Array.from({ length: 10 }, () => ({ })); ``` -Click the button again and **manually** refresh page once the transaction hashes appear. +Click the button again and **manually** refresh page after the transaction hashes appear. **You just minted 10 tokens from 10 transactions with one signature!** ## Improve the UI/UX -While we've got the batched transactions feature working, we've got a few flaws in the user experience that we'll need to resolve, and we should make this a bit nicer looking. +While the batched transactions feature works, we've got a few flaws in the user experience that we'll need to resolve, and we should make this look a bit nicer. ### Install Tailwind :::warning -We initially tried getting an AI friend to install this for us and it got very confused. Next.js and Tailwind have both had a lot of change recently. As a result, the LLMs don't seem to have caught up just yet. +We initially tried to get an AI friend to install this for us and it got very confused. `Next.js` and Tailwind have both had a lot of change recently. As a result, the LLMs don't seem to have caught up just yet. Do this part the old-fashioned way. @@ -597,9 +599,9 @@ Then, add the following to the top of `src/styles/global.css`: Run the app and make sure you see some styling. It won't look nice yet. We'll help you reorganize the components and hook up state monitoring, but it will be up to you to style the app how you'd like. You can check out the [reference repo] for inspiration, but it's far from perfect or beautiful. -### Update State Display +### Update state display -The first thing we'll need to fix is that the user has to refresh the window manually to see the results of the batched transaction in the scoreboard. Start by moving the functionality in `page.tsx` into a new component, called `SuperButton.tsx`. Note that we're mimicking the pattern in `TheButton.tsx` where the blockchain state is managed in `Content.tsx` and we're passing in the relevant information and functions as props: +The first thing we'll need to fix is that the user has to refresh the window manually to see the results of the batched transaction in the scoreboard. To start, move the functionality in `page.tsx` into a new component, called `SuperButton.tsx`. We mimic the pattern in `TheButton.tsx` where the blockchain state is managed in `Content.tsx`, and we pass in the relevant information and functions as props: ```tsx 'use client'; @@ -680,7 +682,7 @@ export default function SuperButton({ } ``` -You should end up with a vastly simplified `page.tsx`: +You will end up with a vastly simplified `page.tsx`: ```tsx import Content from '../components/Content'; @@ -770,11 +772,11 @@ return ( ); ``` -### Testing +### Tests -Run the app and make sure it's working as expected, even if in a rather ugly fashion. +Run the app and make sure it works as expected, even if in a rather ugly fashion. -### Add UI Hints +### Add UI hints With this kind of app, you're likely to have two types of users. Those that have upgraded to the [Flow Wallet] can take advantage of advanced features such as batched transactions, and those who haven't cannot. @@ -789,19 +791,19 @@ It's up to you do design a comprehensive strategy for your app, but here, we can ``` -### Styling +### Style It's up to you to make the app pretty. If you need inspiration, you can always check the [reference repo]. ## Conclusion -In this tutorial, you reviewed the demo starter for building hybrid applications that utilize a common EVM stack and integrate with Flow Cadence. You then added functionality to interface with another contract that mints ERC-20 tokens. Finally, you supercharged your app by using the power of Cadence for EVM multi-call contract writes. +In this tutorial, you reviewed the demo starter to build hybrid applications that use a common EVM stack and integrate with Flow Cadence. You then added functionality to interface with another contract that mints ERC-20 tokens. Finally, you supercharged your app with the power of Cadence for EVM multi-call contract writes. -Now that you have completed the tutorial, you should be able to: +Now that you have completed the tutorial, you will be able to: -- Build an app that seamlessly integrates Flow Cadence and Flow EVM connections -- Add Cadence features to your [Rainbowkit]/[wagmi]/[viem] app -- Utilize [Flow Client Library (FCL)] to enable multi-call contract writes to Flow EVM +- Build an app that seamlessly integrates Flow Cadence and Flow EVM connections. +- Add Cadence features to your [Rainbowkit]/[wagmi]/[viem] app. +- Use [Flow Client Library (FCL)] to enable multi-call contract writes to Flow EVM. @@ -815,7 +817,7 @@ Now that you have completed the tutorial, you should be able to: [native VRF]: ../native-vrf/vrf-in-solidity.md [structure and call EVM transactions]: ./batched-evm-transactions.md [FLIP 316]: https://github.com/onflow/flips/pull/317 -[Flow Client Library (FCL)]: ../../tools/clients/fcl-js +[Flow Client Library (FCL)]: ../../build/tools/clients/fcl-js [wagmi]: https://wagmi.sh/ [viem]: https://viem.sh/ [RainbowKit]: https://www.rainbowkit.com/ @@ -824,7 +826,7 @@ Now that you have completed the tutorial, you should be able to: [FCL + RainbowKit + Wagmi Integration Demo]: https://github.com/jribbink/cross-vm-app [FCL-JS]: https://github.com/onflow/fcl-js [Testnet Cadence Flowscan]: https://testnet.flowscan.io -[Cadence Owned Accounts]: ../../build/basics/accounts.md +[Cadence Owned Accounts]: ../../build/cadence/basics/accounts.md [Testnet EVM Flowscan]: https://evm-testnet.flowscan.io [Button Clicker Contract]: https://github.com/briandoyle81/button-clicker-contract/blob/main/contracts/ClickToken.sol [`0xA7Cf2260e501952c71189D04FAd17c704DFB36e6`]: https://evm-testnet.flowscan.io/address/0xA7Cf2260e501952c71189D04FAd17c704DFB36e6?tab=contract diff --git a/docs/blockchain-development-tutorials/cross-vm-apps/vm-bridge.md b/docs/blockchain-development-tutorials/cross-vm-apps/vm-bridge.md new file mode 100644 index 0000000000..d2e842f602 --- /dev/null +++ b/docs/blockchain-development-tutorials/cross-vm-apps/vm-bridge.md @@ -0,0 +1,555 @@ +--- +title: Cross-VM Bridge +sidebar_label: Cross-VM Bridge +sidebar_position: 6 +--- + +# Cross-VM Bridge + +Flow provides the [Cross-VM Bridge] which allows the movement of fungible and non-fungible tokens between Flow-Cadence & Flow-EVM. The Cross-VM Bridge is a contract-based protocol which allows the automated and atomic bridging of tokens from Cadence into EVM with their corresponding ERC-20 and ERC-721 token types. + +In the opposite direction, it supports bridging of arbitrary ERC-20 and ERC-721 tokens from EVM to Cadence as their corresponding FT or NFT token types. + +By default, when a user onboards a new token to the bridge, the bridge will deploy a standard token contract in the other VM that only the core bridge protocol contracts retain limited control over. This bridge-deployed contract handles basic minting and metadata operations that are required for usage in the needed environment. + +If a developer wants to define and connect the NFT contracts on both sides of the bridge, they can have each contract point to each other to indicate that they are associated and then register that association with the bridge so the token moves between VMs as either definition. + +The Cross-VM Bridge internalizes the capabilities to deploy new token contracts in either VM state as needed, resolves access to and maintains links between associated contracts. It also automates account and contract calls to enforce source VM asset burn or lock, and target VM token mint or unlock. + +Developers who want to use the Cross-VM Bridge must use a Cadence transaction. Cross-VM bridging functionality is not currently available natively in Flow EVM. By extension, this means that the EVM account bridging from EVM to Cadence must be a [`CadenceOwnedAccount` (COA)] as this is the only EVM account type that can be controlled from the Cadence runtime. + +This [FLIP-233] outlines the architecture and implementation of the VM bridge. An additional [FLIP-318] describes how developers can create custom associations between NFTs they define and control in each VM. + +This document will focus on how to use the Cross-VM Bridge and considerations for fungible and non-fungible token projects that deploy to either Cadence or EVM. + +## Deployments + +You can find the core bridge contracts at the following addresses: + +| Contracts | Testnet | Mainnet | +| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| All Cadence Bridge contracts | [`0xdfc20aee650fcbdf`] | [`0x1e4aa0b87d10b141`] | +| `FlowEVMBridgeFactory.sol` | [`0xf8146b4aef631853f0eb98dbe28706d029e52c52`] | [`0x1c6dea788ee774cf15bcd3d7a07ede892ef0be40`] | +| `FlowEVMBridgeDeploymentRegistry.sol` | [`0x8781d15904d7e161f421400571dea24cc0db6938`] | [`0x8fdec2058535a2cb25c2f8cec65e8e0d0691f7b0`] | +| `FlowEVMBridgedERC20Deployer.sol` | [`0x4d45CaD104A71D19991DE3489ddC5C7B284cf263`] | [`0x49631Eac7e67c417D036a4d114AD9359c93491e7`] | +| `FlowEVMBridgedERC721Deployer.sol` | [`0x1B852d242F9c4C4E9Bb91115276f659D1D1f7c56`] | [`0xe7c2B80a9de81340AE375B3a53940E9aeEAd79Df`] | + +And below are the bridge escrow's EVM addresses. These addresses are COAs and are stored stored in the same Flow account +as you'll find the Cadence contracts (see above). + +| Network | Address | +| ------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| Testnet | [`0x0000000000000000000000023f946ffbc8829bfd`] | +| Mainnet | [`0x00000000000000000000000249250a5c27ecab3b`] | + +## Interact With the Bridge + +:::info + +All bridging activity in either direction is orchestrated via Cadence on COA EVM accounts. This means that all bridging activity must be initiated via a Cadence transaction, not an EVM transaction, regardless of the directionality of the bridge request. For more information on the interplay between Cadence and EVM, see [How Flow EVM Works]. + +::: + +## Overview + +The Flow EVM bridge allows both fungible and non-fungible tokens to move atomically between Cadence and EVM. In EVM, fungible tokens are defined as ERC20 tokens, and non-fungible tokens as ERC721 tokens. In Cadence, fungible tokens are defined by contracts that implement [the `FungibleToken` interface] and non-fungible tokens implement [the `NonFungibleToken` interface]. You can find full guides to create these projects [here]. + +Like all operations on Flow, there are native fees associated with both computation and storage. To prevent spam and sustain the bridge account's storage consumption, fees are charged to both onboard assets and bridge assets. In the case where storage consumption is expected, fees are charged based on the storage consumed at the current network storage rate. + +## Onboard your token to the bridge + +For the purpose of this guide, we assume that the developer already deployed a token smart contract to their preferred VM (Flow-Cadence or Flow-EVM) and wants to bridge it to the other (target) VM. + +For the developer to use their token in the target VM, there must be a contract that defines the asset and how it behaves in the target VM that also allows the bridge to fulfill the asset from Cadence to EVM and vice versa. This contract is separate from the contract in the native VM, but they are "associated" with each other by the mechanisms of the Flow VM bridge. + +To create this association, the asset must be "onboarded" to the bridge before bridging operations can be fulfilled. This can happen in two ways: + +### Option 1: automatic onboarding + +Any user registers the native token contract with the bridge and the bridge deploys a basic templated version of the contract in the target VM. This basic contract is automatically associated with the native contract and is used for bridging. The developer has no direct control over this bridge-deployed contract because the bridge controls it. + +This method is covered in the [Automatic Onboarding Section]. + +### Option 2: custom association onboarding + +With this option (available for only for NFTs), developers can deploy their own contract to the target VM and declare a custom association between it and the native contract. This allows them to have more control over both contracts, which lets them to include more sophisticated features and mechanisms in their bridged token contracts such as ERC-721C, unique metadata views, and more that aren't included in the default bridged template versions. + +This method is covered in the [Custom Association Section]. + +:::info + +Before you continue to onboard your token, review the [Prep Your Assets for Bridging] section of this document. This describes some steps you should follow to make sure that your native asset or bridged asset are properly set up for you to register them with the bridge. + +::: + +## Automatic onboarding + +To move from a Cadence-native asset to EVM, automatic onboarding can occur on the fly, where a template contract deploys in the same transaction as the asset is bridged to EVM if the transaction so specifies. + +To move from EVM to Cadence, however, requires that onboarding occur in a separate transaction due to the fact that a Cadence contract is initialized at the end of a transaction and isn't available in the runtime until after the transaction has executed. + +Below are transactions relevant to automatically onboarding assets native to either VM: + +**Automatically Onboard a Cadence-native asset:** + +
+onboard_by_type.cdc + +```cadence onboard_by_type.cdc +!from https://raw.githubusercontent.com/onflow/flow-evm-bridge/main/cadence/transactions/bridge/onboarding/onboard_by_type.cdc +``` + +
+ +**Automatically Onboard an EVM-native asset:** + +
+onboard_by_evm_address.cdc + +```cadence onboard_by_evm_address.cdc +!from https://raw.githubusercontent.com/onflow/flow-evm-bridge/main/cadence/transactions/bridge/onboarding/onboard_by_evm_address.cdc +``` + +
+ +## Custom association onboarding + +With [Custom Associations], developers can deploy NFT contracts in both VMs and associate them with each other, which allows them to retain control of the contracts in both VMs as well as implement custom use-case specific functionality. + +To do this, each contract must implement a special interface that tells the bridge what the associated contract is in the other VM. The fact that both point to each other validates the intended association, which prevents spoofing. If the contracts do not point to each other this way, you can't register them as a custom association. + +Review the [Preparing Custom Associations] section to learn how to set up each of your contracts for a custom association. + +Below is the transaction for onboarding NFTs for a custom association. Remember that both the Cadence and the Solidity contract need to be deployed and include the special interface conformances to point to each other before registration! + +**Onboard an NFT Custom Association:** + +
+register_cross_vm_nft.cdc + +```cadence onboard_by_type.cdc +!from https://github.com/onflow/flow-evm-bridge/blob/flip-318/cadence/transactions/bridge/onboarding/register_cross_vm_nft.cdc +``` + +
+ +## Bridging + +After an asset gets onboarded, either by automatic or custom association, it can be bridged in either direction, referred to by its Cadence type. For Cadence-native assets, this is simply its native type. + +For EVM-native assets, this is in most cases a templated Cadence contract deployed to the bridge account, the name of which is derived from the EVM contract address. For instance, an ERC721 contract at address `0x1234` would be onboarded to the bridge as +`EVMVMBridgedNFT_0x1234`, making its type identifier `A..EVMVMBridgedNFT_0x1234.NFT`. + +To get the type identifier for a given NFT, you can use the following code: + +```cadence +// Where `nft` is either a @{NonFungibleToken.NFT} or &{NonFungibleToken.NFT} +nft.getType().identifier +``` + +You may also retrieve the type associated with a given EVM contract address with the following script: + +
+ +get_associated_type.cdc + +```cadence get_associated_type.cdc +!from https://github.com/onflow/flow-evm-bridge/blob/main/cadence/scripts/bridge/get_associated_type.cdc +``` + +
+ +Alternatively, given some onboarded Cadence type, you can retrieve the associated EVM address with the following script: + +
+ +get_associated_address.cdc + +```cadence get_associated_address.cdc +!from https://github.com/onflow/flow-evm-bridge/blob/main/cadence/scripts/bridge/get_associated_evm_address.cdc +``` + +
+ +#### NFTs + +Any Cadence NFTs that bridge to EVM are escrowed in the bridge account and either minted in a bridge-deployed ERC721 contract or transferred from escrow to the calling COA in EVM. On the return trip, NFTs are escrowed in EVM - owned by the bridge's COA - and either unlocked from escrow if locked or minted from a bridge-owned NFT contract. + +Below are transactions relevant to bridging NFTs: + +
+ +bridge_nft_to_evm.cdc + +```cadence bridge_nft_to_evm.cdc +!from https://raw.githubusercontent.com/onflow/flow-evm-bridge/main/cadence/transactions/bridge/nft/bridge_nft_to_evm.cdc +``` + +
+ +
+ +bridge_nft_from_evm.cdc + +```cadence bridge_nft_from_evm.cdc +!from https://raw.githubusercontent.com/onflow/flow-evm-bridge/main/cadence/transactions/bridge/nft/bridge_nft_from_evm.cdc +``` + +
+ +#### Fungible tokens + +Any Cadence fungible tokens that bridge to EVM are escrowed in the bridge account only if they are Cadence-native. If the bridge defines the tokens, they are burned. On the return trip the pattern is similar, as the bridge burns bridge-defined tokens or escrows them if they are EVM-native. In all cases, if the bridge has authority to mint on one side, it must escrow on the other as the native VM contract is owned by an external party. + +With fungible tokens in particular, there may be some cases where the Cadence contract is not deployed to the bridge account, but the bridge still follows a mint/burn pattern in Cadence. These cases are handled via [`TokenHandler`] implementations. Also know that moving $FLOW to EVM is built into the `EVMAddress` object so any requests to bridge $FLOW to EVM will simply leverage this interface; however, you must move $FLOW from EVM to Cadence through the COA resource. + +Below are transactions relevant to bridging fungible tokens: + +
+ +bridge_tokens_to_evm.cdc + +```cadence bridge_tokens_to_evm.cdc +!from https://raw.githubusercontent.com/onflow/flow-evm-bridge/main/cadence/transactions/bridge/tokens/bridge_tokens_to_evm.cdc +``` + +
+ +
+ +bridge_tokens_from_evm.cdc + +```cadence bridge_tokens_from_evm.cdc +!from https://raw.githubusercontent.com/onflow/flow-evm-bridge/main/cadence/transactions/bridge/tokens/bridge_tokens_from_evm.cdc +``` + +
+ +## Prep your assets for bridging + +### Context + +To maximize utility to the ecosystem, this bridge is permissionless and open to any fungible or non-fungible token as defined by the respective Cadence standards and limited to ERC20 and ERC721 Solidity standards. Ultimately, a project does not have to do anything for users to bridge their assets between VMs. However, there are some considerations developers may take to enhance the representation of their assets in non-native VMs. These largely relate to asset metadata and ensuring that bridging does not compromise critical user assumptions about asset ownership. + +### EVMBridgedMetadata + +Proposed in [@onflow/flow-nft/pull/203], the `EVMBridgedMetadata` view presents a mechanism to both represent metadata from bridged EVM assets as well as allow Cadence-native projects to specify the representation of their assets in EVM. It isn't required to implement this view to bridge asets, but the bridge does default to it when available as a way to provide projects greater control over their EVM asset definitions within the scope of ERC20 and ERC721 standards. + +The interface for this view is as follows: + +```cadence +access(all) struct URI: MetadataViews.File { + /// The base URI prefix, if any. Not needed for all URIs, but helpful + /// for some use cases For example, updating a whole NFT collection's + /// image host easily + access(all) let baseURI: String? + /// The URI string value + /// NOTE: this is set on init as a concatenation of the baseURI and the + /// value if baseURI != nil + access(self) let value: String + + access(all) view fun uri(): String + +} + +access(all) struct EVMBridgedMetadata { + access(all) let name: String + access(all) let symbol: String + + access(all) let uri: {MetadataViews.File} +} +``` + +This uri value could be a pointer to some offchain metadata if you expect your metadata to be static. Or you could couple the `uri()` method with the utility contract below to serialize the onchain metadata on the fly. Alternatively, you may choose to host a metadata proxy which serves the requested token URI content. + +### SerializeMetadata + +The key consideration with respect to metadata is the distinct metadata storage patterns between ecosystem. It's critical for NFT utility that the metadata be bridged in addition to the representation of the NFTs ownership. However, it's commonplace for Cadence NFTs to store metadata onchain while EVM NFTs often store an onchain pointer to metadata stored offchain. + +For Cadence NFTs to be properly represented in EVM platforms, the metadata must be bridged in a format expected by those platforms and be done in a manner that also preserves the atomicity of bridge requests. The path forward on this was decided to be a commitment of serialized Cadence NFT metadata into formats popular in the EVM ecosystem. + +For assets that do not implement `EVMBridgedMetadata`, the bridge will attempt to serialize the metadata of the asset as a JSON data URL string. This is done via the [`SerializeMetadata` contract] which serializes metadata values into a JSON blob compatible with the OpenSea metadata standard. The serialized metadata is then committed as the ERC721 `tokenURI` upon bridging Cadence-native NFTs to EVM. Since Cadence NFTs can easily update onchain metadata either by field or by the ownership of sub-NFTs, this serialization pattern allows token URI updates on subsequent bridge requests. + +### Prepar custom associations + +If you are a developer who wants to deploy and manage NFT contracts in both VMs and have tokens from each be exchangable for each other, you'll have to add some code to your contracts which indicate that they each represent the same token in their respective VMs so they point to each other. + +For the purposes of these instructions, an NFT is native to a VM if that VM is the main source of truth for the contracts and where they are originally minted. + +This feature is not available for Fungible Tokens at the moment, but may be in the future. + +:::warning + +The bridge only supports a single custom association declaration. This means that once you register an association between your Cadence NFT & EVM contract, the association cannot be updated. If you wish to retain some upgradeability to your registered implementations, we recommend that you both retain keys on your Cadence NFT contract account **and ** implement an upgradeable Solidity pattern when deploying your ERC721, then register the association between your Cadence NFT Type & ERC721 proxy (not the implementation address). + +::: + +#### Cadence + +All Cadence NFT contracts implement [Metadata Views] that return metadata about their NFTs in standard ways via the `{Contract}.resolveContractView()` and `{NFT}.resolveView()` methods. + +The following new view (`CrossVMMetadataViews.EVMPointer`) **must** be resolved at the contract level (`ViewResolver.resolveContractView()`) for a given Type **and** at the NFT level (`ViewResolver.Resolver.resolveView()`) + +```cadence +/// View resolved at contract & resource level pointing to the associated EVM implementation +access(all) struct EVMPointer { + /// The associated Cadence Type + access(all) let cadenceType: Type + /// The defining Cadence contract address + access(all) let cadenceContractAddress: Address + /// The associated EVM contract address + access(all) let evmContractAddress: EVM.EVMAddress + /// Whether the asset is Cadence- or EVM-native + access(all) let isCadenceNative: Bool +} +``` + +This view allows a Cadence contract to specify which Solidity contract it is associated with. + +You can see an example of how this view is implemented in [the `ExampleNFT` contract] in the Flow Non-Fungible Token repo. + +If your EVM contract expects metadata to be passed from Cadence at the time of bridging, you must implement the `CrossVMMetadataViews.EVMBytesMetadata` view. You'll find this useful for Cadence-native NFTs with dynamic metadata. This view will be resolved by the bridge and passed to your EVM contract when the `fulfillToEVM` method is called. + +How you handle the bridged bytes in your ERC721 implementation will be a matter of overriding the `_beforeFulfillment` and/or `_afterFulfillment` hooks included in the `CrossVMBridgeERC721Fulfillment` base contract. + +**Flow EVM-Native NFTs** + +If the NFT being onboarded to the bridge is native to Flow-EVM, then the associated contract's minter resource must implement the `FlowEVMBridgeCustomAssociationTypes.NFTFulfillmentMinter` interface: + +```cadence +/// Resource interface used by EVM-native NFT collections allowing for the fulfillment of NFTs from EVM into Cadence + /// + access(all) resource interface NFTFulfillmentMinter { + /// Getter for the type of NFT that's fulfilled by this implementation + /// + access(all) view fun getFulfilledType(): Type + + /// Called by the VM bridge when moving NFTs from EVM into Cadence if the NFT is not in escrow. Since such NFTs + /// are EVM-native, they are distributed in EVM. On the Cadence side, those NFTs are handled by a mint & escrow + /// pattern. On moving to EVM, the NFTs are minted if not in escrow at the time of bridging. + /// + /// @param id: The id of the token being fulfilled from EVM + /// + /// @return The NFT fulfilled from EVM as its Cadence implementation + /// + access(FulfillFromEVM) + fun fulfillFromEVM(id: UInt256): @{NonFungibleToken.NFT} { + pre { + id <= UInt256(UInt64.max): + "The requested ID \(id.toString()) exceeds the maximum assignable Cadence NFT ID \(UInt64.max.toString())" + } + post { + UInt256(result.id) == id: + "Resulting NFT ID \(result.id.toString()) does not match requested ID \(id.toString())" + result.getType() == self.getFulfilledType(): + "Expected \(self.getFulfilledType().identifier) but fulfilled \(result.getType().identifier)" + } + } + } +``` + +You can see an example of an implementation of this interface in the [Flow EVM bridge repo ExampleNFT contract]. + +A Capability with the `FulfillFromEVM` entitlement is required at the time of registration so the bridge can fulfill NFTs bridged from EVM for the first time. + +#### Solidity + +For custom associations, the following interface **must** be implemented in the IERC721-conforming Solidity contract. + +This provides functionality to point to the address and type of the associated Cadence NFT. + +```solidity +interface ICrossVM { + /** + * Returns the Cadence address defining the associated type + */ + function getCadenceAddress() external view returns (string memory); + /** + * Returns the Cadence Type identifier associated with the EVM contract + */ + function getCadenceIdentifier() external view returns (string memory); +} +``` + +As an example, [`ICrossVM` is already implemented] and in use in the bridged [ERC721] and [ERC20] templates. + +If you want to register a custom association for an NFT that is native to Cadence, which means that your project distributes NFTs to users on the Cadence side, then your ERC721 contract must implement the `CrossVMBridgeERC721Fulfillment` contract. This is a required conformance that does three primary things: + +1. Implements the mint/escrow pattern expected by the VM bridge. +2. Allows for the passing of arbitrary abi-encodable metadata from the Cadence NFT at the time of bridging. +3. Exposes two optional hooks, which allows you to update the fulfilled token's URI with the provided metadata at the time of bridging. + +Here is the Solidity contract to implement: + +```solidity +abstract contract CrossVMBridgeERC721Fulfillment is ICrossVMBridgeERC721Fulfillment, CrossVMBridgeCallable, ERC721 { + + /** + * Initializes the bridge EVM address such that only the bridge COA can call privileged methods + */ + constructor(address _vmBridgeAddress) CrossVMBridgeCallable(_vmBridgeAddress) {} + + /** + * @dev Fulfills the bridge request, minting (if non-existent) or transferring (if escrowed) the + * token with the given ID to the provided address. For dynamic metadata handling between + * Cadence & EVM, implementations should override and assign metadata as encoded from Cadence + * side. If overriding, be sure to preserve the mint/escrow pattern as shown in the default + * implementation. See `_beforeFulfillment` and `_afterFulfillment` hooks to enable pre-and/or + * post-processing without the need to override this function. + * + * @param _to address of the token recipient + * @param _id the id of the token being moved into EVM from Cadence + * @param _data any encoded metadata passed by the corresponding Cadence NFT at the time of + * bridging into EVM + */ + function fulfillToEVM(address _to, uint256 _id, bytes memory _data) external onlyVMBridge { + _beforeFulfillment(_to, _id, _data); // hook allowing implementation to perform pre-fulfillment validation + if (_ownerOf(_id) == address(0)) { + _mint(_to, _id); // Doesn't exist, mint the token + } else { + // Should be escrowed under vm bridge - transfer from escrow to recipient + _requireEscrowed(_id); + safeTransferFrom(vmBridgeAddress(), _to, _id); + } + _afterFulfillment(_to, _id, _data); // hook allowing implementation to perform post-fulfillment processing + emit FulfilledToEVM(_to, _id); + } + + /** + * @dev Returns whether the token is currently escrowed under custody of the designated VM bridge + * + * @param _id the ID of the token in question + */ + function isEscrowed(uint256 _id) public view returns (bool) { + return _ownerOf(_id) == vmBridgeAddress(); + } + + /** + * @dev Returns whether the token is exists or not defined positively by whether the owner of + * the token is 0x0. + * + * @param _id the ID of the token in question + */ + function exists(uint256 _id) public view returns (bool) { + return _ownerOf(_id) != address(0); + } + + /** + * @dev Allows a caller to determine the contract conforms to implemented interfaces + */ + function supportsInterface(bytes4 interfaceId) public view virtual override(CrossVMBridgeCallable, ERC721, IERC165) returns (bool) { + return interfaceId == type(ICrossVMBridgeERC721Fulfillment).interfaceId + || interfaceId == type(ICrossVMBridgeCallable).interfaceId + || super.supportsInterface(interfaceId); + } + + /** + * @dev Internal method that reverts with FulfillmentFailedTokenNotEscrowed if the provided + * token is not escrowed with the assigned vm bridge address as owner. + * + * @param _id the token id that must be escrowed + */ + function _requireEscrowed(uint256 _id) internal view { + if (!isEscrowed(_id)) { + revert FulfillmentFailedTokenNotEscrowed(_id, vmBridgeAddress()); + } + } + + /** + * @dev This internal method is included as a step implementations can override and have + * executed in the default fullfillToEVM call. + * + * @param _to address of the pending token recipient + * @param _id the id of the token to be moved into EVM from Cadence + * @param _data any encoded metadata passed by the corresponding Cadence NFT at the time of + * bridging into EVM + */ + function _beforeFulfillment(address _to, uint256 _id, bytes memory _data) internal virtual { + // No-op by default, meant to be overridden by implementations + } + + /** + * @dev This internal method is included as a step implementations can override and have + * executed in the default fullfillToEVM call. + * + * @param _to address of the pending token recipient + * @param _id the id of the token to be moved into EVM from Cadence + * @param _data any encoded metadata passed by the corresponding Cadence NFT at the time of + * bridging into EVM + */ + function _afterFulfillment(address _to, uint256 _id, bytes memory _data) internal virtual { + // No-op by default, meant to be overridden by implementations for things like processing + // and setting metadata + } +} +``` + +The `_beforeFulfillment()` and `_afterFulfillment()` hooks are `virtual`, which allows implementations to optionally override the methods and handle the provided metadata passed from your NFT if `EVMBytesMetadata` is resolved at the time of bridging. Also, notice that the `fulfillToEVM` method is `onlyVMBridge`, which allows the VM bridge to call the method either minting the NFT if it does not exist or transfer the NFT from escrow in a manner consistent with the bridge's mint/escrow pattern. + +### Opt Out + +It's also recognized that the logic of some use cases may actually be compromised by the act of bridging, particularly in such a unique partitioned runtime environment. Such cases might include those that do not maintain ownership assumptions implicit to ecosystem standards. + +For instance, an ERC721 implementation may reclaim a user's assets after a month of inactivity. In such a case, bridging that ERC721 to Cadence would decouple the representation of ownership of the bridged NFT from the actual ownership in the defining ERC721 contract after the token had been reclaimed - there would be no NFT in escrow for the bridge to transfer on fulfillment of the NFT back to EVM. In such cases, projects may choose to opt-out of bridging, but **importantly must do so before the asset has been onboarded to the bridge**. + +For Solidity contracts, opting out is as simple as extending the [`BridgePermissions.sol` abstract contract] which defaults `allowsBridging()` to `false`. The bridge explicitly checks for the implementation of `IBridgePermissions` and the value of `allowsBridging()` to validate that the contract has not opted out of bridging. + +Similarly, Cadence contracts can implement the [`IBridgePermissions.cdc` contract interface]. This contract has a single method `allowsBridging()` with a default implementation returning `false`. Again, the bridge explicitly checks for the implementation of `IBridgePermissions` and the value of `allowsBridging()` to validate that the contract has not opted out of bridging. Should you later choose to turn on bridging, you can simply override the default implementation and return `true`. + +In both cases, `allowsBridging()` gates onboarding to the bridge. After the onboard occurs - **a permissionless operation anyone can execute** - the value of `allowsBridging()` is irrelevant and assets can move between VMs permissionlessly. + +## Under the hood + +For an in-depth look at the high-level architecture of the bridge, see [FLIP #237] + +### Additional resources + +For the current state of Flow EVM across various task paths, see the following resources: + +- [Flow EVM Equivalence forum post] +- [EVM Integration FLIP #223] +- [Gateway & JSON RPC FLIP #235] + + + + +[Flow EVM Equivalence forum post]: https://forum.flow.com/t/evm-equivalence-on-flow-proposal-and-path-forward/5478 +[EVM Integration FLIP #223]: https://github.com/onflow/flips/pull/225/files +[Gateway & JSON RPC FLIP #235]: https://github.com/onflow/flips/pull/235) +[FLIP #237]: https://github.com/onflow/flips/blob/main/application/20231222-evm-vm-bridge.md +[`IBridgePermissions.cdc` contract interface]: https://github.com/onflow/flow-evm-bridge/blob/main/cadence/contracts/bridge/interfaces/IBridgePermissions.cdc +[`BridgePermissions.sol` abstract contract]: https://github.com/onflow/flow-evm-bridge/blob/main/solidity/src/interfaces/BridgePermissions.sol +[`ICrossVM` is already implemented]: https://github.com/onflow/flow-evm-bridge/blob/main/solidity/src/interfaces/ICrossVM.sol +[ERC721]: https://github.com/onflow/flow-evm-bridge/blob/flip-318/solidity/src/templates/FlowEVMBridgedERC721.sol#L37-L43 +[ERC20]: https://github.com/onflow/flow-evm-bridge/blob/flip-318/solidity/src/templates/FlowEVMBridgedERC20.sol#L13-L40 +[Flow EVM bridge repo ExampleNFT contract]: https://github.com/onflow/flow-evm-bridge/blob/flip-318/cadence/contracts/example-assets/cross-vm-nfts/ExampleEVMNativeNFT.cdc#L352-L377 +[the `ExampleNFT` contract]: https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc#L173-L195 +[Metadata Views]: ../../build/cadence/advanced-concepts/metadata-views.md +[`SerializeMetadata` contract]: https://github.com/onflow/flow-evm-bridge/blob/main/cadence/contracts/utils/SerializeMetadata.cdc +[@onflow/flow-nft/pull/203]: https://github.com/onflow/flow-nft/pull/203 +[`TokenHandler`]: https://github.com/onflow/flow-evm-bridge/blob/main/cadence/contracts/bridge/interfaces/FlowEVMBridgeHandlerInterfaces.cdc +[Preparing Custom Associations]: #preparing-custom-associations +[Custom Associations]: https://github.com/onflow/flips/blob/main/application/20250131-cross-vm-nft-support.md +[Automatic Onboarding Section]: #automatic-onboarding +[Custom Association Section]: #custom-association-onboarding +[Prep Your Assets for Bridging]: #prep-your-assets-for-bridging +[How Flow EVM Works]: ../../build/evm/how-it-works.md +[the `FungibleToken` interface]: https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc +[the `NonFungibleToken` interface]: https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc) +[here]: ../tokens/nft-cadence.md) +[`0xdfc20aee650fcbdf`]: https://contractbrowser.com/account/0xdfc20aee650fcbdf/contracts +[`0x1e4aa0b87d10b141`]: https://contractbrowser.com/account/0x1e4aa0b87d10b141/contracts) +[`0xf8146b4aef631853f0eb98dbe28706d029e52c52`]: https://evm-testnet.flowscan.io/address/0xF8146B4aEF631853F0eB98DBE28706d029e52c52) +[`0x1c6dea788ee774cf15bcd3d7a07ede892ef0be40`]: https://evm.flowscan.io/address/0x1C6dEa788Ee774CF15bCd3d7A07ede892ef0bE40) +[`0x8781d15904d7e161f421400571dea24cc0db6938`]: https://evm-testnet.flowscan.io/address0x8781d15904d7e161f421400571dea24cc0db6938 +[`0x8fdec2058535a2cb25c2f8cec65e8e0d0691f7b0`]: https://evm.flowscan.io/address/0x8FDEc2058535A2Cb25C2f8ceC65e8e0D0691f7B0) +[`0x4d45CaD104A71D19991DE3489ddC5C7B284cf263`]: https://evm-testnet.flowscan.io/address/0x4d45CaD104A71D19991DE3489ddC5C7B284cf263 +[`0x49631Eac7e67c417D036a4d114AD9359c93491e7`]: https://evm.flowscan.io/address/0x49631Eac7e67c417D036a4d114AD9359c93491e7 +[`0x1B852d242F9c4C4E9Bb91115276f659D1D1f7c56`]: https://evm-testnet.flowscan.io/address/0x1B852d242F9c4C4E9Bb91115276f659D1D1f7c56 +[`0xe7c2B80a9de81340AE375B3a53940E9aeEAd79Df`]: https://evm.flowscan.io/address/0xe7c2B80a9de81340AE375B3a53940E9aeEAd79Df +[`0x0000000000000000000000023f946ffbc8829bfd`]: https://evm-testnet.flowscan.io/address/0x0000000000000000000000023f946FFbc8829BFD +[`0x00000000000000000000000249250a5c27ecab3b`]: https://evm.flowscan.io/address/0x00000000000000000000000249250a5C27Ecab3B +[`CadenceOwnedAccount` (COA)]: interacting-with-coa.md +[FLIP-233]: https://github.com/onflow/flips/pull/233 +[FLIP-318]: https://github.com/onflow/flips/blob/main/application/20250131-cross-vm-nft-support.md +[Cross-VM Bridge]: https://www.github.com/onflow/flow-evm-bridge \ No newline at end of file diff --git a/docs/evm/guides/foundry.md b/docs/blockchain-development-tutorials/evm/development-tools/foundry.md similarity index 69% rename from docs/evm/guides/foundry.md rename to docs/blockchain-development-tutorials/evm/development-tools/foundry.md index 79fc791d9b..42ca041e0d 100644 --- a/docs/evm/guides/foundry.md +++ b/docs/blockchain-development-tutorials/evm/development-tools/foundry.md @@ -7,14 +7,14 @@ sidebar_position: 5 # Using Foundry with Flow -Foundry is a suite of development tools that simplifies the process of developing and deploying Solidity contracts to EVM networks. This guide will walk you through the process of deploying a Solidity contract to Flow EVM using the Foundry development toolchain. You can check out the official Foundry docs [here](https://book.getfoundry.sh/). +Foundry is a suite of development tools that simplifies the process to develop and deploy Solidity contracts to EVM networks. This guide will walk you through how to deploy a Solidity contract to Flow EVM with the Foundry development toolchain. You can check out the official [Foundry docs]. In this guide, we'll deploy an ERC-20 token contract to Flow EVM using Foundry. We'll cover: -- Developing and testing a basic ERC-20 contract -- Deploying the contract to Flow EVM using Foundry tools -- Querying Testnet state -- Mutating Testnet state by sending transactions +- How to develop and test a basic ERC-20 contract +- Deploy the contract to Flow EVM with Foundry tools +- How to query the Testnet state +- How to mutate Testnet state by sending transactions ## Overview @@ -26,17 +26,17 @@ To use Flow across all Foundry tools you need to: --rpc-url https://testnet.evm.nodes.onflow.org ``` -2. Use the `--legacy` flag to disable [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) style transactions. Flow will support EIP-1559 soon and this flag won't be needed. +2. Use the `--legacy` flag to turn off [EIP-1559] style transactions. Flow will support EIP-1559 soon and this flag won't be needed. -As an example, we'll show you how to deploy a fungible token contract to Flow EVM using Foundry. You will see how the above flags are used in practice. +As an example, we'll show you how to deploy a fungible token contract to Flow EVM with Foundry. You will see how the above flags are used in practice. -## Example: Deploying an ERC-20 Token Contract to Flow EVM +## Example: Deploy an ERC-20 Token Contract to Flow EVM -ERC-20 tokens are the most common type of tokens on Ethereum. We'll use [OpenZeppelin](https://www.openzeppelin.com/) starter templates with Foundry on Flow Testnet to deploy our own token called `MyToken`. +ERC-20 tokens are the most common type of tokens on Ethereum. We'll use [OpenZeppelin] starter templates with Foundry on Flow Testnet to deploy our own token called `MyToken`. ### Installation -The best way to install Foundry, is to use the `foundryup` CLI tool. You can get it using the following command: +The best way to install Foundry, is to use the `foundryup` CLI tool. You can get it with the following command: ```shell curl -L https://foundry.paradigm.xyz | bash @@ -52,17 +52,17 @@ This will install the Foundry tool suite: `forge`, `cast`, `anvil`, and `chisel` You may need to reload your shell after `foundryup` installation. -Check out the official [Installation](https://book.getfoundry.sh/getting-started/installation) guide for more information about different platforms or installing specific versions. +Check out the official [Installation Guide] for more information about different platforms or how to install specific versions. -### Wallet Setup +### Wallet setup -We first need to generate a key pair for our EVM account. We can do this using the `cast` tool: +We first need to generate a key pair for our EVM account. We can do this with the `cast` tool: ```shell cast wallet new ``` -`cast` will print the private key and address of the new account. We can then paste the account address into the [Faucet](https://faucet.flow.com/fund-account) to fund it with some Testnet FLOW tokens. +`cast` will print the private key and address of the new account. We can then paste the account address into the [Faucet] to fund it with some Testnet FLOW tokens. You can verify the balance of the account after funding. Replace `$YOUR_ADDRESS` with the address of the account you funded: @@ -70,7 +70,7 @@ You can verify the balance of the account after funding. Replace `$YOUR_ADDRESS` cast balance --ether --rpc-url https://testnet.evm.nodes.onflow.org $YOUR_ADDRESS ``` -### Project Setup +### Project setup First, create a new directory for your project: @@ -93,9 +93,9 @@ forge test The tests should pass. -### Writing the ERC-20 Token Contract +### Write the ERC-20 token contract -We'll use the OpenZeppelin ERC-20 contract template. We can start by adding OpenZeppelin to our project: +We'll use the OpenZeppelin ERC-20 contract template. To start, we'll add OpenZeppelin to our project: ```shell forge install OpenZeppelin/openzeppelin-contracts @@ -117,7 +117,7 @@ contract MyToken is ERC20 { The above is a basic ERC-20 token with the name `MyToken` and symbol `MyT`. It also mints the specified amount of tokens to the contract deployer. The amount is passed as a constructor argument during deployment. -Before compiling, we also need to update the test file. +Before we comnpile, we also need to update the test file. ### Testing @@ -191,7 +191,7 @@ contract MyTokenTest is Test { } ``` -You can now make sure everything is okay by compiling the contracts: +To make sure everything is okay, compile the contracts: ```shell forge compile @@ -205,9 +205,9 @@ forge test They should all succeed. -### Deploying to Flow Testnet +### Deploy to Flow Testnet -We can now deploy `MyToken` using the `forge create` command. We need to provide the RPC URL, private key from a funded account using the faucet, and constructor arguments that is the initial mint amount in this case. We need to use the `--legacy` flag to disable EIP-1559 style transactions. Replace `$DEPLOYER_PRIVATE_KEY` with the private key of the account you created earlier: +We can now deploy `MyToken` with the `forge create` command. We need to provide the RPC URL, private key from a funded account with the faucet, and constructor arguments that is the initial mint amount in this case. We need to use the `--legacy` flag to turn off EIP-1559 style transactions. Replace `$DEPLOYER_PRIVATE_KEY` with the private key of the account you created earlier: ```shell forge create --broadcast src/MyToken.sol:MyToken \ @@ -219,9 +219,9 @@ forge create --broadcast src/MyToken.sol:MyToken \ The above will print the deployed contract address. We'll use it in the next section to interact with the contract. -### Verifying a Smart Contract +### Verify a smart contract -Once deployed, you can verify the contract so that others can see the source code and interact with it from Flow's block explorer. You can use the [`forge verify-contract`](https://book.getfoundry.sh/reference/forge/forge-verify-contract) command: +After you deploy the contract, you can verify it so that others can see the source code and interact with it from Flow's block explorer. You can use the [`forge verify-contract`] command: ```shell forge verify-contract --rpc-url https://testnet.evm.nodes.onflow.org/ \ @@ -229,15 +229,15 @@ forge verify-contract --rpc-url https://testnet.evm.nodes.onflow.org/ \ --verifier-url https://evm-testnet.flowscan.io/api \ $DEPLOYED_MYTOKEN_ADDRESS \ src/MyToken.sol:MyToken -```` +``` :::info -When verifying a Mainnet contract, be sure to use the Mainnet [RPC](../../evm/networks.md) and block explorer URLs. +When you verify a Mainnet contract, be sure to use the Mainnet [RPC] and block explorer URLs. ::: -### Querying Testnet State +### Query Testnet state Based on the given constructor arguments, the deployer should own `42,000,000 MyT`. We can check the `MyToken` balance of the contract owner. Replace `$DEPLOYED_MYTOKEN_ADDRESS` with the address of the deployed contract and `$DEPLOYER_ADDRESS` with the address of the account you funded earlier: @@ -248,7 +248,7 @@ cast balance \ $DEPLOYER_ADDRESS ``` -This should return the amount specified during deployment. We can also call the associated function directly in the contract: +This will return the amount specified during deployment. We can also call the associated function directly in the contract: ```shell cast call $DEPLOYED_MYTOKEN_ADDRESS \ @@ -265,9 +265,9 @@ cast call $DEPLOYED_MYTOKEN_ADDRESS \ "symbol()(string)" ``` -### Sending Transactions +### Send Transactions -Let's create a second account and move some tokens using a transaction. You can use `cast wallet new` to create a new test account. You don't need to fund it to receive tokens. Replace `$NEW_ADDRESS` with the address of the new account: +Let's create a second account and move some tokens with a transaction. You can use `cast wallet new` to create a new test account. You don't need to fund it to receive tokens. Replace `$NEW_ADDRESS` with the address of the new account: ```shell cast send $DEPLOYED_MYTOKEN_ADDRESS \ @@ -287,7 +287,7 @@ cast balance \ $NEW_ADDRESS ``` -The deployer should also own less tokens now: +The deployer will also own fewer tokens now: ```shell cast balance \ @@ -295,3 +295,13 @@ cast balance \ --erc20 $DEPLOYED_MYTOKEN_ADDRESS \ $DEPLOYER_ADDRESS ``` + + + +[Foundry docs]: https://book.getfoundry.sh/) +[EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559 +[OpenZeppelin]: https://www.openzeppelin.com/ +[Installation Guide]: https://book.getfoundry.sh/getting-started/installation +[Faucet]: https://faucet.flow.com/fund-account +[`forge verify-contract`]: https://book.getfoundry.sh/reference/forge/forge-verify-contract +[RPC]: ../../../build/evm/networks.md \ No newline at end of file diff --git a/docs/evm/guides/hardhat.md b/docs/blockchain-development-tutorials/evm/development-tools/hardhat.md similarity index 76% rename from docs/evm/guides/hardhat.md rename to docs/blockchain-development-tutorials/evm/development-tools/hardhat.md index ed268b6ebf..f860967f2c 100644 --- a/docs/evm/guides/hardhat.md +++ b/docs/blockchain-development-tutorials/evm/development-tools/hardhat.md @@ -7,15 +7,15 @@ sidebar_position: 2 # Flow Hardhat Guide -Hardhat is an Ethereum development tool designed to facilitate the deployment, testing, and debugging of smart contracts. It provides a streamlined experience for developers working with Solidity contracts. +Hardhat is an Ethereum development tool designed to facilitate the deployment, testing, and debugging of Solidity smart contracts. It provides a streamlined experience for developers who work with with Solidity contracts. ## Prerequisites ### Node -Node v18 or higher, available for [download here](https://nodejs.org/en/download). +Node v18 or higher, available for [download here]. -For those new to Hardhat, we recommend exploring the [official documentation](https://hardhat.org/tutorial/creating-a-new-hardhat-project) to get acquainted. The following instructions utilize `npm` to initialize a project and install dependencies: +For those new to Hardhat, we recommend that you exploare the [official Hardhat documentation] to get acquainted. The following instructions use `npm` to initialize a project and install dependencies: ### Wallet @@ -34,13 +34,13 @@ npx hardhat init > When prompted, select TypeScript and to use `@nomicfoundation/hardhat-toolbox` to follow along with this guide. -### Fund Your Wallet +### Fund Your wallet -To deploy smart contracts, ensure your wallet has **$FLOW**. Obtain funds by navigating to the Flow [Faucet](https://faucet.flow.com/fund-account) and entering your wallet address. +To deploy smart contracts, ensure your wallet has **$FLOW**. To obtain funds, navigate to the Flow [Faucet] and enter your wallet address. -## Deploying a Smart Contract with Hardhat +## Deploy a smart contract with Hardhat -This section guides you through the process of deploying smart contracts on the Flow network using Hardhat. +This section guides you through the process of how to deploy smart contracts on the Flow network with Hardhat. ### Configuration @@ -64,11 +64,11 @@ const config: HardhatUserConfig = { export default config; ``` -To keep this example straightforward, we've included the account's private key directly in `hardhat.config.ts`. However, it is crucial to avoid committing private keys to your Git repository for security reasons. Instead, opt for using environment variables for safer handling of sensitive information. +To keep this example straightforward, we've included the account's private key directly in `hardhat.config.ts`. However, it is crucial to not commit private keys to your Git repository for security reasons. Instead, use environment variables to safely handle sensitive information. -### Deploying HelloWorld Smart Contract +### Deploy HelloWorld smart contract -## HelloWorld Smart Contract +## HelloWorld smart contract ```solidity // SPDX-License-Identifier: MIT @@ -98,7 +98,7 @@ contract HelloWorld { } ``` -Deploying: +Deploy: 1. Create a file named `HelloWorld.sol` under `contracts` directory. 2. Add above `HelloWorld.sol` contract code to new file. @@ -129,7 +129,7 @@ main() 5. Run `npx hardhat run scripts/deploy.ts --network testnet` in the project root. 6. Copy the deployed `HelloWorld` address. This address will be used in other scripts. -Output should look like this (with the exception that your address will be different): +Output will look like this (with the exception that your address will be different): ```shell ❯ npx hardhat run scripts/deploy.ts --network testnet @@ -137,9 +137,9 @@ Deploying contracts with the account: ... HelloWorld address: 0x3Fe94f43Fb5CdB8268A801f274521a07F7b99dfb ``` -You can now search for your deployed contract on the [Flowscan block explorer](https://evm-testnet.flowscan.io/)! +You can now search for your deployed contract on the [Flowscan] block explorer! -### Get HelloWorld Contract Greeting +### Get HelloWorld contract greeting Now, we want to get the greeting from the deployed `HelloWorld` smart contract. @@ -172,16 +172,16 @@ main().catch((error) => { Steps: 1. Create a `getGreeting.ts` file in the `scripts` directory. -2. Paste contents of script above. Make sure to update the contract address with the one from deployment in earlier step. +2. Paste contents of script above. Make sure to update the contract address with the one from deployment in an earlier step. 3. Call script to get the greeting, `npx hardhat run scripts/getGreeting.ts --network testnet` -4. The output should be as follows: +4. The output will be as follows: ```shell ❯ npx hardhat run scripts/getGreeting.ts --network testnet The greeting is: Hello, World! ``` -### Update Greeting on HelloWorld Smart Contract +### Update greeting on HelloWorld smart contract Next, we'll add a script to update the greeting and log it. @@ -231,7 +231,7 @@ Here are the steps to follow: 1. Create an `updateGreeting.ts` script in the `scripts` directory. 2. Paste in the TypeScript above, make sure to update the contract address with the one from deployment in earlier step. 3. Call the new script, `NEW_GREETING='Howdy!' npx hardhat run ./scripts/updateGreeting.ts --network testnet` -4. The output should be +4. The output will be: ```shell ❯ NEW_GREETING='Howdy!' npx hardhat run ./scripts/updateGreeting.ts --network testnet @@ -242,9 +242,9 @@ The greeting is: Howdy! ``` -### Verifying Contract +### Verify contract -To verify your contract on [Flowscan](https://evm-testnet.flowscan.io/), you can update your Hardhat config file as such including the correct chainID, apiURL and browserURL: +To verify your contract on [Flowscan], you can update your Hardhat config file. To do this, include the correct chainID, apiURL and browserURL: ```javascript import { HardhatUserConfig } from 'hardhat/config'; @@ -286,8 +286,16 @@ const config: HardhatUserConfig = { export default config; ``` -The [verify](https://docs.blockscout.com/developer-support/verifying-a-smart-contract/hardhat-verification-plugin) plugin requires you to include constructor arguments with the verify task and ensures that they correspond to expected ABI signature. However, Blockscout ignores those arguments, so you may specify any values that correspond to the ABI. Execute the following command to verify the contract: +The [verify] plugin requires you to include constructor arguments with the verify task and ensures that they correspond to expected ABI signature. However, Blockscout ignores those arguments, so you may specify any values that correspond to the ABI. Execute the following command to verify the contract: ```shell npx hardhat verify --network testnet DEPLOYED_CONTRACT_ADDRESS "Constructor argument 1" -``` \ No newline at end of file +``` + + + +[download here]: https://nodejs.org/en/download +[official Hardhat documentation]: https://hardhat.org/tutorial/creating-a-new-hardhat-project +[Faucet]: https://faucet.flow.com/fund-account +[Flowscan]: https://evm-testnet.flowscan.io/ +[verify]: https://docs.blockscout.com/developer-support/verifying-a-smart-contract/hardhat-verification-plugin \ No newline at end of file diff --git a/docs/evm/guides/Remix-adding-metamask-network.gif b/docs/blockchain-development-tutorials/evm/development-tools/imgs/Remix-adding-metamask-network.gif similarity index 100% rename from docs/evm/guides/Remix-adding-metamask-network.gif rename to docs/blockchain-development-tutorials/evm/development-tools/imgs/Remix-adding-metamask-network.gif diff --git a/docs/evm/guides/Remix-call-getGreeting.gif b/docs/blockchain-development-tutorials/evm/development-tools/imgs/Remix-call-getGreeting.gif similarity index 100% rename from docs/evm/guides/Remix-call-getGreeting.gif rename to docs/blockchain-development-tutorials/evm/development-tools/imgs/Remix-call-getGreeting.gif diff --git a/docs/evm/guides/Remix-deploy-contract-flowevm.gif b/docs/blockchain-development-tutorials/evm/development-tools/imgs/Remix-deploy-contract-flowevm.gif similarity index 100% rename from docs/evm/guides/Remix-deploy-contract-flowevm.gif rename to docs/blockchain-development-tutorials/evm/development-tools/imgs/Remix-deploy-contract-flowevm.gif diff --git a/docs/evm/guides/Remix-update-greeting.gif b/docs/blockchain-development-tutorials/evm/development-tools/imgs/Remix-update-greeting.gif similarity index 100% rename from docs/evm/guides/Remix-update-greeting.gif rename to docs/blockchain-development-tutorials/evm/development-tools/imgs/Remix-update-greeting.gif diff --git a/docs/blockchain-development-tutorials/evm/development-tools/index.md b/docs/blockchain-development-tutorials/evm/development-tools/index.md new file mode 100644 index 0000000000..b3e136d02e --- /dev/null +++ b/docs/blockchain-development-tutorials/evm/development-tools/index.md @@ -0,0 +1,43 @@ +--- +title: Flow EVM Development Tools +description: Comprehensive guides for using popular Solidity development tools and IDEs to build, test, and deploy smart contracts on Flow EVM. +sidebar_position: 3 +keywords: + - Flow EVM + - development tools + - Solidity development + - smart contract deployment + - Foundry + - Hardhat + - Remix IDE + - contract testing + - blockchain development +--- + +# Flow EVM Development Tools + +Professional smart contract development requires robust tools to write, test, deploy, and manage Solidity contracts. This section covers the most popular and powerful development tools in the Ethereum ecosystem, adapted for Flow EVM development. From command-line frameworks to browser-based IDEs, these tools provide everything you need for comprehensive smart contract development workflows. + +Each tool offers unique strengths: Foundry excels at testing and gas optimization, Hardhat provides extensive plugin ecosystems and TypeScript support, while Remix allows you to rapidly prototype without local setup. These tutorials demonstrate how to configure and use each tool effectively with Flow EVM, which allows you to choose the right development environment for your project needs. + +## [Foundry] + +Master Foundry's powerful suite of development tools for advanced Solidity contract development, testing, and deployment on Flow EVM. This comprehensive guide covers how to set up Foundry projects, write and test ERC-20 contracts with extensive test coverage, and deploy to Flow networks with proper configuration and verification. Learn to leverage Foundry's forge, cast, and anvil tools for complete development workflows, which include contract interaction and state management. + +## [Hardhat] + +Build and deploy Solidity smart contracts on Flow EVM with Hardhat's comprehensive development environment with TypeScript support and extensive plugins. This tutorial walks through complete project setup, network configuration for Flow testnet and mainnet, contract deployment with custom scripts, and contract verification on Flow's block explorer. You'll implement end-to-end workflows for HelloWorld contract development, testing, and deployment using Hardhat's powerful plugin ecosystem. + +## [Remix] + +Develop and deploy smart contracts directly in the browser with Remix IDE with Flow EVM integration for rapid prototyping and development. This guide demonstrates how to set up Remix for Flow development, deploying contracts through MetaMask integration, and how to interact with deployed contracts with Remix's built-in debugging and interaction tools. Learn to use Remix for quick contract development, testing, and deployment without local development environment setup requirements. + +## Conclusion + +These development tool guides provide comprehensive coverage of the most popular Solidity development environments, each optimized for Flow EVM development. Whether you prefer command-line tools like Foundry, comprehensive frameworks like Hardhat, or browser-based development with Remix, these tutorials offer practical workflows to build, test, and deploy professional smart contracts on Flow's high-performance EVM network. + + + +[Foundry]: ./foundry.md +[Hardhat]: ./hardhat.md +[Remix]: ./remix.md diff --git a/docs/evm/guides/remix.md b/docs/blockchain-development-tutorials/evm/development-tools/remix.md similarity index 69% rename from docs/evm/guides/remix.md rename to docs/blockchain-development-tutorials/evm/development-tools/remix.md index 2b9e57e456..5471060fba 100644 --- a/docs/evm/guides/remix.md +++ b/docs/blockchain-development-tutorials/evm/development-tools/remix.md @@ -7,23 +7,23 @@ sidebar_position: 3 # Using Remix -Remix is an open-source, web-based development environment tailored for EVM smart contract development. It offers developers a comprehensive suite of tools for writing, deploying, and testing smart contracts in Solidity. For more information, visit [Remix](https://remix.ethereum.org/). +Remix is an open-source, web-based development environment tailored for EVM smart contract development. It offers developers a comprehensive suite of tools to write, deploy, and test smart contracts in Solidity. For more information, visit [Remix]. -## Add the Flow Network to MetaMask +## Add the Flow network to MetaMask -![Add Flow Network](./Remix-adding-metamask-network.gif) +![Add Flow Network](./imgs/Remix-adding-metamask-network.gif) -Navigate to the [Using EVM](../using.mdx) page to find the button to add the Flow network information to your metamask. +Navigate to the [Using EVM] page to find the button to add the Flow network information to your metamask. ## Fund Your Flow Account -Navigate to the [Flow Testnet Faucet](https://faucet.flow.com/fund-account) to obtain FLOW tokens necessary for deploying a smart contract. +Navigate to the [Flow Testnet Faucet] to obtain FLOW tokens necessary to deploy a smart contract. -## Deploying a Smart Contract Using Remix +## Deploy a smart contract with Remix -![Deploy Smart Contract](./Remix-deploy-contract-flowevm.gif) +![Deploy smart contract](./imgs/Remix-deploy-contract-flowevm.gif) -### HelloWorld Smart Contract +### HelloWorld smart contract ```solidity // SPDX-License-Identifier: MIT @@ -55,7 +55,7 @@ contract HelloWorld { ``` -### Steps to Deploy the HelloWorld Smart Contract +### Steps to deploy the HelloWorld smart contract 1. Create a file named `HelloWorld.sol`. 2. Select Solidity Compiler and compile `HelloWorld.sol`. @@ -63,11 +63,11 @@ contract HelloWorld { 4. Make sure to select `Injected Provider - Metamask` in Environment dropdown. 5. Deploy the `HelloWorld` smart contract. -## Calling the Deployed Smart Contract +## Call the Deployed Smart Contract -![Call Smart Contract](./Remix-call-getGreeting.gif) +![Call Smart Contract](./imgs/Remix-call-getGreeting.gif) -### Using Ethers.js to Call the HelloWorld Smart Contract +### Use Ethers.js to Call the HelloWorld Smart Contract 1. Create a new `get-greeting.js` file under `scripts`. 2. Paste in the JavaScript code below. @@ -104,14 +104,20 @@ getGreeting(); Follow the steps below to change the greeting and retrieve the new greeting. -## Updating the Deployed Smart Contract +## Updating the deployed smart contract -![Update Smart Contract](./Remix-update-greeting.gif) +![Update smart contract](./imgs/Remix-update-greeting.gif) 1. Select the `HelloWorld.sol` file. 2. Select the `Deploy and Run Transaction` page. 3. Make sure to select `Injected Provider - Metamask` in Environment dropdown. -4. Type a new greeting in the text input next to orange `changeGreeting` button. -5. Click on the orange `changeGreeting` button. +4. Type a new greeting in the text input next to `changeGreeting`. +5. Click `changeGreeting`. 6. Sign the Metamask transaction. -7. Verify the greeting has changed by re-running `get-greeting.js` script above. +7. To verify the greeting changed, re-run the `get-greeting.js` script above. + + + +[Remix]: https://remix.ethereum.org/ +[Flow Testnet Faucet]: https://faucet.flow.com/fund-account +[Using EVM]: ../../../build/evm/using.mdx \ No newline at end of file diff --git a/docs/evm/guides/ethers.md b/docs/blockchain-development-tutorials/evm/frameworks/ethers.md similarity index 50% rename from docs/evm/guides/ethers.md rename to docs/blockchain-development-tutorials/evm/frameworks/ethers.md index 6d679f8fdc..e4f741ea81 100644 --- a/docs/evm/guides/ethers.md +++ b/docs/blockchain-development-tutorials/evm/frameworks/ethers.md @@ -1,20 +1,20 @@ --- title: Ethers.js on Flow Blockchain sidebar_label: Ethers -sidebar_position: 8 +sidebar_position: 1 --- # Ethers.js -[ethers.js](https://docs.ethers.org/v5/) is a powerful JavaScript library for interacting with Ethereum and other EVM-compatible blockchain networks. +[ethers.js] is a powerful JavaScript library for interacting with Ethereum and other EVM-compatible blockchain networks. -In this guide, we'll walk you through how to use ethers.js to interact with smart contracts on the Flow Blockchain. +In this guide, we'll walk you through how to use `ethers.js` to interact with smart contracts on the Flow Blockchain. --- ## Installation -To begin using ethers.js in your project, you'll need to install the package. You can do this by running the following command: +To use `ethers.js` in your project, you'll first need to install the package. To do this, run the following command: ```bash bashCopy code @@ -24,17 +24,17 @@ npm install --save ethers ## Setup -After installing ethers.js, the next step is to import it into your project. +After you install `ethers.js`, the next step is to import it into your project. -You can do this by adding the following line of code at the beginning of your JavaScript file: +To do this, add the following line of code at the beginning of your JavaScript file: ```jsx const ethers = require('ethers'); ``` -## Connecting to Flow +## Connect to Flow -To connect to the Flow Blockchain using ethers.js, you need to create a new `JsonRpcProvider` instance with the appropriate RPC URL for Flow: +To connect to the Flow Blockchain with `ethers.js`, you need to create a new `JsonRpcProvider` instance with the appropriate RPC URL for Flow: ```jsx const ethers = require('ethers'); @@ -43,11 +43,11 @@ const url = 'https://testnet.evm.nodes.onflow.org/'; const provider = new ethers.providers.JsonRpcProvider(url); ``` -**Note:** If you want to connect to the Flow testnet, replace the above URL with `https://mainnet.evm.nodes.onflow.org`. +**Note:** If you want to connect to the Flow mainnet, replace the above URL with `https://mainnet.evm.nodes.onflow.org`. -## Reading Data from the Blockchain +## Read data from the Blockchain -Once your provider is set up, you can start reading data from the Flow Blockchain. For instance, to retrieve the latest block number, you can use the `getBlockNumber` method: +After you set up your provider, you can start reading data from the Flow Blockchain. For instance, to retrieve the latest block number, you can use the `getBlockNumber` method: ```jsx async function getLatestBlock() { @@ -56,9 +56,9 @@ async function getLatestBlock() { } ``` -## Writing Data to the Blockchain +## Write data to the Blockchain -To send transactions or write data to the Flow Blockchain, you need to create a `Signer`. This can be done by initializing a new `Wallet` object with your private key and the previously created `Provider`: +To send transactions or write data to the Flow Blockchain, you need to create a `Signer`. To do this, initialize a new `Wallet` object with your private key and the previously created `Provider`: ```jsx const privateKey = 'YOUR_PRIVATE_KEY'; @@ -67,9 +67,9 @@ const signer = new ethers.Wallet(privateKey, provider); **Note:** Replace `'YOUR_PRIVATE_KEY'` with the actual private key of the wallet you want to use. -## Interacting with Smart Contracts +## Interact with smart contracts -ethers.js also enables interaction with smart contracts on the Flow Blockchain. To do this, create a `Contract` object using the ABI (Application Binary Interface) and the address of the deployed contract: +ethers.js also allows interaction with smart contracts on the Flow Blockchain. To do this, create a `Contract` object using the Application Binary Interface (ABI) and the address of the deployed contract: ```jsx const abi = [ @@ -91,7 +91,7 @@ const contract = new ethers.Contract(contractAddress, abi, signer); **Note:** Replace `'CONTRACT_ADDRESS'` with the actual address of your deployed contract. -After setting up your `Contract` object, you can call methods on the smart contract as needed: +After you set up your `Contract` object, you can call methods on the smart contract as needed: ```jsx async function setValue(value) { @@ -104,3 +104,7 @@ async function getValue() { console.log(value.toString()); } ``` + + + +[ethers.js]: https://docs.ethers.org/v5/ diff --git a/docs/evm/guides/Connect-Metamask.gif b/docs/blockchain-development-tutorials/evm/frameworks/imgs/Connect-Metamask.gif similarity index 100% rename from docs/evm/guides/Connect-Metamask.gif rename to docs/blockchain-development-tutorials/evm/frameworks/imgs/Connect-Metamask.gif diff --git a/docs/evm/guides/Update-HelloWorld-Greeting.gif b/docs/blockchain-development-tutorials/evm/frameworks/imgs/Update-HelloWorld-Greeting.gif similarity index 100% rename from docs/evm/guides/Update-HelloWorld-Greeting.gif rename to docs/blockchain-development-tutorials/evm/frameworks/imgs/Update-HelloWorld-Greeting.gif diff --git a/docs/evm/guides/rainbowkit-1.png b/docs/blockchain-development-tutorials/evm/frameworks/imgs/rainbowkit-1.png similarity index 100% rename from docs/evm/guides/rainbowkit-1.png rename to docs/blockchain-development-tutorials/evm/frameworks/imgs/rainbowkit-1.png diff --git a/docs/evm/guides/rainbowkit-2.png b/docs/blockchain-development-tutorials/evm/frameworks/imgs/rainbowkit-2.png similarity index 100% rename from docs/evm/guides/rainbowkit-2.png rename to docs/blockchain-development-tutorials/evm/frameworks/imgs/rainbowkit-2.png diff --git a/docs/blockchain-development-tutorials/evm/frameworks/index.md b/docs/blockchain-development-tutorials/evm/frameworks/index.md new file mode 100644 index 0000000000..cc6220a27d --- /dev/null +++ b/docs/blockchain-development-tutorials/evm/frameworks/index.md @@ -0,0 +1,49 @@ +--- +title: Flow EVM Frameworks +description: Learn how to integrate popular JavaScript and React frameworks with Flow EVM for building modern blockchain applications with familiar tools. +sidebar_position: 2 +keywords: + - Flow EVM + - JavaScript frameworks + - React frameworks + - ethers.js + - web3.js + - wagmi + - viem + - RainbowKit + - blockchain libraries + - frontend development +--- + +# Flow EVM Frameworks + +Modern blockchain development relies on powerful JavaScript and React frameworks that simplify smart contract interactions and provide seamless user experiences. This section covers the most popular frontend frameworks and libraries that you can use to build Flow EVM applications, from low-level blockchain interaction libraries to high-level React components for wallet management and user interfaces. + +These frameworks allow developers to build sophisticated decentralized applications with familiar JavaScript and React patterns while leveraging Flow's high-performance EVM environment. Whether you want to build simple contract interfaces or complex multi-wallet applications, these tutorials provide practical implementation guidance for you to integrate proven blockchain development frameworks with Flow EVM. + +## [Ethers.js] + +Discover how to use `ethers.js`, the most popular JavaScript library for blockchain interactions, to connect with Flow EVM and manage smart contracts. This guide covers provider setup, how to read blockchain data, how to write transactions with proper signers, and how to implement both read-only queries and state-changing operations. Learn to leverage ethers.js's intuitive interface for comprehensive Flow EVM contract interactions. + +## [Web3.js] + +Master `web3.js` integration with Flow EVM for comprehensive smart contract development and blockchain interaction capabilities. This tutorial demonstrates how to initialize web3 instances with Flow endpoints, how to query blockchain state, how to manage accounts with private keys, and how to execute contract transactions. You'll work through practical examples, such as a complete Storage contract implementation with read and write operations. + +## [Viem & Wagmi] + +Build modern React applications on Flow EVM with wagmi and viem with built-in Flow network configurations and React hooks. This comprehensive guide walks through how to create `Next.js` applications with wallet connection capabilities, smart contract interactions with React hooks, and proper error handling for blockchain operations. Learn to implement complete dApps with wagmi's powerful React integration and viem's efficient blockchain interactions. + +## [RainbowKit] + +Integrate advanced wallet connection experiences into your Flow EVM applications using RainbowKit with custom Flow Wallet support. This tutorial demonstrates how to create custom wallet connectors, how to configure WalletConnect integration for seamless mobile and desktop connections, and how to implement comprehensive wallet onboarding flows. You'll build complete wallet connection interfaces that support Flow Wallet alongside other popular Ethereum wallets. + +## Conclusion + +These framework guides provide comprehensive coverage of the most popular JavaScript and React tools for Flow EVM development. From low-level blockchain interactions with ethers.js and web3.js to sophisticated React applications with wagmi and RainbowKit, these tutorials offer practical implementation patterns for you to build modern decentralized applications on Flow's EVM-compatible network. + + + +[Ethers.js]: ./ethers.md +[Web3.js]: ./web3-js.md +[Viem & Wagmi]: ./wagmi.md +[RainbowKit]: ./rainbowkit.md \ No newline at end of file diff --git a/docs/evm/guides/rainbowkit.md b/docs/blockchain-development-tutorials/evm/frameworks/rainbowkit.md similarity index 63% rename from docs/evm/guides/rainbowkit.md rename to docs/blockchain-development-tutorials/evm/frameworks/rainbowkit.md index 773b70fcc4..35f4aa1833 100644 --- a/docs/evm/guides/rainbowkit.md +++ b/docs/blockchain-development-tutorials/evm/frameworks/rainbowkit.md @@ -5,35 +5,37 @@ sidebar_position: 4 sidebar_label: Rainbowkit --- -Integrating Flow Wallet with [RainbowKit][1] allows users to seamlessly connect their Flow accounts through one of the most popular wallet connection interfaces. +# Using Rainbow Kit with FLow Wallet -This guide walks you through the process of defining Flow Wallet as a custom wallet in RainbowKit and testing the integration. You can follow along by setting up a new RainbowKit project or use the code in this guide to integrate these steps into your existing dApp. +When you integrate Flow Wallet with [RainbowKit][1], you can seamlessly connect your Flow accounts through one of the most popular wallet connection interfaces. + +This guide walks you through how to define Flow Wallet as a custom wallet in RainbowKit and testing the integration. As you follow along, you can set up up a new RainbowKit project or use the code in this guide to integrate these steps into your current dApp. ## Objectives -After completing this guide, you'll be able to: -- Create a custom Flow Wallet connector compatible with RainbowKit's interface -- Configure your Wagmi setup to support Flow Wallet connections -- Implement a complete wallet connection flow for Flow blockchain users -- Test and verify the Flow Wallet integration in your dApp +After you complete this guide, you'll be able to: +- Create a custom Flow Wallet connector compatible with RainbowKit's interface. +- Configure your Wagmi setup to support Flow Wallet connections. +- Implement a complete wallet connection flow for Flow blockchain users. +- Test and verify the Flow Wallet integration in your dApp. ## Prerequisites -### Next.js and Modern Frontend Development +### Next.js and modern frontend development -The RainbowKit starter is built on Next.js, so familiarity with React, hooks, and modern frontend development will help you follow along. +The RainbowKit starter is built on `Next.js`, so familiarity with React, hooks, and modern frontend development will help you follow along. ## A Flow Wallet To use Flow Wallet with RainbowKit, install the Flow Wallet browser extension from the [Chrome Web Store][2]. -Once installed, set up your wallet by creating or importing an account. For quick access, pin the extension to your browser toolbar. +After you install it, create or import an account to set up your wallet. For quick access, pin the extension to your browser toolbar. -## Setting Up Your Environment +## Set up your environment -### Initial Setup +### Initial setup -The RainbowKit starter is built on Next.js, following its standard project structure and conventions. Create a new project or ensure your existing one has the necessary dependencies: +The RainbowKit starter is built on`Next.js` and follows its standard project structure and conventions. Create a new project or ensure your current one has the necessary dependencies: ```bash $ npm init @rainbow-me/rainbowkit@latest @@ -41,10 +43,11 @@ $ cd my-rainbowkit-app $ npm run dev ``` -The [RainbowKit](https://www.rainbowkit.com/) components will be available throughout your application via the provided wrapper components. +The [RainbowKit] components are available throughout your application via the provided wrapper components. + +### Create the Flow Wallet connector -### Creating the Flow Wallet Connector -The first major step is defining the Flow Wallet connector. Create a new file called `flowWallet.ts` in `src/flowWallet.ts` to house the wallet configuration: +The first major step is to define the Flow Wallet connector. Create a new file called `flowWallet.ts` in `src/flowWallet.ts` to house the wallet configuration: ```tsx /* src/flowWallet.ts */ @@ -113,7 +116,7 @@ export const flowWallet = ({ projectId }: MyWalletOptions): Wallet => ({ }); ``` -### Configuring Wagmi Integration +### Configure your Wagmi integration Next, update your Wagmi configuration to include Flow Wallet support. Modify your `wagmi.ts` file: @@ -160,36 +163,39 @@ export const config = createConfig({ WalletConnect Project ID -Every dApp that relies on WalletConnect now needs to obtain a projectId from [WalletConnect Cloud (now rebranded as reown)](https://cloud.reown.com/sign-in). This is absolutely free and only takes a few minutes. +Every dApp that relies on WalletConnect now needs to obtain a projectId from [WalletConnect Cloud (now rebranded as reown)]. This is absolutely free and only takes a few minutes. To get a Project ID, sign up at WalletConnect Cloud, create a new project, and copy the generated ID into the `projectId` variable in the `wagmi.ts` file. ::: -## Testing Your Integration +## Test Your Integration -After implementing the Flow Wallet connector and configuring Wagmi, follow these steps to verify that the integration works correctly in your dApp: +After you implement the Flow Wallet connector and configure Wagmi, follow these steps to verify that the integration works correctly in your dApp: -1. **Click "Connect Wallet"** – Open your application and click the "Connect Wallet" button. -2. **Check for Flow Wallet** – Ensure Flow Wallet appears as an option in the RainbowKit wallet selection modal. - - If you haven't installed the browser extension and set up your wallet yet, you can find install it via the [Chrome Web Store][2]. -3. **Connect the Wallet** – Click on Flow Wallet in the selection modal. If using the browser extension, open it and press "Connect." +1. **Click "Connect Wallet"** – Open your application and click "Connect Wallet." +2. **Check for Flow Wallet** – Ensure Flow Wallet appears as an option in the RainbowKit wallet selection modal. If you haven't installed the browser extension and set up your wallet yet, you can find install it via the [Chrome Web Store][2]. +3. **Connect the Wallet** – Click on Flow Wallet in the selection modal. If you use the browser extension, open it and press "Connect." -![Rainbowkit dAPP UI](./rainbowkit-1.png) +![Rainbowkit dAPP UI](./imgs/rainbowkit-1.png) 4. **Verify Connection** – Confirm that your Flow Wallet is now connected and visible in your dApp's UI. -![Rainbowkit dAPP UI](./rainbowkit-2.png) +![Rainbowkit dAPP UI](./imgs/rainbowkit-2.png) ## Conclusion -In this tutorial, you learned how to integrate Flow Wallet with [RainbowKit](https://www.rainbowkit.com/), creating a seamless wallet connection experience for your users. You should now be able to: -- Create a custom Flow Wallet connector compatible with RainbowKit's interface -- Configure your Wagmi setup to support Flow Wallet connections -- Implement a complete wallet connection flow for Flow blockchain users -- Test and verify the Flow Wallet integration in your dApp +In this tutorial, you learned how to integrate Flow Wallet with [RainbowKit] and create a seamless wallet connection experience for your users. You should now be able to: +- Create a custom Flow Wallet connector compatible with RainbowKit's interface. +- Configure your Wagmi setup to support Flow Wallet connections. +- Implement a complete wallet connection flow for Flow blockchain users. +- Test and verify the Flow Wallet integration in your dApp. Now that you've completed this tutorial, you're ready to enhance your dApp with additional Flow blockchain features such as token transfers, NFT minting, and smart contract interactions. + + [1]: https://www.rainbowkit.com/ -[2]: https://chromewebstore.google.com/detail/flow-wallet/hpclkefagolihohboafpheddmmgdffjm?hl=en \ No newline at end of file +[2]: https://chromewebstore.google.com/detail/flow-wallet/hpclkefagolihohboafpheddmmgdffjm?hl=en +[RainbowKit]: https://www.rainbowkit.com/ +[WalletConnect Cloud (now rebranded as reown)]: https://cloud.reown.com/sign-in) \ No newline at end of file diff --git a/docs/evm/guides/wagmi.md b/docs/blockchain-development-tutorials/evm/frameworks/wagmi.md similarity index 68% rename from docs/evm/guides/wagmi.md rename to docs/blockchain-development-tutorials/evm/frameworks/wagmi.md index 88be0f66d9..d79326f7d3 100644 --- a/docs/evm/guides/wagmi.md +++ b/docs/blockchain-development-tutorials/evm/frameworks/wagmi.md @@ -2,16 +2,16 @@ title: Viem & Wagmi description: 'Using Wagmi to interact with Solidity contract to Flow EVM.' sidebar_label: Viem & Wagmi -sidebar_position: 4 +sidebar_position: 3 --- :::info Make sure to use `viem` version `2.9.6` or greater. This version contains flow EVM networks ::: -# Using viem +# Viem & Wagmi -Flow networks have been added to viem chain definitions [viem networks](https://github.com/wevm/viem/tree/main/src/chains/definitions). This allows for convenient flow network configuration when using viem and wagmi. +Flow networks have been added to viem chain definitions [viem networks]. This allows for convenient flow network configuration when you use viem and wagmi. ## Viem Flow Config @@ -31,19 +31,20 @@ export const config = createConfig({ }); ``` -# Using Next.js and Wagmi +# Use Next.js and Wagmi -This tutorial will guide you through creating a simple web application, connect to an EVM capable wallet and interact with the "HelloWorld" smart contract to get and set greetings. We will not dive into managing transactions. +This tutorial will guide you through how to create a simple web application, connect to an EVM capable wallet and interact with the "HelloWorld" smart contract to get and set greetings. We will not dive into how to manage transactions. ## Prerequisites -- Node.js installed on your machine -- A code editor (e.g., Visual Studio Code) -- Basic knowledge of React and Next.js +- `Node.js` installed on your machine. +- A code editor (such as Visual Studio Code). +- Basic knowledge of React and `Next.js`. -## Step 1: Setting Up the Next.js Project +## Step 1: Set up the Next.js project + +This tutorial will follow the [Wagmi getting-started manual tutorial]. -This tutorial will be following [Wagmi getting-started manual tutorial](https://wagmi.sh/react/getting-started) First, let's create a Wagmi project named `flow-evm-wagmi`. We will use npm but you are welcome to use yarn or bun. ```bash @@ -61,10 +62,11 @@ cd flow-evm-wagmi npm install ``` -## Step 2: Configuring Wagmi and Connecting the Wallet +## Step 2: Configure Wagmi and connect the Wallet + +Make sure you have Metamask installed and Flow network configured. For more information, see [Metamask and Flow blockchain]. -Make sure you have Metamask installed and Flow network configured. [Metamask and Flow blockchain](/evm/using). -Wagmi needs to know what networks to be aware of. Let's configure to use Flow Testnet by updating config.ts file with the following: +Wagmi needs to know what networks to be aware of. Let's configure to use Flow Testnet and update the `config.ts` file with the following: ```javascript import { http, createConfig } from '@wagmi/core'; @@ -80,17 +82,17 @@ export const config = createConfig({ }); ``` -By default Wagmi configures many wallets, MetaMask, Coinbase Wallet, and WalletConnect as wallet providers. Above we simplify the code to only be interested in the Injected Provider, which we are interested in Metamask. Verify `page.tsx` code looks like the following. +By default, Wagmi configures many wallets, MetaMask, Coinbase Wallet, and WalletConnect as wallet providers. Above, we simplify the code to only be interested in the Injected Provider, which we are interested in Metamask. Verify `page.tsx` code looks like the following. ```javascript -'use client' +'use client'; -import { useAccount, useConnect, useDisconnect } from 'wagmi' +import { useAccount, useConnect, useDisconnect } from 'wagmi'; function App() { - const account = useAccount() - const { connectors, connect, status, error } = useConnect() - const { disconnect } = useDisconnect() + const account = useAccount(); + const { connectors, connect, status, error } = useConnect(); + const { disconnect } = useDisconnect(); return ( <> @@ -127,23 +129,21 @@ function App() {
{error?.message}
- ) + ); } -export default App - +export default App; ``` -![Connect Metamask](./Connect-Metamask.gif) +![Connect Metamask](./imgs/Connect-Metamask.gif) -This step relies on an already deployed HelloWorld contract. See [Using Remix](./remix.md) to deploy a smart contract on flow evm blockchain. -Create or edit the simple `page.tsx` file in the app directory to have better styles, that's beyond this tutorial. We will modify `page.txs` to add a new `HelloWorld.tsx`. Replace `YOUR_CONTRACT_ADDRESS` with your deployed address. +This step relies on an already deployed HelloWorld contract. See [Using Remix] to deploy a smart contract on flow evm blockchain. Create or edit the simple `page.tsx` file in the app directory to have better styles, that's beyond this tutorial. We will modify `page.txs` to add a new `HelloWorld.tsx`. Replace `YOUR_CONTRACT_ADDRESS` with your deployed address. -## Step 3: Creating the Interface for HelloWorld Contract +## Step 3: Create the interface for HelloWorld contract Now, let's create a component to interact with the HelloWorld contract. Assume your contract is already deployed, and you have its address and ABI. -- Create a new file, HelloWorld.ts, in the components directory. +- Create a new file, `HelloWorld.ts`, in the components directory. - Use Wagmi's hooks to read from and write to the smart contract: ```javascript @@ -196,7 +196,7 @@ const HelloWorld = () => { export default HelloWorld; ``` -Reminder: aReplace YOUR_CONTRACT_ADDRESS with the actual address of your deployed HelloWorld contract. +Replace YOUR_CONTRACT_ADDRESS with the actual address of your deployed HelloWorld contract. Also notice you need the HelloWorld contract ABI, save this to a new file called `HelloWorld.json` in the app directory. @@ -251,7 +251,7 @@ Also notice you need the HelloWorld contract ABI, save this to a new file called } ``` -## Step 4: Integrating the HelloWorld Component +## Step 4: Integrate the HelloWorld component Finally, import and use the HelloWorld component in your `pages.tsx`, throw it at the bottom of the render section. @@ -283,6 +283,14 @@ import HelloWorld from './helloWorld' Now, you have a functional App that can connect to Metamask, display the current greeting from the "HelloWorld" smart contract, and update the greeting. -Test it by updating the greeting, signing a transaction in your Metamask then wait a minute then refresh the website. Handling transactions are outside of this tutorial. We'll leave that as a future task. [Checkout Wagmi documentation](https://wagmi.sh/react/getting-started) +To test it, update the greeting, sign a transaction in your Metamask, wait a minute, then refresh the website. Handling transactions are outside of this tutorial. We'll leave that as a future task. [Checkout Wagmi documentation] + +![Update HelloWorld Greeting](./imgs/Update-HelloWorld-Greeting.gif) + + -![Update HelloWorld Greeting](./Update-HelloWorld-Greeting.gif) +[viem networks]: https://github.com/wevm/viem/tree/main/src/chains/definitions +[Wagmi getting-started manual tutorial]: https://wagmi.sh/react/getting-started +[Metamask and Flow blockchain]: ../../../build/evm/using.mdx +[Checkout Wagmi documentation]: https://wagmi.sh/react/getting-started +[Using Remix]: ../development-tools/remix.md \ No newline at end of file diff --git a/docs/evm/guides/web3-js.md b/docs/blockchain-development-tutorials/evm/frameworks/web3-js.md similarity index 64% rename from docs/evm/guides/web3-js.md rename to docs/blockchain-development-tutorials/evm/frameworks/web3-js.md index 801969dfe6..4bdbe959c6 100644 --- a/docs/evm/guides/web3-js.md +++ b/docs/blockchain-development-tutorials/evm/frameworks/web3-js.md @@ -1,19 +1,19 @@ --- title: Web3.js on Flow Blockchain sidebar_label: Web3.js -sidebar_position: 9 +sidebar_position: 2 --- # Web3.js -[Web3.js](https://web3js.org/) is a Javascript library for building on EVM-compatible networks. +[Web3.js] is a Javascript library for building on EVM-compatible networks. It allows developers to interact with smart contracts, send transactions, and retrieve data from the network. ## Prerequisites :::info -This guide assumes you have the latest version of [Node.js](https://nodejs.org/en) installed. +This guide assumes you have the latest version of [Node.js] installed. ::: To install `web3` in your project, run the following command: @@ -22,9 +22,9 @@ To install `web3` in your project, run the following command: npm install web3 ``` -## Initializing Web3 with Flow +## Initialize Web3 with Flow -To use `web3` in your project, start by importing the module and initializing your `Web3` instance with a Flow RPC endpoint. +To use `web3` in your project, first import the module and initialize your `Web3` instance with a Flow RPC endpoint. ```js const { Web3 } = require('web3'); @@ -33,11 +33,11 @@ const web3 = new Web3('https://testnet.evm.nodes.onflow.org'); **Note:** If you want to connect to the Flow testnet, replace the above URL with `https://mainnet.evm.nodes.onflow.org`. -## Querying The Blockchain +## Query The blockchain -`web3` provides a number of methods for querying the blockchain, such as getting the latest block number, querying account balances, and more. +`web3` provides a number of methods for how to query the blockchain, such as to retrieve the latest block number, query account balances, and more. -You can try using some of these methods to verify that your `web3` instance is working correctly. +You can try with some of these methods to verify that your `web3` instance works correctly. ```js // Get the latest block number @@ -57,15 +57,15 @@ const gasPrice = await web3.eth.getGasPrice(); console.log(gasPrice); // Gas price in attoFlow ``` -For more information about other queries you can make `web3`, please see the [official documentation](https://docs.web3js.org/). +For more information about other queries you can make `web3`, see the [Web3.js] official documentation. -## Interacting with Smart Contracts +## Interact with smart contracts The `web3` library allows developers to interact with smart contracts via the `web3.eth.Contract` API. For this example we will use the following `Storage` contract. -We recommend deploying your own contract, which can be done using [Hardhat](../guides/hardhat.md) or [Remix](../guides/remix.md). +We recommend that you deploy your own contract, which you can do with [Hardhat] or [Remix]. ```solidity // SPDX-License-Identifier: MIT @@ -84,7 +84,7 @@ contract Storage { } ``` -The ABI for this contract can be generated using the [`solc` compiler](https://docs.soliditylang.org/en/latest/installing-solidity.html), or another tool such as [Hardhat](../guides/hardhat.md) or [Remix](../guides/remix.md). +You can generate the ABI for this contract with the [`solc` compiler], or another tool such as [Hardhat]or [Remix]. Now that we have both the ABI and address of the contract, we can create a new `Contract` object for use in our application. @@ -131,11 +131,11 @@ const contractAddress = '0x4c7784ae96e7cfcf0224a95059573e96f03a4e70'; const contract = new web3.eth.Contract(abi, contractAddress); ``` -We can now interact with the contract on the network by using the `contract` object. +We can now interact with the contract on the network ith the `contract` object. -### Reading State +### Read state -State can be read from the contract by using the `call` function with one of the contract's methods. This will not change the state and will not send a transaction. +State can be read from the contract via the `call` function with one of the contract's methods. This will not change the state and will not send a transaction. ```js // Retrieve the current value stored in the contract @@ -145,22 +145,23 @@ const result = await contract.methods.retrieve().call(); console.log(result); // Current value stored in the contract ``` -### Changing State +### Change state -We can mutate the state of the contract by sending a transaction to the network. +To mutate the state of the contract, we can send a transaction to the network. In order to send a transaction to the network, you will need an account with sufficient funds to pay for the transaction. :::info -If you do not have an account yet, you can create one using the following command from your project's root directory: + +If you do not have an account yet, you can create one with the following command from your project's root directory: ```sh node -e "console.log(require('web3').eth.accounts.create())" ``` -Note that this is not a secure way to generate an account, and you should use a more secure method in a production environment. +This is not a secure way to generate an account, and you should use a more secure method in a production environment. -You can fund your account using the [Flow Faucet](https://faucet.flow.com/fund-account). +You can fund your account with the [Flow Faucet]. ::: We can use the `privateKeyToAccount` function to create an `Web3Account` object from our account's private key. @@ -170,7 +171,7 @@ We can use the `privateKeyToAccount` function to create an `Web3Account` object const account = web3.eth.accounts.privateKeyToAccount('0x1234'); ``` -Then, we can sign a transaction using the user's account and send it to the network. +Then, we can sign a transaction with the user's account and send it to the network. ```js const newValue = 1337; // Replace with any value you want to store @@ -193,11 +194,21 @@ const result = await web3.eth.sendSignedTransaction(signed.rawTransaction); console.log(result); ``` -Now that the transaction has been sent, the contract's state should have been updated. We can verify this by querying the contract's state again: +Now that the transaction was sent, the contract's state was updated. To verify this, we can query the contract's state again: ```js const result = await contract.methods.retrieve().call(); console.log(result); // New value stored in the contract ``` -For more information about using smart contracts in web3.js, see the [official documentation](https://docs.web3js.org/libdocs/Contract). +For more information about how to use smart contracts in web3.js, see the [official documentation]. + + + +[Web3.js]: https://web3js.org/ +[Node.js]: https://nodejs.org/en +[Flow Faucet]: https://faucet.flow.com/fund-account +[`solc` compiler]: https://docs.soliditylang.org/en/latest/installing-solidity.html +[Hardhat]: ../development-tools/hardhat.md) +[Remix]: ../development-tools/remix.md). +[official documentation]: https://docs.web3js.org/libdocs/Contract \ No newline at end of file diff --git a/docs/tutorials/flowtobooth/image-gallery.md b/docs/blockchain-development-tutorials/evm/image-gallery.md similarity index 83% rename from docs/tutorials/flowtobooth/image-gallery.md rename to docs/blockchain-development-tutorials/evm/image-gallery.md index b6caba0592..7bc2359b5a 100644 --- a/docs/tutorials/flowtobooth/image-gallery.md +++ b/docs/blockchain-development-tutorials/evm/image-gallery.md @@ -1,80 +1,84 @@ --- title: Build a Fully-Onchain Image Gallery description: Learn how to store images up to approximately 32kb onchain, on Flow EVM, easily - free with the Flow wallet, or sub-cent with any other wallet. -sidebar_position: 1 +sidebar_position: 4 keywords: - [ - Flow, - EVM, - Flow EVM, - storage, - Solidity, - Next.js, - React, - onchain storage, - base64, - image gallery, - smart contract, - blockchain, - gas efficiency, - web3, - dapp, - tutorial, - onchain app, - ] + - Flow + - EVM, + - Flow EVM, + - storage, + - Solidity, + - Next.js, + - React, + - onchain storage, + - base64, + - image gallery, + - smart contract, + - blockchain, + - gas efficiency, + - web3, + - dapp, + - tutorial, + - onchain app --- -# Build a Fully-Onchain Image Gallery +# Build a fully-onchain image gallery + +:::warning + +This tutorial has not been updated for the new [limit of 16 million gas per transaction] in Fusaka. It will still work, but you will need to resize the images to a maximum of about 160\*160 pixels. + +::: :::info -The [FlowtoBooth] tutorial series teaches you how to build a **fun benchmark app** and provides inspiration for the greater scope of possibilities building on Flow thanks to gas being so much less expensive. +The [FlowtoBooth] tutorial series teaches you how to build a **fun benchmark app** and provides inspiration for the greater scope of possibilities to build on Flow since gas is so much less expensive. It is **not a production best-practice**. While everything in these tutorials works, you'll run into the following problems at production scale: -- RPC Providers will likely rate-limit you for reading this much data at once -- NFT marketplaces may not display the images, likely due to the above -- 256\*256 images are huge by blockchain data standards, but too small for modern devices +- RPC Providers will likely rate-limit you for reading this much data at once. +- NFT marketplaces may not display the images, likely due to the above. +- 256\*256 images are huge by blockchain data standards, but too small for modern devices. ::: -If you search for resources on how to store images of any significant size onchain, you'll be told it's either prohibitively expensive or even completely impossible. The reason for this is two-fold - first the size limit for data on transactions is about 40kb. Second, saving 40kb takes almost all of the 30 million gas limit on most blockchains. +If you search for resources on how to store images of any significant size onchain, you'll be told it's either prohibitively expensive or even completely impossible. The reason for this is two-fold. First, the size limit for data on transactions is about 40kb. Second, to save 40kb takes almost all of the 30 million gas limit on most blockchains. -The former constraint is immutable (though many chains are slowly increasing this limit), which limits the app to images about 256\*256 pixels in size. The latter is heavily dependent on which chain you choose. +The former constraint is immutable (though many chains have started to slowly increase this limit), which limits the app to images about 256\*256 pixels in size. The latter heavily depends on which chain you choose. -At current gas prices on most chains, using all 30 million gas in a block costs **several dollars** - or potentially **thousands** on ETH mainnet. At current prices on Flow, spending 30 million gas costs **less than a penny**, usually 1 or 2 tenths of a cent. +At current gas prices on most chains, to use all 30 million gas in a block costs **several dollars** - or potentially **thousands** on ETH mainnet. At current prices on Flow, to spend 30 million gas costs **less than a penny**, usually one or two tenths of a cent. -Much more computation is available at prices you or your users will be willing to pay for regular interactions. Including, but not limited to: +Much more computation is available at prices you or your users will want to pay for regular interactions. This includes, but isn't limited to: -- Airdropping hundreds of NFTs with one transaction, for pennies -- Generation of large mazes -- Generating large amounts of random numbers (with free [native VRF]) -- Extensive string manipulation onchain -- Simple game AI logic +- Airdrop hundreds of NFTs with one transaction, for pennies. +- Generation of large mazes. +- Generation of large amounts of random numbers (with free [native VRF]). +- Extensive string manipulation onchain. +- Simple game AI logic. In this tutorial, we'll build a smart contract that can store and retrieve images onchain. We'll also build a simple frontend to interact with the contract on Flow and another chain. -![stage-1](stage-1.png) +![stage-1](./imgs/stage-1.png) ## Objectives -After completing this guide, you'll be able to: +After you complete this guide, you'll be able to: -- Construct a composable onchain image gallery that can be used permissionlessly by onchain apps and other contracts to store and retrieve images -- Build an onchain app that can interact with this contract to save and display images -- Compare the price of spending 30 million gas on Flow with the price on other chains +- Construct a composable onchain image gallery that can be used permissionlessly by onchain apps and other contracts to store and retrieve images. +- Build an onchain app that can interact with this contract to save and display images. +- Compare the price of when you spend 30 million gas on Flow with the price on other chains. ## Prerequisites -### Next.js and Modern Frontend Development +### Next.js and modern frontend development -This tutorial uses [Next.js]. You don't need to be an expert, but it's helpful to be comfortable with development using a current React framework. You'll be on your own to select and use a package manager, manage Node versions, and other frontend environment tasks. +This tutorial uses [Next.js]. You don't need to be an expert, but it's helpful to be comfortable with development in a current React framework. You'll be on your own to select and use a package manager, manage Node versions, and other frontend environment tasks. ### Solidity -You don't need to be an expert, but you should be comfortable writing code in [Solidity]. You can use [Hardhat], [Foundry], or even [Remix]. +You don't need to be an expert, but you should be comfortable enough to write code in [Solidity]. You can use [Hardhat], [Foundry], or even [Remix]. -## Build an Image Gallery Contract +## Build an image gallery contract Start a new smart contract project in the toolchain of your choice and install the [OpenZeppelin] contracts. @@ -93,11 +97,11 @@ contract ImageGallery is Ownable { } ``` -We're passing the original owner of the contract as an argument in the constructor to give greater flexibility for ownership when this contract is deployed. +We pass the original owner of the contract as an argument in the constructor to give greater flexibility for ownership when this contract is deployed. -### Set Up Storage for Images +### Set up storage for images -We'll store the images in a simple `struct` that holds the image as a `base64` encoded `string`and also contains a `string` for the description. Doing so allows the image to be directly used in html and makes it easier to test the contract directly with a block explorer, but has the downside of making the images 33% bigger. Another format would be more efficient. +We'll store the images in a simple `struct` that holds the image as a `base64` encoded `string`and also contains a `string` for the description. Doing so allows the image to be directly used in HTML and makes it easier to test the contract directly with a block explorer, but it also makes the images 33% bigger. Another format is more efficient. These will be held in array: @@ -110,7 +114,7 @@ struct Image { Image[] public images; ``` -### Construct Functions to Add and Delete Images +### Construct functions to add and delete images Next, add a function that accepts a `_description` and `_base64EncodedImage` and adds them to the array. @@ -139,13 +143,13 @@ function deleteImage(uint256 index) public onlyOwner { :::warning -If the array gets big enough that calling `deleteImage` takes more than 30 million gas, it will brick this function. A safer and more gas-efficient method is to use a `mapping` with a counter as the index, and handling for the case where an index is empty. +If the array gets big enough that for you to call `deleteImage` takes more than 30 million gas, it will brick this function. A safer and more gas-efficient method is to use a `mapping` with a counter as the index, and handling for the case where an index is empty. -We're doing it this way to provide a way to delete accidentally uploaded images without making things too complex. +We do it this way to provide a way to delete accidentally uploaded images without making things too complex. ::: -### Retrieval Functions +### Retrieval functions Finally, add functions to get one image, get all of the images, and get the number of images in the collection. @@ -166,9 +170,9 @@ function getImageCount() public view returns (uint256) { } ``` -### Final Contract +### Final contract -After completing the above, you'll end up with a contract similar to: +After you complete the above, you'll end up with a contract similar to: ```solidity // SPDX-License-Identifier: UNLICENSED @@ -223,7 +227,7 @@ contract ImageGallery is Ownable { ``` -### Create a Factory +### Create a factory The image gallery contract you've just constructed is intended to be a utility for other contracts and apps to use freely. You don't want just one gallery for everyone, you need to give the ability for any app or contract to create and deploy private galleries freely. @@ -245,11 +249,11 @@ contract ImageGalleryFactory { } ``` -### Tracking Factories +### Track factories -Some app designs may need multiple galleries for each user. For example, you might want to be able to give users the ability to collect images in separate galleries for separate topics, dates, or events, similar to how many photo apps work on smartphones. +Some app designs may need multiple galleries for each user. For example, you might want to give users the ability to collect images in separate galleries for separate topics, dates, or events, similar to how many photo apps work on smartphones. -To facilitate this feature, update your contract to keep track of which galleries have been created by which users. You'll end up with: +To facilitate this feature, update your contract to keep track of which users created which galleries . You'll end up with: ```solidity // SPDX-License-Identifier: UNLICENSED @@ -277,7 +281,7 @@ contract ImageGalleryFactory { } ``` -### Testing the Factory +### Test the factory Write appropriate unit tests, then deploy and verify the factory on Flow Testnet. @@ -289,19 +293,19 @@ If you need help, check out: Navigate to [evm-testnet.flowscan.io], search for your contract, and navigate to the `contracts` tab, then `Read/Write contract`. You'll see something similar to: -![Factory on Flowscan](factory-on-flowscan.png) +![Factory on Flowscan](./imgs/factory-on-flowscan.png) `Connect` your wallet. Use the [Flow Wallet] if you want automatically sponsored gas on both mainnet and testnet, or use the [Flow Faucet] to grab some testnet funds if you prefer to use another wallet. -Expand the `createImageGallery` function, click the `self` button, and then `Write` the function. +Expand the `createImageGallery` function, click `self`, and then `Write` the function. -![createImageGallery](create-image-gallery.png) +![createImageGallery](./imgs/create-image-gallery.png) Approve the transaction and wait for it to complete. Then, call `getGalleries` for your address to find the address of the gallery you've created. -### Testing the Image Gallery +### Test the image gallery -Search for the address of your image gallery contract. It `won't` be verified, but if you're using our exact contract, you will see a message from Flowscan that a verified contract with the same bytecode was found in the Blockscout DB. Click the provided link to complete the verification process. +Search for the address of your image gallery contract. It `won't` be verified, but if you use our exact contract, you will see a message from Flowscan that a verified contract with the same bytecode was found in the Blockscout DB. Click the provided link to complete the verification process. :::info @@ -323,13 +327,13 @@ Most sites of this nature are free tools created by helpful programmers and are Use the tool to convert an image that is ~30kb or smaller. Copy the string and paste it into the field in `addImage`. You can also add a `description`, but the bytes used will count towards the ~40kb limit. -![addImage](add-image.png) +![addImage](./imgs/add-image.png) Click `Write` and approve the transaction. Take note of the cost! You've saved an image onchain forever for just a little bit of gas! -Once the transaction goes through, call `getImage` with `0` as the index to retrieve your description and base64-encoded image. +After the transaction goes through, call `getImage` with `0` as the index to retrieve your description and base64-encoded image. -Paste your image string as the `src` for an `img` tag in an html snippet to confirm it worked. +Paste your image string as the `src` for an `img` tag in an HTML snippet to confirm it worked. ```html
@@ -339,9 +343,9 @@ Paste your image string as the `src` for an `img` tag in an html snippet to conf
``` -## Building the Frontend +## Build the frontend -Now that your contracts are sorted and working, it's time to build an app to interact with it. We'll use [Next.js] for this, but the components we provide will be adaptable to other React frameworks. +Now that your contracts are sorted and work, it's time to build an app to interact with it. We'll use [Next.js] for this, but the components we provide will be adaptable to other React frameworks. Run: @@ -349,7 +353,7 @@ Run: npx create-next-app ``` -We're using the default options. +We'll use' the default options. Next, install [rainbowkit], [wagmi], and their related dependencies: @@ -357,7 +361,7 @@ Next, install [rainbowkit], [wagmi], and their related dependencies: npm install @rainbow-me/rainbowkit wagmi viem@2.x @tanstack/react-query ``` -### Provider Setup +### Provider setup Add a file called `providers` inside the `app` folder. In it, add your config and providers for [wagmi] and [rainbowkit]. You'll need to [add the Flow Wallet] as a custom wallet. It's not included by default because it has special features that aren't compatible with other blockchains. @@ -479,9 +483,9 @@ export default function Providers({ children }: { children: React.ReactNode }) { } ``` -### Add the Connect Button +### Add the connect button -Open `page.tsx` and clear out the default content. Replace it with a message about what your app does and add the [rainbowkit] `Connect` button. Don't forget to import rainbowkit's css file and the `ConnectButton` component: +Open `page.tsx` and clear out the default content. Replace it with a message about what your app does and add the [rainbowkit] `Connect` button. Don't forget to import rainbowkit's `.css` file and the `ConnectButton` component: ```tsx import '@rainbow-me/rainbowkit/styles.css'; @@ -513,13 +517,13 @@ export default function Home() { Test the app and make sure you can connect your wallet. -### Import Your Contracts +### Import Your contracts -Next, you'll need to get your contract ABI and address into your frontend. If you're using Hardhat, you can use the artifacts produced by the Ignition deployment process. If you're using Foundry or Remix, you can adapt this process to the format of artifacts produced by those toolchains. +Next, you'll need to get your contract ABI and address into your frontend. If you use Hardhat, you can use the artifacts produced by the Ignition deployment process. If you use Foundry or Remix, you can adapt this process to the format of artifacts produced by those toolchains. :::tip -If you didn't deploy the Image Gallery contract, do so now to generate an artifact containing the ABI. +If you didn't deploy the Image Gallery contract, do so now to generate an artifact that contains the ABI. ::: @@ -558,13 +562,13 @@ export default function useContracts() { :::info -Note that we're **not** including an `address` for the `imageGallery` itself. We'll need to set this dynamically as users might have more than one gallery. +Note that we **won't** include an `address` for the `imageGallery` itself. We'll need to set this dynamically as users might have more than one gallery. ::: -### Add Content +### Add content -You can use a few strategies to organize the components that interact with the blockchain. One is to create a centralized component that stores all of the state related to smart contracts and uses a single instance of `useWriteContract`. Doing so makes it easier to convey the transaction lifecycle to your users, at the cost of re-fetching all the data from your RPC provider after every transaction. This becomes sub-optimal if your app interacts with many contracts, or even different read functions within the same contract. +You can use a few strategies to organize the components that interact with the blockchain. One is to create a centralized component that stores all of the state related to smart contracts and uses a single instance of `useWriteContract`. This makes it easier to convey the transaction lifecycle to your users, at the cost of re-fetching all the data from your RPC provider after every transaction. This becomes sub-optimal if your app interacts with many contracts, or even different read functions within the same contract. Add a folder in `app` called `components`, and create a file called `Content.tsx`. In it, add the following: @@ -701,7 +705,7 @@ Test the app and make sure you can complete the transaction to create a gallery. ### Gallery List -Next, you'll need to display the list of a user's galleries and enable them to select which one they want to interact with. A dropdown list will serve this function well. Add a component called `AddressList.tsx`, and in it add: +Next, you'll need to display the list of a user's galleries and allow them to select which one they want to interact with. A dropdown list will serve this function well. Add a component called `AddressList.tsx`, and in it add: ```tsx import React, { useEffect, useState } from 'react'; @@ -776,13 +780,13 @@ Finally, add the new component under the ` + ); +} +``` + +**LogoutButton.tsx:** + +```tsx +"use client"; + +import { useAuth } from "@crossmint/client-sdk-react-ui"; + +export function LogoutButton() { + const { logout } = useAuth(); + + return ( + + ); +} +``` + +**Header.tsx (Conditional rendering):** + +```tsx +"use client"; + +import { useAuth, useWallet } from "@crossmint/client-sdk-react-ui"; +import { LoginButton } from "./LoginButton"; +import { LogoutButton } from "./LogoutButton"; + +export function Header() { + const { status: authStatus } = useAuth(); + const { wallet } = useWallet(); + + const isLoggedIn = wallet != null && authStatus === "logged-in"; + + return ( +
+
+

Flow DApp

+ {isLoggedIn ? : } +
+
+ ); +} +``` + +### Step 4. Display wallet information + +Create a component to show wallet details with the `useWallet` hook. + +**WalletInfo.tsx:** + +```tsx +"use client"; + +import { useState } from "react"; +import { useAuth, useWallet } from "@crossmint/client-sdk-react-ui"; + +export function WalletInfo() { + const { wallet, status } = useWallet(); + const { user } = useAuth(); + const [copied, setCopied] = useState(false); + + if (status === "in-progress") { + return ( +
+
Loading wallet...
+
+ ); + } + + if (!wallet) { + return null; + } + + const formatAddress = (address: string) => { + return `${address.slice(0, 6)}...${address.slice(-6)}`; + }; + + const handleCopy = async () => { + await navigator.clipboard.writeText(wallet.address); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }; + + return ( +
+

Wallet Details

+ +
+
+
Address
+
+ + {formatAddress(wallet.address)} + + +
+
+ +
+
Chain
+
{wallet.chain}
+
+ +
+
Owner
+
{user?.email || wallet.owner}
+
+
+
+ ); +} +``` + +### Step 5. Display wallet balance + +Fetch and display the wallet's token balance with the `wallet.balances()` method. + +**WalletBalance.tsx:** + +```tsx +"use client"; + +import { useEffect, useState } from "react"; +import { Balances, useWallet } from "@crossmint/client-sdk-react-ui"; + +export function WalletBalance() { + const { wallet } = useWallet(); + const [balances, setBalances] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + async function fetchBalances() { + if (!wallet) return; + + try { + setIsLoading(true); + const balances = await wallet.balances(); + setBalances(balances); + } catch (error) { + console.error("Error fetching wallet balances:", error); + } finally { + setIsLoading(false); + } + } + + fetchBalances(); + }, [wallet]); + + if (isLoading) { + return ( +
+
Loading balance...
+
+ ); + } + + const nativeBalance = balances?.nativeToken?.amount + ? Number(balances.nativeToken.amount).toFixed(4) + : "0.0000"; + + return ( +
+

Balance

+ +
+
+
+ {balances?.nativeToken?.symbol || "FLOW"} +
+
{nativeBalance}
+
+ + {balances?.tokens && balances.tokens.length > 0 && ( +
+
Tokens
+ {balances.tokens.map((token, index) => ( +
+ {token.symbol} + + {Number(token.amount).toFixed(2)} + +
+ ))} +
+ )} +
+
+ ); +} +``` + +### Step 6. Implement token transfers + +Create a component to transfer tokens with the `wallet.send()` method. + +**TransferTokens.tsx:** + +```tsx +"use client"; + +import { useState } from "react"; +import { useWallet } from "@crossmint/client-sdk-react-ui"; + +export function TransferTokens() { + const { wallet } = useWallet(); + const [recipient, setRecipient] = useState(""); + const [amount, setAmount] = useState(""); + const [isLoading, setIsLoading] = useState(false); + const [explorerLink, setExplorerLink] = useState(null); + const [error, setError] = useState(null); + + async function handleTransfer() { + if (!wallet || !recipient || !amount) { + setError("Please fill in all fields"); + return; + } + + try { + setIsLoading(true); + setError(null); + setExplorerLink(null); + + const txn = await wallet.send( + recipient, + "flow", // Token symbol - use native FLOW token + amount + ); + + setExplorerLink(txn.explorerLink); + + // Reset form + setRecipient(""); + setAmount(""); + } catch (err) { + console.error("Transfer error:", err); + + if (err instanceof Error && err.name === "AuthRejectedError") { + // User cancelled the transaction - don't show error + return; + } + + setError(err instanceof Error ? err.message : "Transfer failed"); + } finally { + setIsLoading(false); + } + } + + return ( +
+

Transfer Tokens

+ +
+
+ + setAmount(e.target.value)} + placeholder="0.00" + className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" + disabled={isLoading} + /> +
+ +
+ + setRecipient(e.target.value)} + placeholder="0x..." + className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent font-mono text-sm" + disabled={isLoading} + /> +
+ + {error && ( +
+ {error} +
+ )} + + {explorerLink && ( +
+
+ Transaction successful! +
+ + View on Explorer � + +
+ )} + + +
+
+ ); +} +``` + +:::tip + +The `wallet.send()` method throws an `AuthRejectedError` when users cancel the transaction. Handle this separately to avoid a display of unnecessary error messages. + +::: + +### Step 7. Build activity feed + +Display transaction history with the `wallet.experimental_activity()` method with polling for real-time updates. + +**ActivityFeed.tsx:** + +```tsx +"use client"; + +import { useEffect, useState } from "react"; +import { type Activity, useWallet } from "@crossmint/client-sdk-react-ui"; + +export function ActivityFeed() { + const { wallet } = useWallet(); + const [activity, setActivity] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + if (!wallet) return; + + const fetchActivity = async () => { + try { + const activity = await wallet.experimental_activity(); + setActivity(activity); + setIsLoading(false); + } catch (error) { + console.error("Failed to fetch activity:", error); + setIsLoading(false); + } + }; + + // Initial fetch + fetchActivity(); + + // Poll every 8 seconds for updates + const interval = setInterval(fetchActivity, 8000); + + return () => clearInterval(interval); + }, [wallet]); + + const formatAddress = (address: string) => { + return `${address.slice(0, 6)}...${address.slice(-6)}`; + }; + + const formatTimestamp = (timestamp: number) => { + // Handle both seconds and milliseconds + const date = new Date( + timestamp < 10000000000 ? timestamp * 1000 : timestamp + ); + const now = new Date(); + const diffInMs = now.getTime() - date.getTime(); + + if (diffInMs < 0) return "just now"; + + const diffInMinutes = Math.floor(diffInMs / (1000 * 60)); + const diffInHours = Math.floor(diffInMs / (1000 * 60 * 60)); + const diffInDays = Math.floor(diffInMs / (1000 * 60 * 60 * 24)); + + if (diffInMinutes < 1) return "just now"; + else if (diffInMinutes < 60) return `${diffInMinutes}m ago`; + else if (diffInHours < 24) return `${diffInHours}h ago`; + else return `${diffInDays}d ago`; + }; + + if (isLoading) { + return ( +
+
Loading activity...
+
+ ); + } + + return ( +
+

Recent Activity

+ + {activity?.events && activity.events.length > 0 ? ( +
+ {activity.events.map((event, index) => { + const isIncoming = + event.to_address?.toLowerCase() === wallet?.address.toLowerCase(); + + return ( +
+
+
+ + {isIncoming ? "Received" : "Sent"} + + + {formatTimestamp(event.timestamp)} + +
+
+ {isIncoming + ? `From ${formatAddress(event.from_address)}` + : `To ${formatAddress(event.to_address)}` + } +
+
+
+
+ {isIncoming ? "+" : "-"}{event.amount} +
+
+ {event.token_symbol || "FLOW"} +
+
+
+ ); + })} +
+ ) : ( +
+

No transactions yet

+

Your activity will appear here

+
+ )} +
+ ); +} +``` + +:::warning + +The `experimental_activity()` method is experimental and may change in future SDK versions. Always handle errors gracefully and provide fallback UI. + +::: + +### Step 8. Create main dashboard + +Combine all components into a cohesive dashboard with proper state management. + +**Dashboard.tsx:** + +```tsx +"use client"; + +import { WalletInfo } from "./WalletInfo"; +import { WalletBalance } from "./WalletBalance"; +import { TransferTokens } from "./TransferTokens"; +import { ActivityFeed } from "./ActivityFeed"; + +export function Dashboard() { + return ( +
+
+
+ + +
+ +
+ + +
+
+
+ ); +} +``` + +**page.tsx (Main application):** + +```tsx +"use client"; + +import { useAuth, useWallet } from "@crossmint/client-sdk-react-ui"; +import { Header } from "@/components/Header"; +import { Dashboard } from "@/components/Dashboard"; +import { LoginButton } from "@/components/LoginButton"; + +export default function Home() { + const { wallet, status: walletStatus } = useWallet(); + const { status: authStatus } = useAuth(); + + const isLoggedIn = wallet != null && authStatus === "logged-in"; + const isLoading = walletStatus === "in-progress" || authStatus === "initializing"; + + return ( +
+
+ +
+ {isLoading ? ( +
+
+
+

Initializing wallet...

+
+
+ ) : isLoggedIn ? ( + + ) : ( +
+
+

Welcome to Flow

+

+ Sign in to access your wallet and start transacting on Flow blockchain +

+ +
+
+ )} +
+
+ ); +} +``` + +--- + +## Additional Platform Support + +While this tutorial focuses on React for web applications, Crossmint provides SDKs for multiple platforms: + +### Node.js (Backend) +For server-side wallet creation and management, use the Node.js SDK: +- [Node.js Quickstart Documentation] + +### React Native (Mobile) +For iOS and Android mobile applications: +- [React Native Quickstart Documentation] + +### Swift (iOS Native) +For native iOS development: +- Contact [Crossmint Sales] for access + +### Kotlin (Android Native) +For native Android development: +- Contact [Crossmint Sales] for access + +--- + +## Conclusion + +In this tutorial, you successfully integrated Crossmint Smart Wallets to enable seamless blockchain experiences on Flow. You learned how to implement email-based authentication, automatically create wallets for users, display balances, execute token transfers, and show transaction history, all without a requirement that users understand complex blockchain concepts like seed phrases or gas fees. + +Now that you have completed the tutorial, you should be able to: + +- Configure Crossmint accounts with proper API keys and permissions +- Implement multiple authentication methods including email and social login +- Automatically create and manage wallets for users +- Display wallet information, balances, and transaction history +- Execute token transfers with proper error handling +- Build production-ready applications with enterprise-grade wallet infrastructure + +Crossmint's wallet infrastructure, combined with Flow's high-performance blockchain, provides a powerful foundation for building user-friendly Web3 applications. By eliminating wallet complexity and onboarding friction, you can create experiences that attract mainstream users while maintaining the security and transparency benefits of blockchain technology. + +## Next Steps + +- Explore [Crossmint's NFT Minting Platform]to add NFT functionality +- Learn about [Payment Checkout] for credit card and crypto payments +- Implement [Passkey Authentication] for enhanced security +- Review [Flow Smart Contract Development] to build custom on-chain logic +- Join the [Flow Discord] to connect with other developers + + + +[Crossmint Console]: https://www.crossmint.com/console +[Staging Console]: https://staging.crossmint.com/console +[Crossmint Documentation]: https://docs.crossmint.com/ +[Crossmint Wallets SDK]: https://github.com/Crossmint/crossmint-sdk +[Crossmint Sales]: https://www.crossmint.com/contact/sales +[Flow Discord]: https://discord.gg/flow +[Crossmint's NFT Minting Platform]: https://docs.crossmint.com/nft-minting/overview +[Payment Checkout]: https://docs.crossmint.com/payments/overview +[Passkey Authentication]: https://docs.crossmint.com/wallets/signers/passkey +[Flow Smart Contract Development]: ../../cadence/ +[Node.js Quickstart Documentation]: https://docs.crossmint.com/wallets/quickstarts/nodejs +[React Native Quickstart Documentation]: https://docs.crossmint.com/wallets/quickstarts/react-native \ No newline at end of file diff --git a/docs/tutorials/integrations/gelato-sw.mdx b/docs/blockchain-development-tutorials/integrations/gelato-sw.md similarity index 67% rename from docs/tutorials/integrations/gelato-sw.mdx rename to docs/blockchain-development-tutorials/integrations/gelato-sw.md index 4d19afc2e9..68136f4f21 100644 --- a/docs/tutorials/integrations/gelato-sw.mdx +++ b/docs/blockchain-development-tutorials/integrations/gelato-sw.md @@ -20,57 +20,57 @@ keywords: import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -# Gelato Smart Wallet Integration Guide +# Gelato Smart Wallet -Gas fees are one of the biggest barriers to blockchain adoption. Users often need to hold native tokens just to pay for transaction fees, creating friction in onboarding and limiting the types of applications that can be built. Gelato Smart Wallet solves this problem by enabling **gasless transactions** on Flow EVM through sponsored transactions. +Gas fees are one of the biggest barriers to blockchain adoption. Users often need to hold native tokens just to pay for transaction fees, which creates friction in onboarding and limits the types of applications that they can build. To solve this problem, Gelato Smart Wallet activates **gasless transactions** on Flow EVM through sponsored transactions. With Gelato Smart Wallet, you can: -- **Eliminate gas fees** for your users by sponsoring their transactions -- **Improve user experience** with seamless onboarding that doesn't require users to hold FLOW tokens -- **Support EIP-7702** for enhanced smart wallet functionality -- **Scale your dApp** by removing the cost barrier for user interactions -- **Leverage Flow's low gas costs** to provide affordable sponsored transactions +- **Eliminate gas fees** for your users by sponsoring their transactions. +- **Improve user experience** with seamless onboarding that doesn't require users to hold FLOW tokens. +- **Support EIP-7702** for enhanced smart wallet functionality. +- **Scale your dApp** by removing the cost barrier for user interactions. +- **Leverage Flow's low gas costs** to provide affordable sponsored transactions. -This tutorial will guide you through setting up Gelato Smart Wallet to enable gasless transactions on Flow EVM. You'll learn how to configure the necessary API keys, fund your sponsorship account, and implement gasless transaction functionality in your applications. +This tutorial will guide you through how to set up Gelato Smart Wallet to activate gasless transactions on Flow EVM. You'll learn how to configure the necessary API keys, fund your sponsorship account, and implement gasless transaction functionality in your applications. :::info -This tutorial focuses on **EIP-7702** implementation with Gelato Smart Wallet on Flow EVM. EIP-7702 provides a streamlined experience for users by maintaining the same address as their EOA while adding smart wallet capabilities, enabling enhanced features like gasless transactions and improved user experience. +This tutorial focuses on **EIP-7702** implementation with Gelato Smart Wallet on Flow EVM. EIP-7702 provides a streamlined experience for users. It maintains the same address as their EOA and adds Smart Wallet capabilities, which activates enhanced features like gasless transactions and improved user experience. ::: ## Objectives -After completing this guide, you'll be able to: +After you complete this guide, you'll be able to: -- Configure a Gelato Smart Wallet account with proper API keys and funding setup -- Implement gasless transaction functionality using the Gelato Smart Wallet SDK -- Estimate and execute sponsored transactions on Flow EVM -- Integrate EIP-7702 features for enhanced user experience -- Troubleshoot common issues with Gelato Smart Wallet integration +- Configure a Gelato Smart Wallet account with proper API keys and funding setup. +- Implement gasless transaction functionality with the Gelato Smart Wallet SDK. +- Estimate and execute sponsored transactions on Flow EVM. +- Integrate EIP-7702 features for enhanced user experience. +- Troubleshoot common issues with Gelato Smart Wallet integration. -## Prerequisites of using Gelato Smart Wallet +## Prerequisites to use Gelato Smart Wallet You need to set up the following in the Gelato App to create a Gelato Sponsor API Key: -### Step 1. Create Your Gelato Account +### Step 1. Create your Gelato account -Sign up on the [Gelato App] to establish an account. This account is the foundation for setting up relay tasks and managing gas sponsorships. +Sign up on the [Gelato App] to establish an account. This account is the foundation to set up relay tasks and manage gas sponsorships. -### Step 2. Deposit Funds into 1Balance +### Step 2. Deposit funds into 1Balance -To use Gelato for sponsored transactions, you need to deposit funds into 1Balance according to your target environment: +To use Gelato for sponsored transactions, you need to deposit funds into 1Balance as your target environment requires: - Mainnets: Deposit USDC. - Testnets: Deposit Sepolia ETH. Click the `1Balance` tab to link your wallet first. -![Link Wallet](./images/gelato-1balance-1.png) +![Link Wallet](./imgs/gelato-1balance-1.png) And then deposit some Sepolia ETH(SEP) testnet funds. -![Deposit Funds into 1Balance](./images/gelato-1balance-2.png) +![Deposit Funds into 1Balance](./imgs/gelato-1balance-2.png) If you need to fund your account, you can use one of the following third-party faucets: @@ -79,14 +79,14 @@ If you need to fund your account, you can use one of the following third-party f - [Chainlink Sepolia Faucet] - [Metamask Sepolia Faucet] -### Step 3. Create a Relay App +### Step 3. Create a relay app Select the `Relay` tab in the Gelato App and switch to the `Testnet` environment. Now you can create a new _Relay App_ with the Flow EVM network. For Testnet, you can first allow `Any contract` to call your relay app. -![Create a Relay App](./images/gelato-relay-1.png) +![Create a Relay App](./imgs/gelato-relay-1.png) :::warning @@ -96,23 +96,23 @@ When set to a specific contract instead of `Any contract`, the API keys will onl ::: -### Step 4. Create/Obtain an API Key +### Step 4. Create or obtain an API key -After creating the Relay App, navigate to its dashboard to locate your Sponsor API Key. +After you create the Relay App, navigate to its dashboard to locate your Sponsor API Key. -![Create a Sponsor API Key](./images/gelato-relay-2.png) +![Create a Sponsor API Key](./imgs/gelato-relay-2.png) This key links your Gelato setup with 1Balance for gas sponsorship. Copy the API key to your clipboard. -## Send Gasless Transactions for your users +## Send gasless transactions for your users After you have created a Sponsor API Key and deposited funds into 1Balance, you can use gasless transactions features for your users. -With the Gelato Smart Wallet SDK, developers can easily set up sponsored transactions for their applications in just a few simple steps, enabling seamless onboarding and interaction without requiring users to hold native tokens. +With the Gelato Smart Wallet SDK, developers can easily set up sponsored transactions for their applications in just a few simple steps, which allows seamless onboarding and interaction and doesn't require users to hold native tokens. -:::note +:::info You can find the examples in the [Gelato Smart Wallet SDK] repository. @@ -144,7 +144,7 @@ You can find the examples in the [Gelato Smart Wallet SDK] repository. -### Step 2. Setup Smart Wallet Account +### Step 2. Set up a Smart Wallet account Import required dependencies: @@ -162,8 +162,7 @@ const publicClient = createPublicClient({ }); ``` -You can set up a Smart Account as per your needs. -Once you create the `gelato` account, the Gelato Smart Account address will be the same as your EOA, enabling EIP-7702 features. +You can set up a Smart Account as per your needs. After you create the `gelato` account, the Gelato Smart Account address will be the same as your EOA, which activates EIP-7702 features. ```ts // Prepare a normal EOA account @@ -187,7 +186,7 @@ const client = createWalletClient({ }); ``` -Once you have a standard viem wallet client, you can wrap it into a Gelato Smart Wallet client with the sponsor API key. +After you have a standard viem wallet client, you can wrap it into a Gelato Smart Wallet client with the sponsor API key. ```ts const sponsorApiKey = process.env.SPONSOR_API_KEY; @@ -200,7 +199,7 @@ const swc = await createGelatoSmartWalletClient(client, { }); ``` -### Step 3. Estimate or Send a Gasless Transaction +### Step 3. Estimate or send a gasless transaction Now you can estimate or send a gasless transaction with the Gelato Smart Wallet client. @@ -277,17 +276,19 @@ results.on("error", (error: Error) => { ## Conclusion -In this tutorial, you successfully integrated Gelato Smart Wallet to enable gasless transactions on Flow EVM. You learned how to set up the necessary infrastructure, configure API keys, fund sponsorship accounts, and implement gasless transaction functionality in your applications. The implementation demonstrates how Flow's low gas costs combined with Gelato's sponsored transaction infrastructure can create seamless user experiences that eliminate the friction of gas fees. +In this tutorial, you successfully integrated Gelato Smart Wallet to activate gasless transactions on Flow EVM. You learned how to set up the necessary infrastructure, configure API keys, fund sponsorship accounts, and implement gasless transaction functionality in your applications. The implementation demonstrates how Flow's low gas costs combined with Gelato's sponsored transaction infrastructure can create seamless user experiences that eliminate the friction of gas fees. Now that you have completed the tutorial, you should be able to: -- Configure a Gelato Smart Wallet account with proper API keys and funding setup -- Implement gasless transaction functionality using the Gelato Smart Wallet SDK -- Estimate and execute sponsored transactions on Flow EVM -- Integrate EIP-7702 features for enhanced user experience -- Troubleshoot common issues with Gelato Smart Wallet integration +- Configure a Gelato Smart Wallet account with proper API keys and funding setup. +- Implement gasless transaction functionality with the Gelato Smart Wallet SDK. +- Estimate and execute sponsored transactions on Flow EVM. +- Integrate EIP-7702 features for enhanced user experience. +- Troubleshoot common issues with Gelato Smart Wallet integration. + +The combination of Flow's efficient gas prices and Gelato's sponsored transaction infrastructure opens up new possibilities for you to build user-friendly dApps. When you eliminate the need for users to hold native tokens for gas fees, you can create onboarding experiences that rival traditional Web2 applications and maintain the security and transparency of blockchain technology. -The combination of Flow's efficient gas pricing and Gelato's sponsored transaction infrastructure opens up new possibilities for building user-friendly dApps. By eliminating the need for users to hold native tokens for gas fees, you can create onboarding experiences that rival traditional Web2 applications while maintaining the security and transparency of blockchain technology. + [Gelato App]: https://app.gelato.cloud/ [Google Cloud Sepolia Faucet]: https://cloud.google.com/application/web3/faucet/ethereum/sepolia diff --git a/docs/tutorials/integrations/images/gelato-1balance-1.png b/docs/blockchain-development-tutorials/integrations/imgs/gelato-1balance-1.png similarity index 100% rename from docs/tutorials/integrations/images/gelato-1balance-1.png rename to docs/blockchain-development-tutorials/integrations/imgs/gelato-1balance-1.png diff --git a/docs/tutorials/integrations/images/gelato-1balance-2.png b/docs/blockchain-development-tutorials/integrations/imgs/gelato-1balance-2.png similarity index 100% rename from docs/tutorials/integrations/images/gelato-1balance-2.png rename to docs/blockchain-development-tutorials/integrations/imgs/gelato-1balance-2.png diff --git a/docs/tutorials/integrations/images/gelato-relay-1.png b/docs/blockchain-development-tutorials/integrations/imgs/gelato-relay-1.png similarity index 100% rename from docs/tutorials/integrations/images/gelato-relay-1.png rename to docs/blockchain-development-tutorials/integrations/imgs/gelato-relay-1.png diff --git a/docs/tutorials/integrations/images/gelato-relay-2.png b/docs/blockchain-development-tutorials/integrations/imgs/gelato-relay-2.png similarity index 100% rename from docs/tutorials/integrations/images/gelato-relay-2.png rename to docs/blockchain-development-tutorials/integrations/imgs/gelato-relay-2.png diff --git a/docs/blockchain-development-tutorials/integrations/index.md b/docs/blockchain-development-tutorials/integrations/index.md new file mode 100644 index 0000000000..f0abef0730 --- /dev/null +++ b/docs/blockchain-development-tutorials/integrations/index.md @@ -0,0 +1,44 @@ +--- +title: Third-Party Integrations +description: Comprehensive guides for integrating popular blockchain infrastructure platforms with Flow to enhance user experience and reduce development complexity. +sidebar_position: 10 +keywords: + - Gelato + - Crossmint + - integrations + - infrastructure + - gasless transactions + - payments + - wallets + - authentication +--- + +# Third-Party integrations + +Flow's developer-friendly ecosystem extends beyond core blockchain functionality through strategic integrations with leading infrastructure platforms. These integrations eliminate common Web3 friction points, which allows you to build sophisticated applications with traditional Web2 user experiences and leverage Flow's unique blockchain capabilities. + +This section provides comprehensive integration guides for platforms that enhance Flow development by addressing key challenges like gas fees, payment processing, user onboarding, and wallet management. Each integration tutorial provides step-by-step implementation guidance, best practices, and real-world examples to help you quickly integrate these powerful services into your Flow applications. + +## Available integrations + +### [Gelato Smart Wallet] + +Eliminate gas fees and improve user experience with Gelato's sponsored transaction infrastructure on Flow EVM. This comprehensive guide shows you how to implement gasless transactions with EIP-7702 features, configure API keys and funding accounts, and integrate the Gelato Smart Wallet SDK for seamless user onboarding. Learn to leverage Flow's low gas costs combined with Gelato's sponsorship infrastructure to create applications that rival traditional Web2 experiences and maintain blockchain security and transparency. + +### [Crossmint Integration Platform] + +Build enterprise-grade Web3 applications on Flow with Crossmint's comprehensive blockchain infrastructure platform. This extensive integration guide covers four key areas: + +- Authentication with email, Social logins, and wallet connections. +- Fiat payment processing supporting credit cards, Apple Pay, and Google Pay +- NFT and token minting platform with no-code deployment tools +- Access to real-world goods through crypto payments. + +Crossmint allows you to create complete blockchain applications that feel familiar to Web2 users and leverage Flow's advanced capabilities. + +## Conclusion + +These third-party integrations demonstrate Flow's commitment to provide developers with the tools they need to build mainstream-ready blockchain applications. When you combine Flow's innovative architecture with best-in-class infrastructure platforms, you can eliminate traditional Web3 barriers and create user experiences that drive adoption. Whether you want to build decentralized finance (DeFi) protocols, NFT marketplaces, or consumer applications, these integrations provide the foundation for scalable, user-friendly products that bridge the gap between Web2 expectations and Web3 capabilities. + +[Gelato Smart Wallet]: ./gelato-sw.md +[Crossmint Integration Platform]: ./crossmint/index.md \ No newline at end of file diff --git a/docs/tutorials/native-vrf/commit-reveal-cadence.md b/docs/blockchain-development-tutorials/native-vrf/commit-reveal-cadence.md similarity index 52% rename from docs/tutorials/native-vrf/commit-reveal-cadence.md rename to docs/blockchain-development-tutorials/native-vrf/commit-reveal-cadence.md index efbe909536..2bb16656df 100644 --- a/docs/tutorials/native-vrf/commit-reveal-cadence.md +++ b/docs/blockchain-development-tutorials/native-vrf/commit-reveal-cadence.md @@ -19,68 +19,78 @@ keywords: # Secure Randomness with Commit-Reveal in Cadence -Randomness is a critical component in blockchain applications, enabling fair and unpredictable outcomes for use cases like gaming, lotteries, and cryptographic protocols. The most basic approach to generating a random number on EVM chains is to utilize block hashes, which combines the block hash with a user-provided seed and hashes them together. The resulting hash can be used as a pseudo-random generator seed. However, this approach has limitations. The block hash can be manipulated by a validator influencing the random source used to compute transactions. The block proposer has the freedom to decide what to include into a block and can through different combinations till they find a favorable random source. +Randomness is a critical component in blockchain applications. It allows fair and unpredictable outcomes for use cases like gaming, lotteries, and cryptographic protocols. -[Chainlink VRF][chainlink-vrf] is a popular tool that improves on this by providing another approach for generating provably random values on Ethereum and other blockchains by relying on a decentralized oracle network to deliver cryptographically secure randomness from off-chain sources. However, this dependence on external oracles introduces several weaknesses, such as cost, latency, and scalability concerns. +The most basic approach that you can use to generate a random number on EVM chains is to use block hashes, which combines the block hash with a user-provided seed and hashes them together. You can use the hash that results as a pseudo-random generator seed. However, this approach has limitations. A validator that influences the random source used to compute transactions can manipulate the block hash. The block proposer can decide what to include into a block and can iterate through different combinations until they find a favorable random source. -In contrast, Flow offers a simpler and more integrated approach with its native on-chain Randomness Beacon at the protocol level, eliminating reliance on external oracles and sidestepping their associated risks. +[Chainlink VRF][chainlink-vrf] is a popular tool that improves on this. It provides another approach you can use to generate provably random values on Ethereum and other blockchains. It relies on a decentralized oracle network to deliver cryptographically secure randomness from off-chain sources. However, this dependence on external oracles introduces several weaknesses, such as cost, latency, and scalability concerns. -In addition to instant randomness that is available to any transaction (via `revertibleRandom` function), Flow provides a solution to reverted transaction. Commit-Reveal schemes on Flow also rely on protocol-native secure randomness and they fix the issue of post-selection by trustless users. Commit-Reveal tools on Flow can be used within both Cadence and Solidity smart contracts. This tutorial will focus on the Cadence case. +In contrast, Flow offers a simpler and more integrated approach with its native onchain Randomness Beacon at the protocol level, which eliminates reliance on external oracles and the need to sidestep their associated risks. + +In addition to instant randomness that is available to any transaction (via `revertibleRandom` function), Flow provides a solution to the problem of a user who reverts a transaction with an unfavorable outcome. Commit-Reveal schemes on Flow also rely on protocol-native secure randomness and they fix the issue of post-selection by trustless users. Commit-Reveal tools on Flow can be used within both Cadence and Consumer Decentralized Finance (DeFi) contracts. This tutorial focuses on Cadence. ## Objectives By the end of this guide, you will be able to: -- Deploy a Cadence smart contract on the Flow blockchain -- Implement commit-reveal pattern for randomness to ensure fairness -- Interact with on-chain randomness features on Flow -- Build and test the Coin Toss game using the Flow Testnet +- Deploy a Cadence smart contract on the Flow blockchain. +- Implement commit-reveal pattern for randomness to ensure fairness. +- Interact with onchain randomness features on Flow. +- Build and test the Coin Toss game with the Flow Testnet. ## Prerequisites You'll need the following: -- Flow Testnet Account: An account on the Flow Testnet with test FLOW tokens for deploying contracts and executing transactions (e.g., via [Flow Faucet][flow-faucet]). -- Flow CLI or Playground: The Flow CLI or Flow Playground for deploying and testing contracts (install via [Flow Docs][flow-docs]). +- Flow Testnet Account: an account on the Flow Testnet with test FLOW tokens to deploy contracts and execute transactions (for example, via [Flow Faucet][flow-faucet]). +- Flow CLI or Playground: the Flow CLI or Flow Playground to deploy and test contracts (install via [Flow Docs][flow-docs]). ## Overview In this guide, we will explore how to use a commit-reveal scheme based on the Flow Random Beacon to achieve secure, non-revertible randomness. This mechanism mitigates post-selection attacks, where participants attempt to reject unfavorable random outcomes after they are revealed. -To illustrate this concept, we will build a Coin Toss game on Flow, demonstrating how smart contracts can leverage a commit-reveal scheme for fair, tamper-resistant results. +To illustrate this concept, we will build a Coin Toss game on Flow, which demonstrates how smart contracts can leverage a commit-reveal scheme for fair, tamper-resistant results. -![Commit Reveal](commit-reveal.png) +![Commit Reveal](./imgs/commit-reveal.png) ### What is the Coin Toss Game? -The Coin Toss Game is a decentralized betting game that showcases the commit-reveal pattern. Players place bets without knowing the random outcome, ensuring fairness and resistance to manipulation. +The Coin Toss Game is a decentralized betting game that showcases the commit-reveal pattern. Players place bets and don't know the random outcome, which ensures fairness and resistance to manipulation. The game consists of two distinct phases: -1. Commit Phase - The player places a bet by sending Flow tokens to the contract. The contract records the commitment to use a future random value from the Flow Random Beacon. The player receives a Receipt, which they will use to reveal the result later. -2. Reveal Phase - Once the random value becomes available in the `RandomBeaconHistory` contract, the player submits their Receipt to determine the outcome: +1. Commit Phase - To place a bet, the player sends Flow tokens to the contract. The contract records the commitment to use a future random value from the Flow Random Beacon. The player receives a Receipt, which they will use to reveal the result later. +2. Reveal Phase - When the random value becomes available in the `RandomBeaconHistory` contract, the player submits their Receipt to determine the outcome: - If the result is 0, the player wins and receives double their bet. - If the result is 1, the player loses, and their bet remains in the contract. -### Why Use a Commit-Reveal scheme? +### Why use a Commit-Reveal scheme? Similarly to revertible randomness, Commit-Reveal inherits the security of Flow native randomness beacon: - Ensures security - The Flow Random Beacon provides cryptographically unpredictable and non-biased randomness. - Ensure fairness - The Flow Random Beacon uses a Verifiable Random Function (VRF) under the hood which allows any external client or user to verify that randoms were generated fairly. -- Reduces reliance on external oracles - The randomness is generated natively on-chain, avoiding additional complexity, third party risk and cost. +- Reduces reliance on external oracles - The randomness is generated natively onchain, and avoids additional complexity, third party risk and cost. In addition, commit-reveal patterns solve the issue of revertible randoms: -- Prevents user manipulation - Players cannot selectively reveal results after seeing the random results. +- Prevents user manipulation - Players cannot evaluate the outcome and choose to revert the transaction if they do not like the result. +- + + +:::info -## Building the Coin Toss Contract +One of the powers of Cadence transactions is that a developer can set post-conditions that must be true, or the transaction will revert. This is very useful for scenarios such as to guarantee a user receives their purchase in a complex and multi-step transaction, but it also means that they can set conditions to reject the transaction. In an instant-win lottery, this would allow users to test large numbers of tickets for a win without purchase price payment. -In this section, we'll walk through constructing the `CoinToss.cdc` contract, which contains the core logic for the Coin Toss game. To function properly, the contract relies on supporting contracts and a proper deployment setup. +::: -This tutorial will focus specifically on writing and understanding the `CoinToss.cdc` contract, while additional setup details can be found in the [original GitHub repo][github-repo]. +## Build the Coin Toss contract -### Step 1: Defining the `CoinToss.cdc` Contract +In this section, we'll walk through how to construct the `CoinToss.cdc` contract, which contains the core logic for the Coin Toss game. To function properly, the contract relies on support contracts and a proper deployment setup. + +This tutorial will focus specifically on how to write and understand the `CoinToss.cdc` contract, while you can find additional setup details in the [original GitHub repo][github-repo]. + +### Step 1: Define the `CoinToss.cdc` contract Let's define our `CoinToss.cdc` and bring the other supporting contracts. @@ -105,9 +115,9 @@ access(all) contract CoinToss { } ``` -### Step 2: Implementing the Commit Phase With `flipCoin` +### Step 2: Implement the commit phase with `flipCoin` -Let's define the first step in our scheme; the commit phase. We do this through a `flipCoin` public function. In this method, the caller commits a bet. The contract takes note of a future block height and bet amount, returning a `Receipt` resource which is used by the former to reveal the coin toss result and determine their winnings. +Let's define the first step in our scheme; the commit phase. We do this through a `flipCoin` public function. In this method, the caller commits a bet. The contract takes note of a future block height and bet amount and returns a `Receipt` resource, which the former uses to reveal the coin toss result and determine their winnings. ```cadence access(all) fun flipCoin(bet: @{FungibleToken.Vault}): @Receipt { @@ -124,10 +134,11 @@ access(all) fun flipCoin(bet: @{FungibleToken.Vault}): @Receipt { } ``` -### Step 3: Implementing the Reveal Phase With `revealCoin` +### Step 3: Implement the reveal phase With `revealCoin` + +Now we implement the reveal phase with the `revealCoin` function. Here, the caller provides the Receipt they recieve at commitment. The contract then "flips a coin" and `_randomCoin()` provides the Receipt's contained Request. The reveal step is possible only when the protocol random source at the committed block height becomes available. -Now we implement the reveal phase with the `revealCoin` function. Here the caller provides the Receipt given to them at commitment. The contract then "flips a coin" with `_randomCoin()` providing the Receipt's contained Request. The reveal step is possible only when the protocol random source at the committed block height becomes available. -If result is 1, user loses, but if it's 0 the user doubles their bet. Note that the caller could condition the revealing transaction, but they've already provided their bet amount so there's no loss for the contract if they do. +If result is 1, the user loses, but if it's 0, the user doubles their bet. Note that the caller could condition the revealed transaction, but they've already provided their bet amount, so there's no loss for the contract if they do. ```cadence access(all) fun revealCoin(receipt: @Receipt): @{FungibleToken.Vault} { @@ -155,18 +166,18 @@ access(all) fun revealCoin(receipt: @Receipt): @{FungibleToken.Vault} { } ``` -The final version of `CoinToss.cdc` should look like [this contract code][coin-toss-contract-code]. +The final version of `CoinToss.cdc` will look like [this contract code][coin-toss-contract-code]. -## Testing CoinToss on Flow Testnet +## Test CoinToss on Flow Testnet -To make things easy, we've already deployed the `CoinToss.cdx` contract for you at this address: [0xb6c99d7ff216a684][coin-toss-contract]. We'll walk through placing a bet and revealing the result using [run.dnz][run-dnz], a Flow-friendly tool similar to Ethereum's Remix. +To make things easy, we've already deployed the `CoinToss.cdx` contract for you at this address: [0xb6c99d7ff216a684][coin-toss-contract]. We'll walk through how to place a bet and reveal the result with [run.dnz][run-dnz], a Flow-friendly tool similar to Ethereum's Remix. -### Placing a Bet with flipCoin +### Place a bet with flipCoin -First, you'll submit a bet to the CoinToss contract by withdrawing Flow tokens and storing a receipt. Here's how to get started: +First, you'll submit a bet to the CoinToss contract. To do this, you'll withdraw Flow tokens and store a receipt. Here's how to get started: -1. Open Your Dev Environment: Head to [run.dnz][run-dnz]. -2. Enter the Transaction Code: Paste the following Cadence code into the editor: +1. Open Your Dev Environment: head to [run.dnz][run-dnz]. +2. Enter the Transaction Code: paste the following Cadence code into the editor: ```cadence import FungibleToken from 0x9a0766d93b6608b7 @@ -197,25 +208,25 @@ transaction(betAmount: UFix64) { } ``` -3. Set Your Bet: A modal will pop up asking for the betAmount. Enter a value (e.g., 1.0 for 1 Flow token) and submit -4. Execute the Transaction: Click "Run," and a WalletConnect window will appear. Choose Blocto, sign in with your email, and hit "Approve" to send the transaction to Testnet. +3. Set Your Bet: a window will appear that asks for the `betAmount`. Enter a value (such as 1.0 for 1 Flow token) and submit. +4. Execute the Transaction: click "Run," and a WalletConnect window will appear. Choose Blocto, sign in with your email, and click "Approve" to send the transaction to Testnet. ![remix5-sc](./imgs/remix5.png) -5. Track it: You can take the transaction id to [FlowDiver][flow-diver][.io](https://testnet.flowdiver.io/tx/9c4f5436535d36a82d4ae35467b37fea8971fa0ab2409dd0d5f861f61e463d98) to have a full view of everything that's going on with this `FlipCoin` transaction. +5. Track it: You can take the transaction id to [FlowDiver][flow-diver][.io] to have a full view of everything about this `FlipCoin` transaction. -### Revealing the Coin Toss Result +### Reveal the coin toss result -Let's reveal the outcome of your coin toss to see if you've won. This step uses the receipt from your bet, so ensure you're using the same account that placed the bet. Here's how to do it: +Let's reveal the outcome of your coin toss to see if you've won. This step uses the receipt from your bet, so ensure you use the same account that placed the bet. Here's how to do it: 1. Return to your Dev Environment: Open [run.dnz][run-dnz] again. -2. Enter the Reveal Code: Paste the following Cadence transaction into the editor: +2. Enter the Reveal Code. Paste the following Cadence transaction into the editor: ```cadence import FlowToken from 0x7e60df042a9c0868 import CoinToss from 0xb6c99d7ff216a684 -/// Retrieves the saved Receipt and redeems it to reveal the coin toss result, depositing winnings with any luck +/// Retrieves the saved Receipt, redeems it to reveal the coin toss result, and deposits the winnings with any luck /// transaction { @@ -238,33 +249,34 @@ transaction { } ``` -After running this transaction, we reveal the result of the coin flip and it's 1! Meaning we have won nothing this time, but keep trying! +After we run this transaction, we reveal the result of the coin flip and it's 1! It means we haven't won anything this time, but we'll try again! You can find the full transaction used for this example, with its result and events, at [FlowDiver.io/tx/][flow-diver-tx]. ## Conclusion -The commit-reveal scheme, implemented within the context of the Flow Randomness Beacon, provides a robust solution for generating secure and non-revertible randomness in decentralized applications. By leveraging this mechanism, developers can ensure that their applications are: +The commit-reveal scheme, implemented within the context of the Flow Randomness Beacon, provides a robust solution to generate secure and non-revertible randomness in decentralized applications. When developers leverage this mechanism, they can ensure that their applications are: -- Fair: Outcomes remain unbiased and unpredictable. -- Resistant to post-selection: Protects against trustless users who cannot reverse their commitments. +- Fair: outcomes remain unbiased and unpredictable. +- Resistant to post-selection: protects against trustless users who cannot reverse their commitments. -The CoinToss game serves as a practical example of these principles in action. By walking through its implementation, you've seen firsthand how straightforward yet effective this approach can be—balancing simplicity for developers with robust security for users. As blockchain technology advances, embracing such best practices is essential to creating a decentralized ecosystem that upholds fairness and integrity, empowering developers to innovate with confidence. +The CoinToss game serves as a practical example of these principles in action. Now that you've walked through its implementation, you've seen firsthand how straightforward yet effective this approach can be, as it balances simplicity for developers with robust security for users. As blockchain technology advances, it's essential that you embrace such best practices to create a decentralized ecosystem that upholds fairness and integrity, which empowers developers to innovate with confidence. This tutorial has equipped you with hands-on experience and key skills: - You deployed a Cadence smart contract on the Flow blockchain. - You implemented commit-reveal to ensure fairness. -- You interacted with on-chain randomness features on Flow. -- You built and tested the Coin Toss game using the Flow Testnet. +- You interacted with onchain randomness features on Flow. +- You built and tested the Coin Toss game with the Flow Testnet. -By harnessing the built-in randomness capabilities on Flow, you can now focus on crafting engaging, user-centric experiences without grappling with the complexities or limitations of external systems. This knowledge empowers you to create secure, scalable, and fair decentralized applications. +When you harness the built-in randomness capabilities on Flow, you can create engaging, user-centric experiences without grappling with the complexities or limitations of external systems. This knowledge empowers you to create secure, scalable, and fair decentralized applications. [chainlink-vrf]: https://docs.chain.link/vrf [flow-faucet]: https://faucet.flow.com/fund-account [flow-docs]: https://developers.flow.com [flow-diver]: https://testnet.flowdiver.io/ [github-repo]: https://github.com/onflow/random-coin-toss +[.io]: https://testnet.flowdiver.io/tx/9c4f5436535d36a82d4ae35467b37fea8971fa0ab2409dd0d5f861f61e463d98 [run-dnz]: https://run.dnz.dev/ [coin-toss-contract]: https://contractbrowser.com/A.b6c99d7ff216a684.CoinToss [coin-toss-contract-code]: https://github.com/onflow/random-coin-toss/blob/main/contracts/CoinToss.cdc diff --git a/docs/tutorials/native-vrf/commit-reveal.png b/docs/blockchain-development-tutorials/native-vrf/imgs/commit-reveal.png similarity index 100% rename from docs/tutorials/native-vrf/commit-reveal.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/commit-reveal.png diff --git a/docs/tutorials/native-vrf/imgs/remix1.png b/docs/blockchain-development-tutorials/native-vrf/imgs/remix1.png similarity index 100% rename from docs/tutorials/native-vrf/imgs/remix1.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/remix1.png diff --git a/docs/tutorials/native-vrf/imgs/remix2.png b/docs/blockchain-development-tutorials/native-vrf/imgs/remix2.png similarity index 100% rename from docs/tutorials/native-vrf/imgs/remix2.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/remix2.png diff --git a/docs/tutorials/native-vrf/imgs/remix3.png b/docs/blockchain-development-tutorials/native-vrf/imgs/remix3.png similarity index 100% rename from docs/tutorials/native-vrf/imgs/remix3.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/remix3.png diff --git a/docs/tutorials/native-vrf/imgs/remix4.png b/docs/blockchain-development-tutorials/native-vrf/imgs/remix4.png similarity index 100% rename from docs/tutorials/native-vrf/imgs/remix4.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/remix4.png diff --git a/docs/tutorials/native-vrf/imgs/remix5.png b/docs/blockchain-development-tutorials/native-vrf/imgs/remix5.png similarity index 100% rename from docs/tutorials/native-vrf/imgs/remix5.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/remix5.png diff --git a/docs/tutorials/native-vrf/imgs/vrf-1.png b/docs/blockchain-development-tutorials/native-vrf/imgs/vrf-1.png similarity index 100% rename from docs/tutorials/native-vrf/imgs/vrf-1.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/vrf-1.png diff --git a/docs/tutorials/native-vrf/imgs/vrf-2.png b/docs/blockchain-development-tutorials/native-vrf/imgs/vrf-2.png similarity index 100% rename from docs/tutorials/native-vrf/imgs/vrf-2.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/vrf-2.png diff --git a/docs/tutorials/native-vrf/imgs/vrf-3.png b/docs/blockchain-development-tutorials/native-vrf/imgs/vrf-3.png similarity index 100% rename from docs/tutorials/native-vrf/imgs/vrf-3.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/vrf-3.png diff --git a/docs/tutorials/native-vrf/imgs/vrf-4.png b/docs/blockchain-development-tutorials/native-vrf/imgs/vrf-4.png similarity index 100% rename from docs/tutorials/native-vrf/imgs/vrf-4.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/vrf-4.png diff --git a/docs/tutorials/native-vrf/imgs/vrf-5.png b/docs/blockchain-development-tutorials/native-vrf/imgs/vrf-5.png similarity index 100% rename from docs/tutorials/native-vrf/imgs/vrf-5.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/vrf-5.png diff --git a/docs/tutorials/native-vrf/imgs/vrf-6.png b/docs/blockchain-development-tutorials/native-vrf/imgs/vrf-6.png similarity index 100% rename from docs/tutorials/native-vrf/imgs/vrf-6.png rename to docs/blockchain-development-tutorials/native-vrf/imgs/vrf-6.png diff --git a/docs/blockchain-development-tutorials/native-vrf/index.md b/docs/blockchain-development-tutorials/native-vrf/index.md new file mode 100644 index 0000000000..9babac89a0 --- /dev/null +++ b/docs/blockchain-development-tutorials/native-vrf/index.md @@ -0,0 +1,54 @@ +--- +title: Native VRF (Built-in Randomness) Tutorials +description: Build on a blockchain with built-in randomness. Flow's native VRF enables verifiable, low-cost randomness for gaming, NFTs, and DeFi. WIth no third-party dependencies. +sidebar_position: 8 +keywords: + - VRF + - randomness + - Cadence + - Solidity + - Flow EVM + - smart contracts + - commit-reveal + - secure randomness + - Random Beacon + - blockchain + - gaming + - NFTs + - DeFi +--- + +# Native VRF (Built-in Randomness) Tutorials + +Flow is a **blockchain with built-in randomness**, powered by its native **VRF (Verifiable Random Function)** capabilities. Unlike other blockchains that require external oracles, Flow's **Random Beacon** provides cryptographically secure randomness **at the protocol level**. This elimiates extra costs, reduces latency, and improves reliability for decentralized applications. + +These tutorials cover how to implement secure randomness directly in both **Cadence** and **Solidity** smart contracts on Flow. Whether you build on Flow's native environment or Flow EVM, you can generate unbiased, verifiable random values without third-party dependencies. + +## Tutorials + +### [Secure Randomness with Commit-Reveal in Cadence] + +Learn how to implement secure randomness in Cadence with Flow's commit-reveal scheme, which ensures fairness and resistance to manipulation. + +### [VRF (Randomness) in Solidity] + +Learn how to use Flow's **native verifiable randomness** in Consumer Decentralized Finance (DeFi) contracts on Flow EVM, which includes best practices, security considerations, and complete code examples. + +## Why Flow for randomness? + +- Protocol-level randomness: no need for external oracles or APIs. + +- Lower costs: built-in randomness means no extra transaction fees. + +- Enhanced security: cryptographically secure and verifiable onchain. + +- Cross-language support: Wwrks seamlessly in both Cadence and Consumer DeFi. + +- Speed: Flow is a [fast blockchain] with the design goal of 1,000,000 transactions per second. + + + +[Secure Randomness with Commit-Reveal in Cadence]: ./commit-reveal-cadence.md +[VRF (Randomness) in Solidity]: ./vrf-in-solidity.md +[VRF (Randomness) in Solidity]: ./vrf-in-solidity.md +[fast blockchain]: https://flow.com/core-protocol-vision diff --git a/docs/tutorials/native-vrf/vrf-in-solidity.md b/docs/blockchain-development-tutorials/native-vrf/vrf-in-solidity.md similarity index 50% rename from docs/tutorials/native-vrf/vrf-in-solidity.md rename to docs/blockchain-development-tutorials/native-vrf/vrf-in-solidity.md index 82744b1b52..1a9eaf61ee 100644 --- a/docs/tutorials/native-vrf/vrf-in-solidity.md +++ b/docs/blockchain-development-tutorials/native-vrf/vrf-in-solidity.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 2 title: VRF (Randomness) in Solidity sidebar_label: VRF (Randomness) in Solidity keywords: @@ -14,56 +14,42 @@ keywords: - DeFi --- -## **Introduction** +# VRF (Randomness) in Solidity -Flow provides secure, native on-chain randomness that developers can leverage through Cadence Arch, a precompiled contract available on the Flow EVM environment. This guide will walk through how Solidity developers can use Cadence Arch to access Flow's verifiable randomness using Solidity. +Flow provides secure, native onchain randomness that developers can leverage through Cadence Arch, a precompiled contract available on the Flow EVM environment. This guide walks you through how Consumer Decentralized Finance (DeFi) developers can use Cadence Arch to access Flow's verifiable randomness with Consumer DeFi. -### **What is Cadence Arch?** +### What is Cadence Arch? -[Cadence Arch] is a precompiled smart contract that allows Solidity developers on Flow EVM to interact with Flow's randomness and other network features like block height. This contract can be accessed using its specific address, and Solidity developers can make static calls to retrieve random values and other information. +[Cadence Arch] is a precompiled smart contract that allows DeFi developers on Flow EVM to interact with Flow's randomness and other network features like block height. This contract can be accessed with its specific address, and DeFi developers can make static calls to retrieve random values and other information. ---- +## Prerequisites -## **Prerequisites** +- Basic DeFi knowledge +- Installed Metamask extension +- Remix IDE for compilation and deployment +- Flow EVM Testnet setup in Metamask -- Basic Solidity knowledge. -- Installed Metamask extension. -- Remix IDE for compilation and deployment. -- Flow EVM Testnet setup in Metamask. +## Network information for Flow EVM -## **Network Information for Flow EVM** +See [Network information] for more details. -| **Parameter** | **Value** | -| ------------------- | ----------------------------------------------------------------------------- | -| **Network Name** | Flow EVM Testnet | -| **RPC Endpoint** | [Flow EVM Testnet RPC] | -| **Chain ID** | 545 | -| **Currency Symbol** | FLOW | -| **Block Explorer** | [Flow EVM Testnet Explorer] | +## Steps to connect Flow EVM testnet to metamask -## **Steps to Connect Flow EVM Testnet to Metamask** +See [Wallets & Configurations] for more details. -1. Open Metamask and click **Networks** -> **Add Network**. -2. Enter the following details: - - **Network Name**: Flow EVM Testnet - - **RPC URL**: `https://testnet.evm.nodes.onflow.org` - - **Chain ID**: `545` - - **Currency Symbol**: `FLOW` - - **Block Explorer**: `https://evm-testnet.flowscan.io` -3. Click **Save** and switch to the Flow EVM Testnet. +## Solidity commit reveal -![MetaMask Network Configuration](./imgs/vrf-1.png) +Make sure you review the Solidity version of the [commit reveal] to learn more about Flow EVM's native secure randomness through a simple demonstration. -## **Obtaining Testnet FLOW** +## Obtaining testnet FLOW -You can fund your account with testnet FLOW using the [Flow Faucet]. -Enter your Flow-EVM testnet address, and you'll receive testnet FLOW tokens to interact with smart contracts. +You can fund your account with testnet FLOW with the [Flow Faucet]. ---- +Enter your Flow-EVM testnet address, and you'll receive testnet FLOW tokens to interact with smart contracts. -## **Solidity Code Example: Retrieving Random Numbers** +## Solidity code example: retrieving random numbers -Below is a simple Solidity contract that interacts with the Cadence Arch contract to retrieve a pseudo-random number. +The following is a simple Solidity contract that interacts with the Cadence Arch contract to retrieve a pseudo-random number: ```solidity // SPDX-License-Identifier: GPL-3.0 @@ -83,59 +69,52 @@ contract CadenceArchCaller { return output; } } - ``` -### **Explanation of the Contract** +### Explanation of the contract 1. **Cadence Arch Address**: - The `cadenceArch` variable stores the address of the Cadence Arch precompiled contract - (`0x0000000000000000000000010000000000000001`), which is constant across Flow EVM. + The `cadenceArch` variable stores the address of the Cadence Arch precompiled contract (`0x0000000000000000000000010000000000000001`), which is constant across Flow EVM. 2. **Revertible Random**: - The `revertibleRandom()` function makes a static call to the `revertibleRandom()` function to fetch a pseudo-random - number. If the call is successful, it decodes the result as a `uint64` random value. + The `revertibleRandom()` function makes a static call to the `revertibleRandom()` function to fetch a pseudo-random number. If the call is successful, it decodes the result as a `uint64` random value. ---- - -## **Deploying and Testing the Contract** +## Deploy and test the contract -### Compile and Deploy the Contract +### Compile and deploy the contract 1. Open Remix IDE. 2. Create a new file and paste the Solidity code above. -![Creating file in Remix](./imgs/vrf-2.png) + ![Creating file in Remix](./imgs/vrf-2.png) -3. Compile the contract by selecting the appropriate Solidity compiler version (0.8.x). +3. To compile the contract, select the appropriate Consumer DeFi compiler version (0.8.x). -![Compiling in Remix](./imgs/vrf-3.png) + ![Compiling in Remix](./imgs/vrf-3.png) -4. Connect Remix to your Metamask wallet (with Flow EVM testnet) by selecting **Injected Web3** as the environment. +4. Connect Remix to your Metamask wallet (with Flow EVM testnet). To do this, select **Injected Web3** as the environment. -![Connecting to MetaMask](./imgs/vrf-4.png) + ![Connecting to MetaMask](./imgs/vrf-4.png) 5. Deploy the contract. -![Deploying the contract](./imgs/vrf-5.png) + ![Deploying the contract](./imgs/vrf-5.png) ### Call revertibleRandom After deployment, you can interact with the contract to retrieve a random number. -Call the `revertibleRandom()` function in the left sidebar on the deployed contract. This will fetch a pseudo-random number generated by Flow's VRF. +Call the `revertibleRandom()` function in the left sidebar on the deployed contract. This fetches a pseudo-random number that Flow's VRF generates. ![Calling revertibleRandom function](./imgs/vrf-6.png) The result will be a `uint64` random number generated on Flow EVM. ---- +## Generate random numbers in a range -## **Generating Random Numbers in a Range** - -For use-cases like games and lotteries, it's useful to generate a random number within a specified range, the following example shows how to get a value between a min and max number. +For use-cases like games and lotteries, it's useful to generate a random number within a specified range. The following example shows how to get a value between a min and max number. ```solidity // SPDX-License-Identifier: GPL-3.0 @@ -163,17 +142,17 @@ The above code is susceptible to the [modulo bias], particularly if the random n ::: -## **Secure Randomness with Commit-Reveal Scheme in Solidity** +## Secure randomness with commit-reveal scheme in Solidity -The **`revertibleRandom()`** function can be directly used to generate a pseudo-random number. However, in certain situations, especially involving untrusted callers, this function exposes a vulnerability: the ability of a transaction to **revert after seeing the random result**. +You can use the **`revertibleRandom()`** function directly to generate a pseudo-random number. However, in certain situations, especially with untrusted callers, this function exposes a vulnerability: the ability of a transaction to **revert after seeing the random result**. -**The Issue with Using `revertibleRandom()` Directly:** +**The Issue with Using `revertibleRandom()` Directly** - When an untrusted party calls a contract function that uses `revertibleRandom()`, they receive the random number **during the transaction execution**. -- **Post-selection** is the ability of the caller to abort the transaction if the random outcome is unfavorable. In this case, the user could choose to revert the transaction (for example, if they lose a bet) and attempt to call the function again in hopes of a better outcome. -- This can lead to a form of **transaction reversion attack**, where the randomness can be exploited by repeatedly attempting transactions until a favorable result is obtained. +- **Post-selection** is the caller's ability to abort the transaction if the random outcome is unfavorable. In this case, the user could choose to revert the transaction (for example, if they lose a bet) and attempt to call the function again in hopes of a better outcome. +- This can lead to a form of _transaction reversion attack_, where the randomness can be exploited by repeatedly attempting transactions until a favorable result is obtained. -## Read More +## Further reading For further details on Flow's randomness and secure development practices, check out the [Flow Randomness Documentation]. @@ -181,12 +160,17 @@ You can also view an example in both Solidity and Cadence of a [random coin toss _This documentation was contributed by [Noah Naizir] a community developer._ + + [Cadence Arch]: https://github.com/onflow/flips/blob/main/protocol/20231116-evm-support.md#cadence-arch [Flow EVM Testnet RPC]: https://testnet.evm.nodes.onflow.org/ [Flow EVM Testnet Explorer]: https://evm-testnet.flowscan.io/ [Flow Faucet]: https://testnet-faucet.onflow.org/fund-account [modulo bias]: https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/ [this repository]: https://github.com/onflow/random-coin-toss -[Flow Randomness Documentation]: https://developers.flow.com/build/advanced-concepts/randomness +[Flow Randomness Documentation]: https://developers.flow.com/build/cadence/advanced-concepts/randomness [random coin toss implentation]: https://github.com/onflow/random-coin-toss [Noah Naizir]: https://x.com/noah_overflow +[Network information]: ../../build/evm/quickstart.md#network-information +[Wallets & Configurations]: ../../blockchain-development-tutorials/evm/setup/integrating-metamask.mdx +[commit reveal]: https://github.com/onflow/random-coin-toss/blob/main/solidity/src/CoinToss.sol \ No newline at end of file diff --git a/docs/build/guides/fungible-token.md b/docs/blockchain-development-tutorials/tokens/fungible-token-cadence.md similarity index 66% rename from docs/build/guides/fungible-token.md rename to docs/blockchain-development-tutorials/tokens/fungible-token-cadence.md index 47d159f819..9a2dfab993 100644 --- a/docs/build/guides/fungible-token.md +++ b/docs/blockchain-development-tutorials/tokens/fungible-token-cadence.md @@ -1,7 +1,7 @@ --- title: Creating a Fungible Token description: Learn how to create and deploy a fungible token on Flow using Cadence. Follow this guide to implement the Flow Fungible Token standard, manage token minting, transfers, and vault management. -sidebar_position: 6 +sidebar_position: 1 keywords: - fungible token - Flow token @@ -23,24 +23,21 @@ keywords: :::info -This guide is an in-depth tutorial on launching a Fungible Token contract from scratch. To launch in 2 minutes using a tool check out [Toucans](https://toucans.ecdao.org/) +This guide is an in-depth tutorial on launching a Fungible Token contract from scratch. To launch in two minutes with a tool, check out [Toucans] ::: -## What are Fungible Tokens? +## What are fungible tokens? -Fungible tokens are digital assets that are interchangeable and indistinguishable with other tokens of the same type. This means that each token is identical in specification to every other token in circulation. Think of them like traditional money; every dollar bill has the same value as every other dollar bill. Fungible tokens play a crucial role in web3 ecosystems, serving as both a means of payment and an incentive for network participation. They can take on various roles including currencies, structured financial instruments, shares of index funds, and even voting rights in decentralized autonomous organizations. +Fungible tokens are digital assets that are interchangeable and indistinguishable with other tokens of the same type. This means that each token is identical in specification to every other token in circulation. Think of them like traditional money; every dollar bill has the same value as every other dollar bill. + +Fungible tokens play a crucial role in web3 ecosystems. They serve as both a means of payment and an incentive for network participation. They can take on various roles, such as currencies, structured financial instruments, shares of index funds, and even voting rights in decentralized autonomous organizations. ## Vaults on Flow -On the Flow blockchain and in the Cadence programming language, -fungible tokens are stored in structures called resources. -Resources are objects in Cadence that store data, -but have special restrictions about how they can be stored and transferred, -making them perfect for representing digital objects with real value. +On the Flow blockchain and in the Cadence programming language, fungible tokens are stored in structures called resources. Resources are objects in Cadence that store data, but have special restrictions about how they can be stored and transferred, which makes them perfect to represent digital objects with real value. -You can learn more about resources in the Cadence [documentation](https://cadence-lang.org/docs/language/resources) -and [tutorials](https://cadence-lang.org/docs/tutorial/resources). +You can learn more about resources in the [Cadence documentation] and [Cadence tutorials]. For fungible tokens specifically, tokens are represented by a resource type called a `Vault`: @@ -53,58 +50,52 @@ access(all) resource interface Vault { } ``` -Think of a `Vault` as a digital piggy bank. -Users who own fungible tokens store vault objects that track their balances -directly in their account storage. This is opposed to languages -that track user balances in a central ledger smart contract. +Think of a `Vault` as a digital piggy bank. Users who own fungible tokens store vault objects that track their balances directly in their account storage. This is opposed to languages that track user balances in a central ledger smart contract. When you transfer tokens from one vault to another: -1. The transferor's vault creates a temporary vault holding the transfer amount. +1. The transferor's vault creates a temporary vault that contains the transfer amount. 2. The original vault's balance decreases by the transfer amount. -3. The recipient's vault receives the tokens from the temporary vault - and adds the temporary vault's balance to the its own balance. +3. The recipient's vault receives the tokens from the temporary vault and adds the temporary vault's balance to the its own balance. 4. The temporary vault is then destroyed. This process ensures secure and accurate token transfers on the Flow blockchain. -## Fungible Token Standard +## Fungible token standard + +The [Fungible Token Standard] defines how a fungible token should behave on Flow. Wallets and other platforms need to recognize these tokens, so they adhere to a specific interface, which defines fields like balance, totalSupply, withdraw functionality, and more. This interface ensures that all fungible tokens on Flow have a consistent structure and behavior. -The [Fungible Token Standard](https://github.com/onflow/flow-ft) defines how a fungible token should behave on Flow. -Wallets and other platforms need to recognize these tokens, -so they adhere to a specific interface, which defines fields like balance, -totalSupply, withdraw functionality, and more. -This interface ensures that all fungible tokens on Flow have a consistent structure and behavior. -Clink the link to the fungible token standard to see the full standard -and learn about specific features and requirements. +Clink the link to the fungible token standard to see the full standard and learn about specific features and requirements. -[Learn more about interfaces here](https://developers.flow.com/cadence/language/interfaces). +[Learn more about interfaces here]. -## Setting Up a Project +## Set up a project -To start creating a Fungible Token on the Flow blockchain, you'll first need some tools and configurations in place. +To create a fungible token on the Flow blockchain, you'll first need some tools and configurations in place. -### Installing Flow CLI +### Install Flow CLI The **Flow CLI** (Command Line Interface) provides a suite of tools that allow developers to interact seamlessly with the Flow blockchain. -If you haven't installed the Flow CLI yet and have [Homebrew](https://brew.sh/) installed, -you can run `brew install flow-cli`. If you don't have Homebrew, -please follow [the installation guide here](https://developers.flow.com/tools/flow-cli/install). +If you haven't installed the Flow CLI yet and have [Homebrew] installed, you can run `brew install flow-cli`. If you don't have Homebrew, follow the [Flow CLI installation guide]. + +### Initialize a new project -### Initializing a New Project +:::info + +> 💡 Here is a link to the [completed code] if you want to skip ahead or reference as you follow along. -> 💡 Note: Here is [a link to the completed code](https://github.com/chasefleming/FooToken) if you want to skip ahead or reference as you follow along. +::: -Once you have the Flow CLI installed, you can set up a new project using the `flow init` command. This command initializes the necessary directory structure and a `flow.json` configuration file (a way to configure your project for contract sources, deployments, accounts, and more): +After you've installed the Flow CLI, you can set up a new project with the `flow init` command. This command initializes the necessary directory structure and a `flow.json` configuration file (a way to configure your project for contract sources, deployments, accounts, and more): ```bash flow init FooToken ``` -> Note: Select "No" when it asks you to install core contracts for the purposes of this tutorial. +Select `Basic Cadence project (no dependencies)`. -Upon execution, the command will generate the following directory structure: +When you execute the command, it generates the following directory structure: ``` /cadence @@ -121,19 +112,9 @@ Now, navigate into the project directory: cd FooToken ``` -In our configuration file, called `flow.json`, for the network we want to use, -we are going to state the address the `FungibleToken` contract is deployed -to via `aliases` in a new `contracts` section. Since it is a standard contract, -it has already been deployed to the emulator, a tool that runs and emulates -a local development version of the Flow Blockchain, for us. -You can find addresses for other networks, like Testnet and Mainnet, on the [Fungible Token Standard repo](https://github.com/onflow/flow-ft). +In our configuration file, called `flow.json`, for the network we want to use, we'll state the address the `FungibleToken` contract is deployed to via `aliases` in a new `contracts` section. Since it is a standard contract, it has already been deployed to the emulator, a tool that runs and emulates a local development version of the Flow Blockchain, for us. You can find addresses for other networks, like Testnet and Mainnet, on the [Fungible Token Standard] repo. -We'll also need to add the addresses for `ViewResolver`, `MetadataViews`, -and `FungibleTokenMetadataViews`, which are other important contracts to use. -These contracts are deployed to the Flow emulator by default, -so there is not need to copy their code into your repo. -The addresses below are the addresses in the emulator that your contract -will import them from. +We'll also need to add the addresses for `ViewResolver`, `MetadataViews`, and `FungibleTokenMetadataViews`, which are other important contracts to use. These contracts are deployed to the Flow emulator by default, so there is not need to copy their code into your repo. The addresses below are the addresses in the emulator that your contract will import them from. ```json "contracts": { @@ -160,9 +141,9 @@ will import them from. } ``` -## Writing Our Token Contract +## Write Our token contract -Next let's create a `FooToken` contract at `cadence/contract/FooToken.cdc` using the boilerplate `generate` command from the Flow CLI: +Next let's create a `FooToken` contract at `cadence/contract/FooToken.cdc` with the boilerplate `generate` command from the Flow CLI: ```bash flow generate contract FooToken @@ -176,10 +157,9 @@ In this contract file, we want to import our `FungibleToken` contract that we've import "FungibleToken" ``` -In this same file, let's create our contract which implements the `FungibleToken` contract interface (it does so by setting it following the `FooToken:`). -We'll also include fields for standard storage and public paths -for our resource definitions. -In our `init` — which runs on the contract's first deployment and is used to set initial values — let's set an starting total supply of 1,000 tokens for this example. +In this same file, let's create our contract which implements the `FungibleToken` contract interface (to do this, it sets it after the `FooToken:`). We'll also include fields for standard storage and public paths for our resource definitions. + +In our `init` — which runs on the contract's first deployment and is used to set initial values — let's set an initial total supply of 1,000 tokens for this example. ```cadence // ...previous code @@ -200,12 +180,9 @@ access(all) contract FooToken: FungibleToken { } ``` -### Creating a Vault +### Create a vault -Inside of this contract, we'll need to create a resource for a `Vault`. -The `FungibleToken` standard requires that your vault implements the `FungibleToken.Vault` interface. -This interface inherits from [many other interfaces](https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc#L140) -which enforce different functionality that you can learn about in the standard. +Inside of this contract, we'll need to create a resource for a `Vault`. The `FungibleToken` standard requires that your vault implements the `FungibleToken.Vault` interface. This interface inherits from [many other interfaces], which enforce different functionality that you can learn about in the standard. ```cadence import "FungibleToken" @@ -226,16 +203,9 @@ access(all) contract FooToken: FungibleToken { } ``` -In order to give an account a vault, we need to create a function -that creates a vault of our FooToken type and returns it to the account. -This function takes a `vaultType: Type` argument that allows the caller -to specify which type of `Vault` they want to create. -Contracts that implement multiple `Vault` types can use this argument, -but since your contract is only implementing one `Vault` type, -it can ignore the argument. +In order to give an account a vault, we need to create a function that creates a vault of our `FooToken` type and returns it to the account. This function takes a `vaultType: Type` argument that allows the caller to specify which type of `Vault` they want to create. Contracts that implement multiple `Vault` types can use this argument, but since your contract only implements one `Vault` type, it can ignore the argument. -A simpler version of this function with no parameter -should also be added to your `Vault` implementation. +You should also add a simpler version of this function with no parameter to your `Vault` implementation. ```cadence import "FungibleToken" @@ -264,9 +234,7 @@ access(all) contract FooToken: FungibleToken { } ``` -Inside our `Vault` resource, we also need a way to withdraw balances. -To do that, we need to add a `withdraw()` function that returns a new vault -with the transfer amount and decrements the existing balance. +Inside our `Vault` resource, we also need a way to withdraw balances. To do that, we need to add a `withdraw()` function that returns a new vault with the transfer amount and decrements the current balance. ```cadence import "FungibleToken" @@ -291,36 +259,18 @@ access(all) contract FooToken: FungibleToken { } ``` -As you can see, this function has an `access(FungibleToken.Withdraw)` access modifier. -This is an example of entitlements in Cadence. -[Entitlements](https://cadence-lang.org/docs/language/access-control#entitlements) -are a way for developers to restrict access to privileged fields and functions -in a composite type like a resource when a reference is created for it. -In this example, the `withdraw()` function is always accessible to code that -controls the full `Vault` object, but if a reference is created for it, -the `withdraw()` function can only be called if the reference -is authorized by the owner with `FungibleToken.Withdraw`, -which is [a standard entitlement](https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc#L53) -defined by the FungibleToken contract: +As you can see, this function has an `access(FungibleToken.Withdraw)` access modifier. This is an example of entitlements in Cadence. [Entitlements] are a way for developers to restrict access to privileged fields and functions in a composite type like a resource when a reference is created for it. They are what protects third-party access to the privileged functionality in your resource objects. We recommend that you read the [Entitlements] documentation to understand how to use the feature properly. + +[References]can be freely up-casted and down-casted in Cadence, so it is important for privileged functionality to be protected by an entitlement so that it can only be accessed if it is authorized. + +In this example, the `withdraw()` function is always accessible to code that controls the full `Vault` object, but if a reference is created for it, the `withdraw()` function can only be called if the reference is authorized by the owner with `FungibleToken.Withdraw`, which is a [standard entitlement] defined by the FungibleToken contract: ```cadence // Example of an authorized entitled reference to a FungibleToken.Vault ``` -Entitlements are important to understand because they are what protects -privileged functionality in your resource objects from being accessed by third-parties. -It is recommended to read the [entitlements documentation](https://cadence-lang.org/docs/language/access-control#entitlements) -to understand how to use the feature properly. - -[References](https://cadence-lang.org/docs/language/references) can be freely up-casted and down-casted in Cadence, so it is important -for privileged functionality to be protected by an entitlement so that it can -only be accessed if it is authorized. - -In addition to withdrawing, the vault also needs a way to deposit. -We'll [typecast](https://cadence-lang.org/docs/language/operators#casting-operators) -to make sure we are dealing with the correct token, update the vault balance, -and destroy the vault. Add this code to your resource: +In addition to withdrawl, the vault also needs a way to deposit. We'll [typecast] to make sure we are dealing with the correct token, update the vault balance, and destroy the vault. Add this code to your resource: ```cadence import "FungibleToken" @@ -347,10 +297,7 @@ access(all) contract FooToken: FungibleToken { } ``` -Many projects rely on events the signal when withdrawals, deposits, or burns happen. -Luckily, the `FungibleToken` standard handles the definition and emission -of events for projects, so there is no need for you to add any events -to your implementation for withdraw, deposit, and burn. +Many projects rely on events the signal when withdrawals, deposits, or burns happen. Luckily, the `FungibleToken` standard handles the definition and emission of events for projects, so there is no need for you to add any events to your implementation for withdraw, deposit, and burn. Here are the `FungibleToken` event definitions: @@ -365,20 +312,13 @@ access(all) event Deposited(type: String, amount: UFix64, to: Address?, toUUID: access(all) event Burned(type: String, amount: UFix64, fromUUID: UInt64) ``` -These events are [emitted by the `Vault` interface](https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc#L198) -in the `FungibleToken` contract whenever the relevant function is called on any implementation. +These events are emitted by the [`Vault` interface] in the `FungibleToken` contract whenever the relevant function is called on any implementation. -One important piece to understand about the `Burned` event in particular -is that in order for it to be emitted when a `Vault` is burned, it needs to -be burnt via [the `Burner` contract's `burn()` method](https://github.com/onflow/flow-ft/blob/master/contracts/utility/Burner.cdc#L23). +One important piece to understand about the `Burned` event in particular is that for it to be emitted when a `Vault` is burned, it needs to be burnt via [the `Burner` contract's `burn()` method]. -The [`Burner` contract](../core-contracts/14-burner.md) defines a standard -that all projects should use for handling the destruction of any resource. -It allows projects to define custom logic that can be executed when a resource is destroyed, -like emitting events, or updating a field in the contract to show that the resource was destroyed. +The [`Burner` contract] defines a standard that all projects should use to handle the destruction of any resource. It allows projects to define custom logic that can be executed when a resource is destroyed, like emitting events, or update a field in the contract to show that the resource was destroyed. -This will call the resource's `burnCallback()` function, which emits the event. -You'll need to also add this function to your token contract now: +This will call the resource's `burnCallback()` function, which emits the event. You'll need to also add this function to your token contract now: ```cadence import "FungibleToken" @@ -407,11 +347,9 @@ access(all) contract FooToken: FungibleToken { } ``` -If you ever need to destroy a `Vault` with a non-zero balance, -you should destroy it via the `Burner.burn` method so this important function can be called. +If you ever need to destroy a `Vault` with a non-zero balance, you should destroy it via the `Burner.burn` method so this important function can be called. -There are three other utility methods that need to be added to your `Vault` -to get various information: +There are three other utility methods that need to be added to your `Vault` to get various information: ```cadence import "FungibleToken" @@ -449,20 +387,11 @@ access(all) contract FooToken: FungibleToken { } ``` -### Adding Support for Metadata Views +### Add support for metadata views -The Fungible Token standard also enforces that implementations -provide functionality to return a set of standard views about the tokens -via the [ViewResolver](https://github.com/onflow/flow-nft/blob/master/contracts/ViewResolver.cdc) -and [FungibleTokenMetadataViews](https://github.com/onflow/flow-ft/blob/master/contracts/FungibleTokenMetadataViews.cdc) definitions. -(You will need to add these imports to your contract now) -These provide developers with standard ways of representing metadata -about a given token such as supply, token symbols, website links, and standard -account paths and types that third-parties can access in a standard way. -You can see the [metadata views documentation](../advanced-concepts/metadata-views.md) -for a more thorough guide using a NFT contract as an example. +The Fungible Token standard also enforces that implementations provide functionality to return a set of standard views about the tokens via the [ViewResolver] and [FungibleTokenMetadataViews] definitions. (You will need to add these imports to your contract now.) These provide developers with standard ways to represent metadata about a given token such as supply, token symbols, website links, and standard account paths and types that third-parties can access in a standard way. -For now, you can add this code to your contract to support the important metadata views: +You can see the [metadata views documentation] for a more thorough guide that uses an NFT contract as an example. For now, you can add this code to your contract to support the important metadata views: ```cadence import "FungibleToken" @@ -504,7 +433,7 @@ access(all) contract FooToken: FungibleToken { name: "Example Foo Token", symbol: "EFT", description: "This fungible token is used as an example to help you develop your next FT #onFlow.", - externalURL: MetadataViews.ExternalURL("https://developers.flow.com/build/guides/fungible-token"), + externalURL: MetadataViews.ExternalURL("https://developers.flow.com/build/cadence/guides/fungible-token"), logos: medias, socials: { "twitter": MetadataViews.ExternalURL("https://twitter.com/flow_blockchain") @@ -550,9 +479,9 @@ access(all) contract FooToken: FungibleToken { } ``` -### Creating a Minter +### Create a minter -Let's create a minter resource which is used to mint vaults that have tokens in them. We can keep track of tokens we are minting with totalSupply +Let's create a minter resource which is used to mint vaults that have tokens in them. We can keep track of tokens we mint with totalSupply. If we want the ability to create new tokens, we'll need a way to mint them. To do that, let's create another resource on the `FooToken` contract. This will have a `mintToken`function which can increase the total supply of the token. @@ -590,10 +519,7 @@ access(all) contract FooToken: FungibleToken { } ``` -We also want to decide which account/s we want to give this ability to. -In our example, we'll give it to the account where the contract is deployed. -We can set this in the contract init function below the setting of total supply -so that when the contract is created the minter is stored on the same account. +We also want to decide which accounts we want to give this ability to. In our example, we'll give it to the account where the contract is deployed. We can set this in the contract init function below the setting of total supply so that when the contract is created, the minter is stored on the same account. ```cadence import "FungibleToken" @@ -611,7 +537,7 @@ access(all) contract FooToken: FungibleToken { } ``` -After each of these steps, your `FooToken.cdc` contract file should now look like this: +After each of these steps, your `FooToken.cdc` contract file will now look like this: ```cadence import "FungibleToken" @@ -662,7 +588,7 @@ access(all) contract FooToken: FungibleToken { name: "Example Foo Token", symbol: "EFT", description: "This fungible token is used as an example to help you develop your next FT #onFlow.", - externalURL: MetadataViews.ExternalURL("https://developers.flow.com/build/guides/fungible-token"), + externalURL: MetadataViews.ExternalURL("https://developers.flow.com/build/cadence/guides/fungible-token"), logos: medias, socials: { "twitter": MetadataViews.ExternalURL("https://twitter.com/flow_blockchain") @@ -788,10 +714,9 @@ access(all) contract FooToken: FungibleToken { } ``` -## Deploying the Contract +## Deploy the contract -In order to use the contract, we need to deploy it to the network we want to use it on. -In our case we are going to deploy it to emulator while developing. +To use the contract, we need to deploy it to the network we want to use it on. In our case, we'll deploy it to emulator while we develop it. Back in our `flow.json`, let's add our `FooToken` to the `contracts` after `FungibleToken` with the path of the source code: @@ -799,9 +724,7 @@ Back in our `flow.json`, let's add our `FooToken` to the `contracts` after `Fung "FooToken": "cadence/contracts/FooToken.cdc" ``` -Let's also add a new `deployments` section to `flow.json` with the network -we want to deploy it to, `emulator`, the account we want it deployed to `emulator-account`, -and the list of contracts we want deployed in the array. +Let's also add a new `deployments` section to `flow.json` with the network we want to deploy it to, `emulator`, the account we want it deployed to `emulator-account`, and the list of contracts we want deployed in the array. ```json "deployments": { @@ -811,8 +734,7 @@ and the list of contracts we want deployed in the array. } ``` -Next, using the Flow CLI, we will start the emulator. As mentioned, -this will give us a local development environment for the Flow Blockchain. +Next, via the Flow CLI, we will start the emulator. As mentioned, this will give us a local development environment for the Flow Blockchain. ```bash flow emulator start @@ -824,13 +746,11 @@ Open a new terminal and run the following to deploy your project: flow project deploy ``` -Congrats, you've deployed your contract to the Flow Blockchain emulator. -To read more about deploying your project to other environments, -see the [CLI docs](https://developers.flow.com/tools/flow-cli/deployment/deploy-project-contracts). +Congrats, you've deployed your contract to the Flow Blockchain emulator. To read more about how to deploy your project to other environments, see the [Deploy Project Contracts with CLI] docs. -## Reading the Token's Total Supply +## Read the token's total supply -Let's now check that our total supply was initialized with 1,000 FooTokens. Go ahead and create a script called `get_total_supply.cdc` using the `generate` command. +Let's now check that our total supply was initialized with 1,000 FooTokens. Go ahead and create a script called `get_total_supply.cdc` with the `generate` command. ```bash flow generate script get_total_supply @@ -846,36 +766,28 @@ access(all) fun main(): UFix64 { } ``` -To run this using the CLI, enter this in your terminal: +To run this with the CLI, enter this in your terminal: ```bash flow scripts execute cadence/scripts/get_total_supply.cdc ``` -In the terminal where you started the emulator, you should see `Result: 1000.0` +In the terminal where you started the emulator, you will see `Result: 1000.0` -To learn more about running scripts using Flow CLI, [see the docs](https://developers.flow.com/tools/flow-cli/scripts/execute-scripts). +To learn more about how to run scripts with Flow CLI, see the [Execute Scripts in Flow CLI] docs. -## Giving Accounts the Ability to Receive Tokens +## Give accounts the ability to receive tokens -On Flow, newly created accounts cannot receive arbitrary assets. -They need to be initialized to receive resources. -In our case, we want to give accounts tokens and we'll need to create -a `Vault` (which acts as a receiver) on each account that we want -to have the ability to receive tokens. To do this, we'll need to run a transaction -which will create the vault and set it in their storage -using the `createEmptyVault()` function we created earlier on the contract. +On Flow, newly-created accounts cannot receive arbitrary assets. They need to be initialized to receive resources. +In our case, we want to give accounts tokens and we'll need to create a `Vault` (which acts as a receiver) on each account that we want to have the ability to receive tokens. To do this, we'll need to run a transaction which will create the vault and set it in their storage with the `createEmptyVault()` function we created earlier on the contract. -Let's first create the file at `cadence/transactions/setup_ft_account.cdc` using the `generate` command: +Let's first create the file at `cadence/transactions/setup_ft_account.cdc` with the `generate` command: ```bash flow generate transaction setup_ft_account ``` -Then add this code to it. -This will call the `createEmptyVault` function, save it in storage, -and create a capability for the vault which will later allow us to read from it -(To learn more about capabilities, see [the Cadence docs here](https://developers.flow.com/cadence/language/capabilities)). +Then add this code to it. This will call the `createEmptyVault` function, save it in storage, and create a capability for the vault which will later allow us to read from it. To learn more about capabilities, see the [Cadence Capabilities] docs ```cadence import "FungibleToken" @@ -904,11 +816,10 @@ transaction () { } ``` -There are also examples of [generic transactions](https://github.com/onflow/flow-ft/blob/master/transactions/metadata/setup_account_from_address.cdc) -that you can use to setup an account for ANY fungible token using metadata views! -You should check those out and try to use generic transactions whenever it is possible. +There are also examples of [generic transactions] that you can use to setup an account for ANY fungible token with metadata views! +Check those out and try to use generic transactions whenever it is possible. -Next let's create a new emulator account using the CLI. We'll use this account to create a new vault and mint tokens into it. Run: +Next let's create a new emulator account with the CLI. We'll use this account to create a new vault and mint tokens into it. Run: ```bash flow accounts create @@ -928,11 +839,11 @@ To call our setup account transaction from the CLI, we'll run the following: flow transactions send ./cadence/transactions/setup_ft_account.cdc --signer test-acct --network emulator ``` -To learn more about running transactions using CLI, [see the docs](https://developers.flow.com/tools/flow-cli/transactions/send-transactions). +To learn more about how to run transactions with Flow CLI, see the [Send a Transaction] docs. -## Reading a Vault's Balance +## Read a vault's balance -Let's now read the balance of the newly created account (`test-acct`) to check it's zero. +Let's now read the balance of the newly-created account (`test-acct`) to check that it's zero. Create this new script file `cadence/scripts/get_footoken_balance.cdc`: @@ -960,20 +871,17 @@ access(all) fun main(address: Address): UFix64 { } ``` -To run this script using the CLI, enter the following in your terminal. -Note: you'll need to replace `123` with the address created by CLI -in your `flow.json` for the `test-acct` address. +To run this script with the CLI, enter the following in your terminal. You'll need to replace `123` with the address created by Flow CLI in your `flow.json` for the `test-acct` address. ```bash flow scripts execute cadence/scripts/get_footoken_balance.cdc 123 // change "123" to test-acct address ``` -You should see a balance of zero logged. +You will see a balance of zero logged. -## Minting More Tokens +## Mint more tokens -Now that we have an account with a vault, let's mint some tokens into it -using the Minter we created on the contract account. +Now that we have an account with a vault, let's mint some tokens into it with the Minter we created on the contract account. To do this, let's create a new transaction file `cadence/transactions/mint_footoken.cdc`: @@ -981,9 +889,7 @@ To do this, let's create a new transaction file `cadence/transactions/mint_footo flow generate transaction mint_footoken ``` -Next, let's add the following code to the `mint_footoken.cdc` file. -This code will attempt to borrow the minting capability -and mint 20 new tokens into the receivers account. +Next, let's add the following code to the `mint_footoken.cdc` file. This code will attempt to borrow the minting capability and mint 20 new tokens into the receivers account. ```cadence import "FungibleToken" @@ -1021,9 +927,7 @@ transaction(recipient: Address, amount: UFix64) { } ``` -To run this transaction, enter this in your terminal. -Note: `123` should be replaced with address of `test-acct` found in your `flow.json`. -This command also states to sign with our `emulator-account` on the Emulator network. +To run this transaction, enter this in your terminal. Replace `123` with the `test-acct` address found in your `flow.json`. This command also states to sign with our `emulator-account` on the Emulator network. ```bash flow transactions send ./cadence/transactions/mint_footoken.cdc 123 20.0 --signer emulator-account --network emulator @@ -1035,9 +939,9 @@ Let's go ahead and read the vault again. Remember to replace `123` with the corr flow scripts execute cadence/scripts/get_footoken_balance.cdc 123 ``` -It should now say 20 tokens are in the vault. +It will now say 20 tokens are in the vault. -## Transferring Tokens Between Accounts +## Transfer tokens between accounts The final functionality we'll add is the ability to transfer tokens from one account to another. @@ -1047,9 +951,7 @@ To do that, create a new `cadence/transactions/transfer_footoken.cdc` transactio flow generate transaction transfer_footoken ``` -Let's add the code which states that the signer of the transaction -will withdraw from their vault and put it into the receiver's vault -which will be passed as a transaction argument. +Let's add the code which states that the signer of the transaction will withdraw from their vault and put it into the receiver's vault, which will be passed as a transaction argument. ```cadence import "FungibleToken" @@ -1110,7 +1012,7 @@ Don't forget the new account will need a vault added, so let's run the following flow transactions send ./cadence/transactions/setup_ft_account.cdc --signer test-acct-2 --network emulator ``` -Now, let's send 1 token from our earlier account to the new account. Remember to replace `123` with account address of `test-acct-2`. +Now, let's send one token from our earlier account to the new account. Remember to replace `123` with account address of `test-acct-2`. ```bash flow transactions send ./cadence/transactions/transfer_footoken.cdc 123 1.0 --signer test-acct --network emulator @@ -1122,13 +1024,45 @@ After that, read the balance of `test-acct-2` (replace the address `123`). flow scripts execute cadence/scripts/get_footoken_balance.cdc 123 ``` -You should now see 1 token in `test-acct-2` account! +You will now see one token in `test-acct-2` account! -The transfer transaction also has a [generic version](https://github.com/onflow/flow-ft/blob/master/transactions/generic_transfer_with_address.cdc) that developers are encouraged to use! +The transfer transaction also has a [generic version] that developers are encouraged to use! ## More -- [View a repo of this example code](https://github.com/chasefleming/FooToken) -- [Review an `ExampleToken` contract implementing all of the remaining FungibleToken interface](https://github.com/onflow/flow-ft/blob/master/contracts/ExampleToken.cdc) -- [View the Flow Token Standard](https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc) -- Learn about how you can [bridge your FTs to Flow-EVM](../../tutorials/cross-vm-apps/vm-bridge.md#cross-vm-bridge) and how you can build your FT project [to be compatible with the Flow VM bridge](../../tutorials/cross-vm-apps/vm-bridge.md#prep-your-assets-for-bridging). +- View a repo of this [completed code]. +- Review an [`ExampleToken`] contract that implements all of the remaining FungibleToken interface. +- View the [Flow Token Standard] +- Learn about how you can [bridge your FTs to Flow-EVM] and how you can [build your FT project] to be compatible with the Flow VM bridge. + + + +[bridge your FTs to Flow-EVM]: ../cross-vm-apps/vm-bridge.md#cross-vm-bridge +[`Burner` contract]: ../../build/cadence/core-contracts/14-burner.md +[build your FT project]: ../cross-vm-apps/vm-bridge.md#prep-your-assets-for-bridging +[Cadence Capabilities]: https://cadence-lang.org/docs/language/capabilities +[Cadence documentation]: https://cadence-lang.org/docs/language/resources +[Cadence tutorials]: https://cadence-lang.org/docs/tutorial/resources +[completed code]: https://github.com/onflow/FooToken +[Deploy Project Contracts with CLI]: /docs/build/tools/flow-cli/deployment/deploy-project-contracts.md +[Entitlements]: https://cadence-lang.org/docs/language/access-control#entitlements +[`ExampleToken`]: https://github.com/onflow/flow-ft/blob/master/contracts/ExampleToken.cdc +[Execute Scripts in Flow CLI]: /docs/build/tools/flow-cli/scripts/execute-scripts.md +[Flow Token Standard]: https://github.com/onflow/flow-ft +[FungibleTokenMetadataViews]: https://github.com/onflow/flow-ft/blob/master/contracts/FungibleTokenMetadataViews.cdc +[Funglible Token Standard]: https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc +[generic version]: https://github.com/onflow/flow-ft/blob/master/transactions/generic_transfer_with_address.cdc +[generic transactions]: https://github.com/onflow/flow-ft/blob/master/transactions/metadata/setup_account_from_address.cdc +[Flow CLI installation guide]: ../../build/tools/flow-cli/install.md +[Homebrew]: https://brew.sh/ +[Learn more about interfaces here]: https://cadence-lang.org/docs/language/interfaces +[many other interfaces]: https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc#L140 +[metadata views documentation]: ../../build/cadence/advanced-concepts/metadata-views.md +[References]: https://cadence-lang.org/docs/language/references +[Send a Transaction]: /docs/build/tools/flow-cli/transactions/send-transactions.md +[standard entitlement]: https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc#L53 +[the `Burner` contract's `burn()` method]: https://github.com/onflow/flow-ft/blob/master/contracts/utility/Burner.cdc#L23 +[Toucans]: https://toucans.ecdao.org/ +[typecast]: https://cadence-lang.org/docs/language/operators/casting-operators +[ViewResolver]: https://github.com/onflow/flow-nft/blob/master/contracts/ViewResolver.cdc +[`Vault` interface]: https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc#L198 diff --git a/docs/blockchain-development-tutorials/tokens/index.md b/docs/blockchain-development-tutorials/tokens/index.md new file mode 100644 index 0000000000..a6d935ad00 --- /dev/null +++ b/docs/blockchain-development-tutorials/tokens/index.md @@ -0,0 +1,38 @@ +--- +title: Token Development and Registration +description: Complete guides for creating, deploying, and registering tokens on Flow using both Cadence and EVM approaches. +sidebar_position: 8 +--- + +# Token Development and Registration + +Flow supports token development through two primary approaches: native Cadence contracts that leverage Flow's unique resource-oriented programming model, and EVM-compatible contracts that enable easy migration from Ethereum. This section provides comprehensive guides for how to create tokens with both approaches, along with registration processes to ensure ecosystem visibility. + +## Cadence token development + +### [Creating a Fungible Token] + +Learn how to build a complete fungible token contract with Cadence's resource-based programming model. This comprehensive guide covers how to implement the Flow Fungible Token standard, manage token vaults for secure storage, create minter resources for controlled token creation, and deploy with proper metadata views. You'll build a production-ready token that integrates seamlessly with Flow's ecosystem, such as wallets, exchanges, and DeFi protocols. + +### [Creating an NFT Contract] + +Master the development of non-fungible token contracts with Flow's powerful Cadence language. This detailed tutorial walks through how to implement the Flow NFT standard, create collection resources for efficient NFT management, build minting mechanisms with access controls, and add comprehensive metadata support. Learn to create NFTs that work perfectly with marketplaces, wallets, and other Flow ecosystem applications. + +### [Register Your Assets in Cadence] + +Complete the registration process for your Cadence-based fungible and non-fungible tokens to ensure visibility across the Flow ecosystem. This guide covers how to submit your tokens to official registries, provide required metadata and documentation, follow community standards for token information, and integrate with major wallets and applications like Flow Wallet and IncrementFi. + +## Flow EVM Token Development + +### [Register Your ERC20 Token] + +Register your ERC20 tokens deployed on Flow EVM to appear in wallets and ecosystem applications. This guide details the GitHub Pull Request process to add tokens to the Flow standard token list, provide proper token metadata and logos, meet verification requirements, and ensure compatibility with Flow Wallet, MetaMask, and other ecosystem tools. + +## Conclusion + +Flow's dual approach to token development provides developers with flexibility to choose the best paradigm for their projects. Whether you want to leverage Cadence's innovative resource model for enhanced security and composability, or use familiar EVM patterns for quick deployment, these guides ensure your tokens integrate seamlessly with Flow's thriving ecosystem of wallets, exchanges, and applications. + +[Creating a Fungible Token]: ./fungible-token-cadence.md +[Creating an NFT Contract]: ./nft-cadence.md +[Register Your Assets in Cadence]: ./register-cadence-assets.md +[Register Your ERC20 Token]: ./register-erc20-token.md diff --git a/docs/build/guides/nft.md b/docs/blockchain-development-tutorials/tokens/nft-cadence.md similarity index 64% rename from docs/build/guides/nft.md rename to docs/blockchain-development-tutorials/tokens/nft-cadence.md index 98f4728406..bd22374894 100644 --- a/docs/build/guides/nft.md +++ b/docs/blockchain-development-tutorials/tokens/nft-cadence.md @@ -1,7 +1,7 @@ --- title: Creating an NFT Contract description: Learn how to create and deploy a non-fungible token (NFT) contract on Flow using Cadence. Follow this guide to implement the Flow NFT standard, manage collections, and handle token minting and transfers. -sidebar_position: 5 +sidebar_position: 2 keywords: - NFT - non-fungible token @@ -24,44 +24,42 @@ keywords: :::info This guide is an in-depth tutorial on launching NFT contracts from scratch. -To launch in 2 minutes using a tool check out [Touchstone](https://www.touchstone.city/) +To launch in two minutes with a tool, check out [Touchstone] ::: ## What are NFTs NFTs, or Non-Fungible Tokens, represent a unique digital asset verified -using blockchain technology. Unlike cryptocurrencies such as Bitcoin, +with blockchain technology. Unlike cryptocurrencies such as Bitcoin, which are fungible and can be exchanged on a one-for-one basis, NFTs are distinct and cannot be exchanged on a like-for-like basis. -This uniqueness and indivisibility make them ideal for representing +This uniqueness and indivisibility make them ideal to represent rare and valuable items like art, collectibles, tickets and even real estate. Their blockchain-backed nature ensures the authenticity and ownership of these digital assets. -## Setting Up a Project +## Set up a project -To start creating an NFT on the Flow blockchain, you'll first need some tools and configurations in place. +To create an NFT on the Flow blockchain, you'll first need some tools and configurations in place. -### Installing Flow CLI +### Instal Flow CLI The **Flow CLI** (Command Line Interface) provides a suite of tools that allow developers to interact seamlessly with the Flow blockchain. -If you haven't installed the Flow CLI yet and have [Homebrew](https://brew.sh/) installed, -you can run `brew install flow-cli`. If you don't have Homebrew, -please follow [the installation guide here](../../tools/flow-cli/install.md). +If you haven't installed the Flow CLI yet and have [Homebrew]installed, you can run `brew install flow-cli`. If you don't have Homebrew, follow the [Flow CLI installation guide]. -### Initializing a New Project +### Initialize a New Project -> 💡 Note: Here is [a link to the completed code](https://github.com/chasefleming/foobar-nft) if you want to skip ahead or reference as you follow along. +> 💡 Note: Here is [a link to the completed code] if you want to skip ahead or reference as you follow along. -Once you have the Flow CLI installed, you can set up a new project using the `flow init` command. This command initializes the necessary directory structure and a `flow.json` configuration file (a way to configure your project for contract sources, deployments, accounts, and more): +After you install the Flow CLI, you can set up a new project with the `flow init` command. This command initializes the necessary directory structure and a `flow.json` configuration file (a way to configure your project for contract sources, deployments, accounts, and more): ```bash flow init foobar-nft ``` -> Note: Select "No" when it asks you to install core contracts for the purposes of this tutorial. +Select `Basic Cadence project (no dependencies)`. Upon execution, the command will generate the following directory structure: @@ -80,8 +78,7 @@ Now, navigate into the project directory: cd foobar-nft ``` -To begin, let's create a contract file named `FooBar` for the `FooBar` token, -which will be the focus of this tutorial. To do this, we can use the boilerplate `generate` command from the Flow CLI: +To begin, let's create a contract file named `FooBar` for the `FooBar` token, which is the focus of this tutorial. To do this, we can use the boilerplate `generate` command from the Flow CLI: ```bash flow generate contract FooBar @@ -95,9 +92,7 @@ access(all) contract FooBar { } ``` -Now, add these contracts to your `flow.json`. -These are important contracts that your contract will import that -are pre-deployed to the emulator. +Now, add these contracts to your `flow.json`. These are important contracts that your contract will import that are pre-deployed to the emulator. ```json "contracts": { @@ -119,18 +114,13 @@ are pre-deployed to the emulator. } ``` -## Setting Up Our NFT on the Contract +## Set up our NFT on the contract -### Understanding Resources +### understand resources -On the Flow blockchain, "[Resources](https://cadence-lang.org/docs/tutorial/resources-compose)" -are a key feature of the Cadence programming language. -They represent unique, non-duplicable assets, ensuring that they can only exist -in one place at a time. This concept is crucial for representing NFTs on Flow, -as it guarantees their uniqueness. +On the Flow blockchain, "[Resources]" are a key feature of the Cadence programming language. They represent unique, non-duplicable assets, and ensure that they can only exist in one place at a time. This concept is crucial for representing NFTs on Flow, as it guarantees their uniqueness. -To begin, let's define a basic `NFT` resource. -This resource requires an `init` method, which is invoked when the resource is instantiated: +To begin, let's define a basic `NFT` resource. This resource requires an `init` method, which is invoked when the resource is instantiated: ```cadence access(all) contract FooBar { @@ -143,8 +133,9 @@ access(all) contract FooBar { } ``` -Every resource in Cadence has a unique identifier assigned to it. -We can use it to set an ID for our NFT. Here's how you can do that: +Every resource in Cadence has a unique identifier assigned to it. We can use it to set an ID for our NFT. + +Here's how you can do that: ```cadence access(all) contract FooBar { @@ -161,8 +152,8 @@ access(all) contract FooBar { } ``` -To control the creation of NFTs, it's essential to have a mechanism -that restricts their minting. This ensures that not just anyone can create an NFT and inflate its supply. +To control the creation of NFTs, it's essential to have a mechanism that restricts their minting. This ensures that not just anyone can create an NFT and inflate its supply. + To achieve this, you can introduce an `NFTMinter` resource that contains a `createNFT` function: ```cadence @@ -182,8 +173,8 @@ access(all) contract FooBar { } ``` -In this example, the `NFTMinter` resource will be stored on the contract account's storage. -This means that only the contract account will have the ability to mint new NFTs. +In this example, the `NFTMinter` resource is stored on the contract account's storage. This means that only the contract account will have the ability to mint new NFTs. + To set this up, add the following line to the contract's `init` function: ```cadence @@ -197,15 +188,12 @@ access(all) contract FooBar { } ``` -### Setting Up an NFT Collection +### Set Up an NFT Collection -Storing individual NFTs directly in an account's storage can cause issues, -especially if you want to store multiple NFTs. -Instead, it's required to create a collection that can hold multiple NFTs. -This collection can then be stored in the account's storage. +If you store individual NFTs directly in an account's storage, it can cause issues, especially if you want to store multiple NFTs. +Instead, you must create a collection that can hold multiple NFTs. You can then store this collection in the account's storage. -Start by creating a new resource named `Collection`. -This resource will act as a container for your NFTs, storing them in a dictionary indexed by their IDs. +To start, create a new resource named `Collection`. This resource will act as a container for your NFTs, and stores them in a dictionary indexed by their IDs. ```cadence access(all) contract FooBar { @@ -226,21 +214,15 @@ access(all) contract FooBar { } ``` -## Fitting the Flow NFT Standard +## Fit the Flow NFT standard -To ensure compatibility and interoperability within the Flow ecosystem, -it's crucial that your NFT contract adheres to the [Flow NFT standard](https://github.com/onflow/flow-nft). -This standard defines the events, functions, resources, metadata and other elements that a contract should have. -By following this standard, your NFTs will be compatible with various marketplaces, apps, and other services within the Flow ecosystem. +To ensure compatibility and interoperability within the Flow ecosystem, it's crucial that your NFT contract adheres to the Flow [NFT standard]. This standard defines the events, functions, resources, metadata and other elements that a contract should have. When you follow this standard, your NFTs will be compatible with various marketplaces, apps, and other services within the Flow ecosystem. -### Applying the Standard +### Apply the Standard -To start, you need to inform the Flow blockchain that your contract will implement the `NonFungibleToken` standard. -Since it's a standard, there's no need for deployment. -It's already available on the Emulator, Testnet, and Mainnet for the community's benefit. +To start, you need to inform the Flow blockchain that your contract will implement the `NonFungibleToken` standard. Since it's a standard, there's no need for deployment. It's already available on the Emulator, Testnet, and Mainnet for the community's benefit. -Begin by importing the token standard into your contract -and adding the correct interface conformances to FooBar, NFT, and Collection: +To start, import the token standard into your contract and add the correct interface conformances to FooBar, NFT, and Collection: ```cadence import "NonFungibleToken" @@ -281,23 +263,11 @@ access(all) contract FooBar: NonFungibleToken { } ``` -As you can see, we also added standard paths for the Collection and Minter +As you can see, we also added standard paths for the Collection and Minter. -These interface conformances for [NFT](https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc#L98) -and [Collection](https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc#L190) -inherit from other interfaces that provide important functionality and restrictions -for your NFT and Collection types. +These interface conformances for [NFT] and [Collection] inherit from other interfaces that provide important functionality and restrictions for your NFT and Collection types. -To allow accounts to create their own collections, add a function -in the main contract that creates a new `Collection` and returns it. -This function takes a `nftType: Type` argument that allows the caller -to specify which type of `Collection` they want to create. -Contracts that implement multiple `NFT` and/or `Collection` types can use this argument, -but since your contract is only implementing one `NFT` and `Collection` type, -it can ignore the argument. -You'll also want to add a simpler one directly -to the `NFT` and `Collection` definitions -so users can directly create a collection from an existing collection: +To allow accounts to create their own collections, add a function in the main contract that creates a new `Collection` and returns it. This function takes a `nftType: Type` argument that allows the caller to specify which type of `Collection` they want to create. Contracts that implement multiple `NFT` and/or `Collection` types can use this argument, but since your contract only implements one `NFT` and `Collection` type, it can ignore the argument. You'll also want to add a simpler one directly to the `NFT` and `Collection` definitions so users can directly create a collection from a current collection: ```cadence access(all) contract FooBar: NonFungibleToken { @@ -380,38 +350,22 @@ access(all) resource Collection: NonFungibleToken.Collection { } ``` -As you can see, this function has an `access(NonFungibleToken.Withdraw)` access modifier. -This is an example of entitlements in Cadence. -[Entitlements](https://cadence-lang.org/docs/language/access-control#entitlements) -are a way for developers to restrict access to privileged fields and functions -in a composite type like a resource when a reference is created for it. -In this example, the `withdraw()` function is always accessible to code that -controls the full `Collection` object, but if a reference is created for it, -the `withdraw()` function can only be called if the reference -is authorized by the owner with `NonFungibleToken.Withdraw`, -which is [a standard entitlement](https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc#L58) -defined by the `NonFungibleToken` contract: +As you can see, this function has an `access(NonFungibleToken.Withdraw)` access modifier. This is an example of entitlements in Cadence. [Entitlements] are a way for developers to restrict access to privileged fields and functions in a composite type like a resource when a reference is created for it. + +In this example, the `withdraw()` function is always accessible to code that controls the full `Collection` object, but if a reference is created for it, the `withdraw()` function can only be called if the reference is authorized by the owner with `NonFungibleToken.Withdraw`, which is a [standard entitlement] defined by the `NonFungibleToken` contract: ```cadence // Example of an authorized entitled reference to a NonFungibleToken.Collection ``` -Entitlements are important to understand because they are what protects -privileged functionality in your resource objects from being accessed by third-parties. -It is recommended to read the [entitlements documentation](https://cadence-lang.org/docs/language/access-control#entitlements) -to understand how to use the feature properly. +It's important to understand entitlements because they protect privileged functionality in your resource objects from third-party access. We recommended that you read the [Entitlements] documentation to understand how to use the feature properly. -[References](https://cadence-lang.org/docs/language/references) can be freely up-casted and down-casted in Cadence, so it is important -for privileged functionality to be protected by an entitlement so that it can -only be accessed if it is authorized. +[References] can be freely up-casted and down-casted in Cadence, so it is important for you to use an entitlement to protect privileged functionality so that it can only be accessed if it is authorized. ### Standard NFT Events -Many projects rely on events the signal when withdrawals or deposits happen. -Luckily, the `NonFungibleToken` standard handles the definition and emission -of events for projects, so there is no need for you to add any events -to your implementation for withdraw and deposit. +Many projects rely on events the signal when withdrawals or deposits happen. Luckily, the `NonFungibleToken` standard handles the definition and emission of events for projects, so there is no need for you to add any events to your implementation for withdraw and deposit. Here are the `FungibleToken` event definitions: @@ -434,28 +388,23 @@ Here are the `FungibleToken` event definitions: ``` -These events are [emitted by the `Collection` interface](https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc#L202) -in the `NonFungibleToken` contract whenever the relevant function is called on any implementation. +These events are emitted by the [`Collection` interface] in the `NonFungibleToken` contract whenever the relevant function is called on any implementation. There is also a `NonFungibleToken.NFT.ResourceDestroyed` event that is emitted every time an NFT is destroyed: + ```cadence /// Event that is emitted automatically every time a resource is destroyed /// The type information is included in the metadata event so it is not needed as an argument access(all) event ResourceDestroyed(id: UInt64 = self.id, uuid: UInt64 = self.uuid) ``` -`ResourceDestroyed` events are standard events that can be added to any resource definition -to be emitted when the resource is destroyed. Learn more about them [in the Cadence docs](https://cadence-lang.org/docs/language/resources#destroy-events). -Additionally, check out the optional [`Burner` contract](../core-contracts/14-burner.md), -which is the standard that all projects should use for handling the destruction of any resource. +`ResourceDestroyed` events are standard events that can be added to any resource definition to be emitted when the resource is destroyed. Learn more about them [in the Cadence docs]. -Lastly, there is a [standard `NonFungibleToken.Updated` event](https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc#L63-L77) -that your contract can emit if the NFT is updated in any way. -This is optional though, so no need to include support for it in your implementation. +Additionally, check out the optional [`Burner` contract], which is the standard that all projects should use to handle any resource's destruction. -To facilitate querying, you'll also want a function to retrieve -important information from the collection, like what types it supports -and all the NFT IDs within a collection: +Lastly, there is a [standard `NonFungibleToken.Updated` event] that your contract can emit if the NFT is updated in any way. This is optional though, so no need to include support for it in your implementation. + +To facilitate querying, you'll also want a function to retrieve important information from the collection, like what types it supports and all the NFT IDs within a collection: ```cadence access(all) resource Collection: NonFungibleToken.Collection { @@ -483,18 +432,12 @@ access(all) resource Collection: NonFungibleToken.Collection { } ``` -### Supporting NFT Metadata +### Supporting NFT metadata + +The Non-Fungible Token standard also enforces that implementations provide functionality to return a set of standard views about the tokens via the [ViewResolver] +and [MetadataViews] definitions. (You will need to add these imports to your contract) -The Non-Fungible Token standard also enforces that implementations -provide functionality to return a set of standard views about the tokens -via the [ViewResolver](https://github.com/onflow/flow-nft/blob/master/contracts/ViewResolver.cdc) -and [MetadataViews](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc) definitions. -(You will need to add these imports to your contract) -These provide developers with standard ways of representing metadata -about a given token such as token symbols, images, royalties, editions, -website links, and standard account paths and types that third-parties can access in a standard way. -You can see the [metadata views documentation](../advanced-concepts/metadata-views.md) -for a more thorough guide using a NFT contract as an example. +These provide developers with standard ways of representing metadata about a given token such as token symbols, images, royalties, editions, website links, and standard account paths and types that third-parties can access in a standard way. You can see the [metadata views documentation] for a more thorough guide that uses a NFT contract as an example. For now, you can add this code to your contract to support the important metadata: @@ -611,24 +554,15 @@ access(all) contract FooBar: NonFungibleToken { } ``` -If you ever plan on making your NFTs more complex, you should look into -adding views for `Edition`, `EVMBridgedMetadata`, `Traits`, and `Royalties`. -These views make it much easier for third-party sites like marketplaces -and NFT information aggregators to clearly display information -about your projects on their apps and websites and are critical -for every project to include if we want to have a vibrant and interoperable -ecosystem. +If you ever plan to make your NFTs more complex, you could add views for `Edition`, `EVMBridgedMetadata`, `Traits`, and `Royalties`. These views make it much easier for third-party sites like marketplaces and NFT information aggregators to clearly display information about your projects on their apps and websites and are critical for every project to include if we want to have a vibrant and interoperable ecosystem. -## Flow VM Bridge NFTs +## Flow VM bridge NFTs -Flow provides an EVM environment where projects can deploy -their solidity smart contracts as an easier on-ramp to building on Flow. -The [Cross-VM Bridge](https://www.github.com/onflow/flow-evm-bridge) enables the movement of -fungible and non-fungible tokens between Flow-Cadence & Flow-EVM. +Flow provides an EVM environment where projects can deploy their solidity smart contracts as an easier on-ramp to building on Flow. The [Cross-VM Bridge] allows the movement of fungible and non-fungible tokens between Flow-Cadence & Flow-EVM. -Learn about how you can [bridge your NFTs to Flow-EVM](../../tutorials/cross-vm-apps/vm-bridge.md#cross-vm-bridge) and how you can build your NFT project [to be compatible with the Flow VM bridge](../../tutorials/cross-vm-apps/vm-bridge.md#prep-your-assets-for-bridging). +Learn about how you can [bridge your NFTs to Flow-EVM] and how you can [build your NFT project] to be compatible with the Flow VM bridge. -## Deploying the Contract +## Deploy the Contract With your contract ready, it's time to deploy it. First, add the `FooBar` contract to the `flow.json` configuration file: @@ -650,18 +584,20 @@ Next, configure the deployment settings by running the following command: flow config add deployment ``` -Choose the `emulator` for the network and `emulator-account` -for the account to deploy to. -Then, select the `FooBar` contract (you may need to scroll down). -This will update your `flow.json` configuration. -After that, you can select `No` when asked to deploy another contract. +Choose the `emulator` for the network and `emulator-account` for the account to deploy to. Then, select the `FooBar` contract (you may need to scroll down). This will update your `flow.json` configuration. After that, you can select `No` when asked to deploy another contract. -To start the Flow emulator, run (you may need to approve a prompt to allow connection the first time): +To start the Flow emulator, run: ```bash flow emulator start ``` +:::info + +you may need to approve a prompt to allow connection the first time + +::: + In a separate terminal or command prompt, deploy the contract: ```bash @@ -670,10 +606,9 @@ flow project deploy You'll then see a message that says `All contracts deployed successfully`. -## Creating an NFTCollection +## Create an NFTCollection -To manage multiple NFTs, you'll need an NFT collection. -Start by creating a transaction file for this purpose (we can use the `generate` command again): +To manage multiple NFTs, you'll need an NFT collection. To start, create a transaction file for this purpose (we can use the `generate` command again): ```bash flow generate transaction setup_foobar_collection @@ -681,15 +616,9 @@ flow generate transaction setup_foobar_collection This creates a transaction file at `cadence/transactions/setup_foobar_collection.cdc`. -Transactions, on the other hand, are pieces of Cadence code -that can mutate the state of the blockchain. -Transactions need to be signed by one or more accounts, -and they can have multiple phases, represented by different blocks of code. +Transactions, on the other hand, are pieces of Cadence code that can mutate the state of the blockchain. Transactions need to be signed by one or more accounts, and they can have multiple phases, represented by different blocks of code. -In this file, import the necessary contracts and define a transaction -to create a new collection, storing it in the account's storage. -Additionally, the transaction creates a capability that allows others -to get a public reference to the collection to read from its methods. +In this file, import the necessary contracts and define a transaction to create a new collection, and store it in the account's storage. Additionally, the transaction creates a capability that allows others to get a public reference to the collection to read from its methods. This capability ensures secure, restricted access to specific functionalities or information within a resource. @@ -718,9 +647,7 @@ transaction { } ``` -There are also examples of [generic transactions](https://github.com/onflow/flow-nft/blob/master/transactions/setup_account_from_address.cdc) -that you can use to setup an account for ANY non-fungible token using metadata views! -You should check those out and try to use generic transactions whenever it is possible. +There are also examples of [generic transactions] that you can use to setup an account for ANY non-fungible token using metadata views! You should check those out and try to use generic transactions whenever it is possible. To store this new NFT collection, create a new account: @@ -738,12 +665,9 @@ Congratulations! You've successfully created an NFT collection for the `test-acc ## Get an Account's NFTs -To retrieve the NFTs associated with an account, you'll need a script. -Scripts are read-only operations that allow you to query the blockchain. -They don't modify the blockchain's state, and therefore, -they don't require gas fees or signatures (read more about scripts here). +To retrieve the NFTs associated with an account, you'll need a script. Scripts are read-only operations that allow you to query the blockchain. They don't modify the blockchain's state, and therefore, they don't require compute unit fees or signatures. -Start by creating a script file using the `generate` command again: +To start, create a script file with the `generate` command again: ```bash flow generate script get_foobar_ids @@ -776,7 +700,7 @@ flow scripts execute cadence/scripts/get_foobar_ids.cdc 0x123 Since you haven't added any NFTs to the collection yet, the result will be an empty array. -## Minting and Depositing an NFT to a Collection +## Mint and Deposit an NFT to a Collection To mint and deposit an NFT into a collection, create a new transaction file: @@ -784,10 +708,7 @@ To mint and deposit an NFT into a collection, create a new transaction file: flow generate transaction mint_foobar_nft ``` -In this file, define a transaction that takes a recipient's address as an argument. -This transaction will borrow the minting capability from the contract account, -borrow the recipient's collection capability, create a new NFT using the minter, -and deposit it into the recipient's collection: +In this file, define a transaction that takes a recipient's address as an argument. This transaction will borrow the minting capability from the contract account, borrow the recipient's collection capability, create a new NFT with the minter, and deposit it into the recipient's collection: ```cadence import "NonFungibleToken" @@ -827,36 +748,35 @@ transaction( } ``` -To run this transaction, use the Flow CLI. Remember, the contract account -(which has the minting resource) should be the one signing the transaction. -Pass the test account's address (from the `flow.json` file) as the recipient argument -(note: replace `0x123` with the address for `test-acct` from `flow.json`): +To run this transaction, use the Flow CLI. Remember, the contract account (which has the minting resource) should be the one that signs the transaction. Pass the test account's address (from the `flow.json` file) as the recipient argument: + +:info + +replace `0x123` with the address for `test-acct` from `flow.json`) + +::: ```bash flow transactions send cadence/transactions/mint_foobar_nft.cdc 0x123 --signer emulator-account --network emulator ``` -After executing the transaction, you can run the earlier script to verify -that the NFT was added to the `test-acct`'s collection (remember to replace `0x123`): +After you execute the transaction, run the earlier script to verify that the NFT was added to the `test-acct`'s collection (remember to replace `0x123`): ```bash flow scripts execute cadence/scripts/get_foobar_ids.cdc 0x123 ``` -You should now see a value in the `test-acct`'s collection array! +You will now see a value in the `test-acct`'s collection array! -## Transferring an NFT to Another Account +## Transfer an NFT to Another Account -To transfer an NFT to another account, create a new transaction file using `generate`: +To transfer an NFT to another account, create a new transaction file with `generate`: ```bash flow generate transaction transfer_foobar_nft ``` -In this file, define a transaction that takes a recipient's address and the ID -of the NFT you want to transfer as arguments. -This transaction will borrow the sender's collection, get the recipient's capability, -withdraw the NFT from the sender's collection, and deposit it into the recipient's collection: +In this file, define a transaction that takes a recipient's address and the ID of the NFT you want to transfer as arguments. This transaction will borrow the sender's collection, get the recipient's capability, withdraw the NFT from the sender's collection, and deposit it into the recipient's collection: ```cadence import "FooBar" @@ -910,9 +830,7 @@ Name it `test-acct-2` and select `Emulator` as the network. Next, create a colle flow transactions send cadence/transactions/setup_foobar_collection.cdc --signer test-acct-2 --network emulator ``` -Now, run the transaction to transfer the NFT from `test-acct` to `test-acct-2` -using the addresses from the `flow.json` file (replace `0x124` with `test-acct-2`'s address. -Also note that `0` is the `id` of the `NFT` we'll be transferring): +Now, run the transaction to transfer the NFT from `test-acct` to `test-acct-2` with the addresses from the `flow.json` file (replace `0x124` with `test-acct-2`'s address. Also note that `0` is the `id` of the `NFT` we'll be transferring): ```bash flow transactions send cadence/transactions/transfer_foobar_nft.cdc 0x124 0 --signer test-acct --network emulator @@ -924,17 +842,46 @@ To verify the transfer, you can run the earlier script for `test-acct-2` (replac flow scripts execute cadence/scripts/get_foobar_ids.cdc 0x123 ``` -The transfer transaction also has a [generic version](https://github.com/onflow/flow-nft/blob/master/transactions/generic_transfer_with_address.cdc) -that developers are encouraged to use! +The transfer transaction also has a [generic version] that developers are encouraged to use! Congrats, you did it! You're now ready to launch the next fun NFT project on Flow. ## More -- Explore [an example NFT repository](https://github.com/nvdtf/flow-nft-scaffold/blob/main/cadence/contracts/exampleNFT/ExampleNFT.cdc) -- Dive into the details of [the NFT Standard](https://github.com/onflow/flow-nft) -- Check out the [`Burner` contract](../core-contracts/14-burner.md), which is the standard -that all projects should use for handling the destruction of any resource. -- For a deeper dive into `MetadataViews`, consult the [introduction guide](../advanced-concepts/metadata-views.md) or [the FLIP that introduced this feature](https://github.com/onflow/flips/blob/main/application/20210916-nft-metadata.md). -- Learn about how you can [bridge your NFTs to Flow-EVM](../../tutorials/cross-vm-apps/vm-bridge.md#cross-vm-bridge) and how you can build your NFT project [to be compatible with the Flow VM bridge](../../tutorials/cross-vm-apps/vm-bridge.md#prep-your-assets-for-bridging). -- Use a [no code tool for creating NFT projects on Flow](https://www.touchstone.city/) +- Explore an [example NFT repository] +- Dive into the details of the [NFT Standard] +- Check out the [`Burner` contract], which is the standard + that all projects should use for handling the destruction of any resource. +- For a deeper dive into `MetadataViews`, consult the [introduction guide] or [the FLIP that introduced this feature]. +- Learn about how you can [bridge your NFTs to Flow-EVM]and how you can [build your FT project] to be compatible with the Flow VM bridge. +- Use a no code tool to create NFT projects on Flow with [Touchstone]. + + + +[a link to the completed code]: https://github.com/onflow/foobar-nft +[bridge your NFTs to Flow-EVM]: ../cross-vm-apps/vm-bridge.md#cross-vm-bridge +[`Burner` contract]: ../../build/cadence/core-contracts/14-burner.md +[build your NFT project]: ../cross-vm-apps/vm-bridge.md#prep-your-assets-for-bridging +[in the Cadence docs]: https://cadence-lang.org/docs/language/resources#destroy-events +[`Collection` interface]: https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc#L202 +[Collection]: https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc#L190 +[Cross-VM Bridge]: https://www.github.com/onflow/flow-evm-bridge +[Entitlements]: https://cadence-lang.org/docs/language/access-control#entitlements +[example NFT repository]: https://github.com/nvdtf/flow-nft-scaffold/blob/main/cadence/contracts/exampleNFT/ExampleNFT.cdc +[Flow CLI installation guide]: ../../build/tools/flow-cli/install.md +[generic version]: https://github.com/onflow/flow-nft/blob/master/transactions/generic_transfer_with_address.cdc +[generic transactions]:https://github.com/onflow/flow-nft/blob/master/transactions/setup_account_from_address.cdc +[Homebrew]: https://brew.sh/ +[introduction guide]: ../../build/cadence/advanced-concepts/metadata-views.md +[metadata views documentation]: ../../build/cadence/advanced-concepts/metadata-views.md +[MetadataViews]: https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc +[NFT Standard]: https://github.com/onflow/flow-nft +[References]: https://cadence-lang.org/docs/language/references +[Resources]: https://cadence-lang.org/docs/language/resources +[NFT]: https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc#L98) +[standard entitlement]: https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc#L58 +[standard `NonFungibleToken.Updated` event]: https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc#L63-L77 +[the FLIP that introduced this feature]: https://github.com/onflow/flips/blob/main/application/20210916-nft-metadata.md. +[Touchstone]: https://www.touchstone.city/ +[ViewResolver]: https://github.com/onflow/flow-nft/blob/master/contracts/ViewResolver.cdc + diff --git a/docs/tutorials/token-launch/register-cadence-assets.md b/docs/blockchain-development-tutorials/tokens/register-cadence-assets.md similarity index 82% rename from docs/tutorials/token-launch/register-cadence-assets.md rename to docs/blockchain-development-tutorials/tokens/register-cadence-assets.md index 2f563831e1..d7a43dd6a8 100644 --- a/docs/tutorials/token-launch/register-cadence-assets.md +++ b/docs/blockchain-development-tutorials/tokens/register-cadence-assets.md @@ -2,7 +2,7 @@ title: Register Your Assets on Flow description: 'Register your Fungible Token or Non-Fungible Token on Flow so it appears in Flow Wallet, IncrementFi, and other ecosystem apps.' sidebar_label: Register Cadence Assets -sidebar_position: 2 +sidebar_position: 3 keywords: - Fungible Token - Non-Fungible Token @@ -23,7 +23,7 @@ There are two ways to register your token: **manually** via a web interface or * --- -## Manual Registration (~1 min) +## Manual registration (~1 min) The following works for both fungible and non-fungible tokens on Flow Cadence or Flow EVM. @@ -40,26 +40,26 @@ The following works for both fungible and non-fungible tokens on Flow Cadence or ERC-20 tokens registered with this method will use the default logo of Flow Official Assets. -If you want to register your ERC-20 token on Flow EVM with your customized logo, you should follow the [Register ERC-20 Token on Flow EVM] guide. +If you want to register your ERC-20 token on Flow EVM with your customized logo, follow the [Register ERC-20 Token on Flow EVM] guide. ::: --- -## Programmatic Registration +## Programmatic registration For seamless automation, you can integrate token registration into your token deployment workflow. -You can use the following Cadence transaction to register your Fungible or Non-Fungible token on Flow Cadence or Flow EVM. +You can use this Cadence transaction to register your Fungible or Non-Fungible token on Flow Cadence or Flow EVM. ### Register Fungible Token or Non-Fungible Token automatically on Flow Cadence Use a standalone Cadence transaction to register your Fungible Token or Non-Fungible Token on Flow Cadence. - Use this **Cadence transaction**: [register-standard-asset.cdc]. -- This transaction should be executed **right after deploying your Fungible Token or Non-Fungible Token contract**. +- Execute this transaction **right after you deploy your Fungible Token or Non-Fungible Token contract**. -Or you can also pick up some code from the [register-standard-asset.cdc] file to make your own Cadence transaction with the same logic for more seamless integration. Here is an example: +Or, you can also pick up some code from the [register-standard-asset.cdc] file to make your own Cadence transaction with the same logic for more seamless integration. Here is an example: ```cadence import "TokenList" @@ -79,10 +79,10 @@ transaction( } ``` -### Register ERC-20 or ERC-721 Tokens automatically on Flow EVM +### Register ERC-20 or ERC-721 tokens automatically on Flow EVM - Use this **Cadence transaction**: [register-evm-asset.cdc] -- This transaction should be executed **right after deploying your ERC-20 or ERC-721 contract**. +- Execute this transaction **right after you deploy your ERC-20 or ERC-721 contract**. :::warning @@ -101,6 +101,8 @@ Similar to manual registration: For any issues, refer to the [Token List GitHub Repository] or reach out to the [Flow developer community]. + + [Token List Registration]: https://token-list.fixes.world/ [Register ERC-20 Token on Flow EVM]: ./register-erc20-token.md [register-standard-asset.cdc]: https://github.com/fixes-world/token-list/blob/main/cadence/transactions/register-standard-asset.cdc diff --git a/docs/tutorials/token-launch/register-erc20-token.md b/docs/blockchain-development-tutorials/tokens/register-erc20-token.md similarity index 55% rename from docs/tutorials/token-launch/register-erc20-token.md rename to docs/blockchain-development-tutorials/tokens/register-erc20-token.md index 87986e7009..5a84f3fb83 100644 --- a/docs/tutorials/token-launch/register-erc20-token.md +++ b/docs/blockchain-development-tutorials/tokens/register-erc20-token.md @@ -2,7 +2,7 @@ title: Register Your ERC20 Token on Flow EVM description: 'Register your ERC20 token on Flow EVM so it appears in Flow Wallet, MetaMask, and other ecosystem apps.' sidebar_label: Register ERC20 Token -sidebar_position: 1 +sidebar_position: 4 keywords: - ERC20 - Fungible Token @@ -16,55 +16,71 @@ keywords: # Register Your ERC20 Token on Flow EVM +
+ +
+ ## Overview -This section covers the process of registering your ERC20 token on Flow EVM via a Github Pull Request process so it appears in Flow standard Token List which is used by Flow Wallet, MetaMask, and other ecosystem apps. +This section covers how to register your ERC20 token on Flow EVM via a Github Pull Request process so it appears in Flow standard Token List, which Flow Wallet, MetaMask, and other ecosystem apps use. + +We will use the [Flow Official Assets] repository as the standard token list repository to update the token list for the whole Flow ecosystem. The repository is open to the public and you can submit your PRs to add your token to the list. + +:::info -We will use the [Flow Official Assets] repository as the standard token list repository for updating the token list for the whole Flow ecosystem. The repository is open to the public and you can submit your PRs to add your token to the list. +The logic of the registration is based on the [Register Assets in Cadence] backend process. -Note: The logic of the registration is based on the [Register Assets in Cadence] backend process. +::: -## Guides for submitting your PRs +## Guides for how to submit your PRs Steps to submit your PRs: 1. **Fork the [Flow Official Assets] repository** - - Click the `Fork` button in the top right corner of the repository. + - Click `Fork` in the top right corner of the repository. - Create a new fork of the repository in your own Github account. 2. **Create a new branch** - Clone your forked repository to your local development environment by `git clone https://github.com/your-github-username/assets` - Create a new branch for your token by `git checkout -b new-token-branch` -3. **Add/Update your token to the list** +3. **Add or update your token to the list** - For new Tokens: - Create the token folders in the `tokens/registry` directory. - The name of the token folders must be the same as the token's contract address. - - e.g. `tokens/registry/0x1234567890123456789012345678901234567890` + - For example, `tokens/registry/0x1234567890123456789012345678901234567890` - for Testnet tokens, the folder should be `tokens/registry/testnet:0x1234567890123456789012345678901234567890` - - Put the required metadata file in the token folder, at least one of the following files should be included: + - Put the required metadata file in the token folder, include at least one of the following files: - `logo.png`: PNG format token logo (256x256px recommended) - `logo.svg`: SVG format token logo, optimized and viewboxed - You can also add extra optional metadata file: - `mods.json`: Mods JSON file for token metadata, you can adjust the `symbol`, `name`, `description` for the final output in the `token.json` file. - - For existing Tokens: + - For current Tokens: - Identify the token folder in the `tokens/registry` directory by the token's contract address. - Update the token metadata in the `tokens/registry/${token_address}` directory. 4. **Submit a Pull Request** - Commit your changes and push to your forked repository. - - Create a new Pull Request for your changes in the [Flow Official Assets] repository. - - A Github Action will be triggered to verify the on-chain status of the token and update the report in the PR's comment. - - If there is any issue, you will see some warnings and suggestions in the PR's comment. Please check the report and update the token metadata if needed. + - Create a new Pull Request (PR) for your changes in the [Flow Official Assets] repository. + - A Github Action will be triggered to verify the onchain status of the token and update the report in the PR's comment. + - If there is any issue, you will see some warnings and suggestions in the PR's comment. Check the report and update the token metadata if needed. - You may see a comment from the Github Action that you need to send 1 $FLOW to the registry address for the token registration because there is a VM Bridge onboarding fee. Learn more about the registration process in the [Assets Registry] README.md file of the repository. ## What's next? -After submitting your PR, you just need to wait for the Flow team to review your token and merge your PR. -Once the PR is merged, your token will be registered by the Github Actions in the [Flow Official Assets] repository automatically and a new PR will be created automatically by Github Actions to update the token list. The Flow team will regularly merge the token list updates PR to the main branch. +After you submit your PR, you just need to wait for the Flow team to review your token and merge your PR. -## How to verify the token is registered? +After the PR is merged, your token will be registered by the Github Actions in the [Flow Official Assets] repository automatically and Github Actions automatically creates a new PR to update the token list. The Flow team will regularly merge the token list updates PR to the main branch. -As the registration and token list generation is executed by Github Actions, you can check the status of the PRs and the token list JSON files in the [Flow Official Assets] repository. +## How to verify the token is registered + +As Github Actions executes the registration and token list generation, you can check the status of the PRs and the token list JSON files in the [Flow Official Assets] repository. Here are the URLs for the token list JSON files: - Mainnet: `https://raw.githubusercontent.com/onflow/assets/refs/heads/main/tokens/outputs/mainnet/token-list.json` @@ -72,6 +88,8 @@ Here are the URLs for the token list JSON files: You can check the token list JSON files to verify the token is registered in the `token-list.json` file. + + [Flow Official Assets]: https://github.com/onflow/assets [Register Assets in Cadence]: ./register-cadence-assets.md [Assets Registry]: https://github.com/onflow/assets/tree/main/tokens diff --git a/docs/tutorials/use-AI-to-build-on-flow/agentkit-flow-guide.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/agentkit-flow-guide.md similarity index 67% rename from docs/tutorials/use-AI-to-build-on-flow/agentkit-flow-guide.md rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/agentkit-flow-guide.md index c533e056a2..ece4396abd 100644 --- a/docs/tutorials/use-AI-to-build-on-flow/agentkit-flow-guide.md +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/agentkit-flow-guide.md @@ -2,18 +2,18 @@ title: Build Custom AI Agents on Flow with AgentKit description: Learn how to configure and deploy AI agents on the Flow testnet using AgentKit, Langchain, and the EVM-compatible Flow environment. sidebar_label: Using AgentKit on Flow -sidebar_position: 4 +sidebar_position: 2 --- -# Getting Started with AgentKit on Flow +# Build Custom AI Agents on Flow with AgentKit AgentKit is an ecosystem-agnostic modular developer toolkit that lets you rapidly build, deploy, and iterate on AI agents using pre-configured environments and ready-to-use templates. -In this guide, you'll set up your own custom agent running on **Flow's EVM-compatible testnet**, powered by **Langchain** and **Anthropic's Claude** LLM. +In this guide, you'll set up your own custom agent that runs on **Flow's EVM-compatible testnet**, powered by **Langchain** and **Anthropic's Claude** LLM. --- -## Quickstart - Starting From Scratch +## Quickstart - start from scratch Open your terminal and run: @@ -36,42 +36,42 @@ Follow the interactive setup: --- -## Project Setup +## Project setup -Once your scaffold is ready: +When your scaffold is ready: ```bash cd onchain-agent npm install ``` -Now open the project in your preferred IDE (e.g. Cursor). +Now open the project in your preferred integrated development environment (IDE) (for example, [Cursor]. ### Environment Configuration -1. Create a `.env.local` file (or edit the one generated). +1. Create a `.env.local` file (or edit the one that you generated). 2. Add your API keys (we'll use **Anthropic** here). > You can also use OpenAI, DeepSeek, or any other supported LLM. ### Get Your Anthropic API Key -- Head to [Anthropic Console](https://console.anthropic.com/dashboard) -- Create an account and **purchase credits** -- Click **Create Key**, name it, and copy the API key +- Head to [Anthropic Console]. +- Create an account and **purchase credits**. +- Click **Create Key**, name it, and copy the API key. - Add this to your `.env.local`: ```env ANTHROPIC_API_KEY=your_api_key_here ``` -### Wallet Setup with MetaMask +### Wallet setup with MetaMask -1. Add [Flow Testnet](https://developers.flow.com/evm/using) to MetaMask -2. Use the [Faucet](https://faucet.flow.com/fund-account) to fund your wallet +1. Add [Flow Testnet] to MetaMask. +2. Use the [Faucet] to fund your wallet. 3. Get your private key: - - Click the `...` menu in MetaMask > **Account Details** - - Enter your password, copy the private key + - Click the `...` menu in MetaMask > **Account Details**. + - Enter your password, copy the private key. 4. Add it to `.env.local`: ```env @@ -102,13 +102,13 @@ http://localhost:3000 ## Configure Your LLM -If your agent doesn't respond yet — no worries! You still need to configure your **LLM and client libraries**. +If your agent doesn't respond yet, no worries! You still need to configure your **LLM and client libraries**. -### Choose a Model +### Choose a model -Langchain supports many LLMs ([full list here](https://python.langchain.com/docs/integrations/llms/)). +Langchain supports many LLMs ([full list here]). -For this example, we'll use **Anthropic's `claude-3-5-haiku-20241022`**, a lightweight and affordable model. Alternatively, [DeepSeek](https://deepseek.com/) is highly recommended for budget-friendly usage. +For this example, we'll use **Anthropic's `claude-3-5-haiku-20241022`**, a lightweight and affordable model. Alternatively, [DeepSeek] is highly recommended for budget-friendly usage. ### Update `create-agent.ts` @@ -134,9 +134,9 @@ npm install @langchain/anthropic --- -## Configure Flow and Viem Wallet +## Configure Flow and Viem wallet -### Update the Faucet Provider Logic +### Update the Faucet provider logic Change this: @@ -150,7 +150,7 @@ To: const canUseFaucet = walletProvider.getNetwork().networkId == 'flow-testnet'; ``` -### Add Flow Context Message to Agent +### Add Flow context message to Agent This gives your agent context about the Flow testnet: @@ -196,11 +196,11 @@ agent = createReactAgent({ --- -## You're Done! +## You're done! -You now have a working AI agent connected to Flow testnet using AgentKit! +You now have a working AI agent connected to Flow testnet with AgentKit! -You can send faucet tokens to your wallet and start testing smart contract interactions or on-chain workflows. +You can send faucet tokens to your wallet and start to test smart contract interactions or onchain workflows. --- @@ -210,15 +210,15 @@ Want to skip the setup? > [Fork the Flow AgentKit Starter](https://github.com/Aliserag/flow-agentkit-starter) -This starter includes all necessary config to start building immediately on Flow. +This starter includes all of the necessary configurations to start building immediately on Flow. --- -## Adding AgentKit to an Existing Project +## Add AgentKit to a current project -Already have a project and want to add AgentKit? Follow these steps to integrate it into your existing codebase: +Already have a project and want to add AgentKit? Follow these steps to integrate it into your codebase: -### Install the Package +### Install the package Run this command in your project's root directory: @@ -228,11 +228,11 @@ npm install onchain-agent@latest This will: -- Download and install the latest version of the `onchain-agent` package -- Add it to the dependencies section of your `package.json` -- Update your `node_modules` folder accordingly +- Download and install the latest version of the `onchain-agent` package. +- Add it to the dependencies section of your `package.json`. +- Update your `node_modules` folder accordingly. -### Configure Environment +### Configure environment 1. Create or update your `.env` file with the necessary API keys: @@ -249,7 +249,7 @@ FLOW_TESTNET_RPC_URL=https://testnet.evm.nodes.onflow.org FLOW_MAINNET_RPC_URL=https://mainnet.evm.nodes.onflow.org ``` -### Integrate AgentKit in Your Code +### Integrate AgentKit in your code Import and configure AgentKit in your application: @@ -284,7 +284,7 @@ const agent = createReactAgent({ // ... ``` -### Add Specialized Tools (Optional) +### Add Specialized tools (optional) To add specialized blockchain tools to your agent: @@ -314,11 +314,25 @@ const agent = createReactAgent({ ## Resources -- [AgentKit Docs](https://docs.cdp.coinbase.com/agent-kit/welcome) -- [Flow EVM Guide](https://developers.flow.com/evm/using) -- [Langchain LLM Integrations](https://python.langchain.com/docs/integrations/llms/) -- [Anthropic Model Comparison](https://docs.anthropic.com/en/docs/about-claude/models/all-models#model-comparison-table) +- [AgentKit Docs] +- [Flow EVM Guide] +- [Langchain LLM Integrations] +- [Anthropic Model Comparison] --- Happy hacking on Flow! + + + +[Cursor]: ../cursor/index.md +[Anthropic Console]: https://console.anthropic.com/dashboard +[Flow Testnet]: https://developers.flow.com/evm/using +[Faucet]: https://faucet.flow.com/fund-account +[full list here]: https://python.langchain.com/docs/integrations/llms/ +[DeepSeek]: https://deepseek.com/ +[Fork the Flow AgentKit Starter]: https://github.com/Aliserag/flow-agentkit-starter +[AgentKit Docs]: https://docs.cdp.coinbase.com/agent-kit/welcome +[Flow EVM Guide]: https://developers.flow.com/evm/using +[Langchain LLM Integrations]: https://python.langchain.com/docs/integrations/llms/ +[Anthropic Model Comparison]: https://docs.anthropic.com/en/docs/about-claude/models/all-models#model-comparison-table \ No newline at end of file diff --git a/docs/tutorials/use-AI-to-build-on-flow/eliza/build-plugin.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/eliza/build-plugin.md similarity index 57% rename from docs/tutorials/use-AI-to-build-on-flow/eliza/build-plugin.md rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/eliza/build-plugin.md index 1e9ec79b32..275da75aa2 100644 --- a/docs/tutorials/use-AI-to-build-on-flow/eliza/build-plugin.md +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/eliza/build-plugin.md @@ -1,7 +1,7 @@ --- title: Eliza Plugin Guide description: Learn how to build Eliza plugins for your AI Agent on Flow -sidebar_position: 2 +sidebar_position: 1 keywords: - AI - AI Agent @@ -14,46 +14,52 @@ keywords: # Eliza Plugin Development Guide -Plugins are a powerful way to extend the functionality of your Eliza AI agents. This guide will walk you through the process of creating custom plugins that can enhance your agent's capabilities, from simple utilities to complex integrations with external services. You'll learn how to leverage the plugin system to create modular and reusable components for your AI agents. +## Overview -## Learning Objectives +Plugins are a powerful way to extend the functionality of your Eliza AI agents. This guide will walk you through the process of how to create custom plugins that can enhance your agent's capabilities, from simple utilities to complex integrations with external services. You'll learn how to leverage the plugin system to create modular and reusable components for your AI agents. -By the end of this tutorial, you will be able to: +## Learning objectives -- Create a new plugin repository from the template -- Understand the plugin development workflow -- Implement custom actions and services -- Integrate plugins with your Eliza agent -- Register and publish plugins to the Eliza Plugin Registry -- Use dependency injection for better plugin architecture +After you complete this tutorial, you will be able to: + +- Create a new plugin repository from the template. +- Understand the plugin development workflow. +- Implement custom actions and services. +- Integrate plugins with your Eliza agent. +- Register and publish plugins to the Eliza Plugin Registry. +- Use dependency injection for better plugin architecture. ## Prerequisites -Before getting started with Eliza, ensure you have: +Before you get started with Eliza, make sure you have: -- [Node.js 23+] (using [nvm] is recommended) +- [Node.js 23+] (we recommend that you use [nvm]) - [pnpm 9+] - Git for version control -- A code editor ([VS Code], [Cursor] or [VSCodium] recommended) +- A code editor (we recommend [VS Code], [Cursor] or [VSCodium]) - [Flow-cli] for Flow blockchain interaction. -> **Note for Windows Users:** [WSL 2] is required. +> **Note for Windows users:** [WSL 2] is required. ## Quickstart -Please follow the [Quickstart Guide] to set up your development environment. +Follow the [Quickstart Guide] to set up your development environment. + +## Plugin development -## Plugin Development +### Create a plugin repository from Template -### Create a Plugin repository from Template +Visit [Eliza Plugin Template] and click "Use this template" to create a new repository. -Visit [Eliza Plugin Template] and click on the "Use this template" button to create a new repository. +Or, you can create a new empty repository and copy the files from some examples at the [Eliza Plugins] organization. -Or you can create a new empty repository and copy the files from some examples at [Eliza Plugins] organization. +:::note -> Note: Flow's Eliza plugin template is using Dependency Injection(`@elizaos-plugins/plugin-di`), you can learn more about the Dependency Injection in the [plugin's README.md]. It allows you can use `Class` instead of `Object` for your `Actions`, `Providers`, `Services`, and etc. **If you don't want to use it, you can follow the other examples in Eliza Plugins organiazation.** +Flow's Eliza plugin template uses Dependency Injection(`@elizaos-plugins/plugin-di`). You can learn more about the Dependency Injection in the [plugin's README.md]. It allows you can use `Class` instead of `Object` for your `Actions`, `Providers`, `Services`, and so on. **If you don't want to use it, you can follow the other examples in Eliza Plugins organiazation.** + +::: -### Add the Plugin repository to your Eliza project +### Add the plugin repository to your Eliza project Let's say you created a repository named `username/plugin-foo`. @@ -77,7 +83,7 @@ Add the plugin to agent's `package.json` pnpm add @elizaos-plugins/plugin-foo@'workspace:*' --filter ./agent ``` -Check the `agent/package.json` to ensure the plugin is added, you should see something like this: +Check the `agent/package.json` to make sure the plugin is added. You'll see something like this: ```json { @@ -87,9 +93,9 @@ Check the `agent/package.json` to ensure the plugin is added, you should see som } ``` -### Build the Plugin +### Build the plugin -Build the plugin using the following command: +Build the plugin with the following command: ```bash pnpm build --filter ./packages/plugin-foo @@ -98,9 +104,9 @@ pnpm build --filter ./packages/plugin-foo pnpm build ``` -### Add Plugin to the `character.json` you want to use +### Add the plugin to the `character.json` you want to use -Let's say you want to add the plugin to the `sample` character which is `characters/sample.character.json`. +Let's say you want to add the plugin to the `sample` character, which is `characters/sample.character.json`. ```json { @@ -113,7 +119,7 @@ Let's say you want to add the plugin to the `sample` character which is `charact :::warning -If you are using Dependency Injection(`@elizaos-plugins/plugin-di`) in your plugin, remember to add it to the `postProcessors` field. And **`clients` field is deprecated** in the latest version of Eliza, so if you want to add clients you also need to use `plugins` field. +If you use Dependency Injection(`@elizaos-plugins/plugin-di`) in your plugin, remember to add it to the `postProcessors` field. The **`clients` field is deprecated** in the latest version of Eliza, so if you want to add clients, you also need to use `plugins` field. ::: @@ -130,7 +136,7 @@ If you are using Dependency Injection(`@elizaos-plugins/plugin-di`) in your plug } ``` -### Run the Eliza Agent with your Plugin +### Run the Eliza agent with your plugin Run the Eliza agent to test the plugin. @@ -141,7 +147,7 @@ pnpm start --character="characters/sample.character.json" pnpm start:debug --character="characters/sample.character.json" ``` -### Interact with the Agent +### Interact with the agent Now, you're ready to start a conversation with your agent. @@ -151,11 +157,11 @@ Open a new terminal window and run the client's http server. pnpm start:client ``` -## Plugin Registration +## Plugin registration You need to register your plugin in the [Eliza Plugin Registry] to make it available for other users. -Please follow the guide there, modify the [index.json] and submit a PR to the registry repository. +Follow the guide there, modify the [index.json] file, and submit a pull request (PR) to the registry repository. ## Conclusion diff --git a/docs/tutorials/use-AI-to-build-on-flow/eliza/index.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/eliza/index.md similarity index 50% rename from docs/tutorials/use-AI-to-build-on-flow/eliza/index.md rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/eliza/index.md index f8c7f70f9b..a49e5b1b3c 100644 --- a/docs/tutorials/use-AI-to-build-on-flow/eliza/index.md +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/eliza/index.md @@ -1,9 +1,9 @@ --- title: Eliza on Flow description: Learn how to build AI Agent on Flow with Eliza -sidebar_position: 4 +sidebar_position: 1 keywords: - - AI + - AI - AI Agent - Eliza - Eliza on Flow @@ -13,30 +13,30 @@ keywords: # Quickstart Guide to build AI Agent on Flow with Eliza -Eliza is a powerful framework for building AI agents that can interact with users through natural language. This tutorial will guide you through setting up and deploying an AI agent on the Flow blockchain using Eliza. You'll learn how to create intelligent agents that can understand and respond to user queries, while leveraging Flow's secure and scalable infrastructure. +Eliza is a powerful framework you can use to build AI agents that interact with users through natural language. This tutorial will guide you through how to set up and deploy an AI agent on the Flow blockchain with Eliza. You'll learn how to create intelligent agents that can understand and respond to user queries, and leverage Flow's secure and scalable infrastructure. -## Learning Objectives +## Learning objectives -By the end of this tutorial, you will be able to: +After you complete this tutorial, you will be able to: -- Set up the Eliza development environment -- Configure and deploy an AI agent on Flow -- Create and customize character configurations -- Integrate different AI models with your agent -- Interact with your AI agent through a web interface -- Add and develop custom plugins for extended functionality +- Set up the Eliza development environment. +- Configure and deploy an AI agent on Flow. +- Create and customize character configurations. +- Integrate different AI models with your agent. +- Interact with your AI agent through a web interface. +- Add and develop custom plugins for extended functionality. ## Prerequisites -Before getting started with Eliza, ensure you have: +Before you get started started with Eliza, make sure you have: -- [Node.js 23+] (using [nvm] is recommended) +- [Node.js 23+] (we recommend that you use [nvm]) - [pnpm 9+] - Git for version control -- A code editor ([VS Code], [Cursor] or [VSCodium] recommended) +- A code editor (we recommend [VS Code], [Cursor] or [VSCodium]) - [Flow-cli] for Flow blockchain interaction. -> **Note for Windows Users:** [WSL 2] is required. +> **Note for Windows Uuers:** [WSL 2] is required. ## Installation @@ -58,7 +58,7 @@ cd elizaOnFlow git checkout main ``` -Or, If you want to use the origin Eliza, please run: +Or, If you want to use the origin Eliza, run: ```bash # Eliza's characters folder is a submodule @@ -71,7 +71,7 @@ cd eliza git checkout $(git describe --tags --abbrev=0) ``` -If you already cloned without submodules, please run: +If you already cloned without submodules, run: ```bash # Fetch submodules @@ -86,11 +86,11 @@ pnpm install --no-frozen-lockfile :::warning -Please only use the `--no-frozen-lockfile` option when you're initially instantiating the repo or are bumping the version of a package or adding a new package to your package.json. This practice helps maintain consistency in your project's dependencies and prevents unintended changes to the lockfile. +Only use the `--no-frozen-lockfile` option when you initially instantiate the repo or bump the version of a package or add a new package to your `package.json` file. This practice helps maintain consistency in your project's dependencies and prevents unintended changes to the lockfile. ::: -If you are using ElizaOnFlow, you need to install Flow Cadence contracts dependencies to ensure `*.cdc` be correctly linted by Cadence extension. +If you use ElizaOnFlow, you need to install Flow Cadence contracts dependencies to ensure that the Cadence extension correctly lints `*.cdc`. Install Flow Cadence contracts dependencies: @@ -104,43 +104,41 @@ Build all packages: pnpm build ``` -## Configure Environment +## Configure environment -Copy .env.example to .env and fill in the appropriate values. +Copy `.env.example` to `.env` and fill in the appropriate values. ```bash cp .env.example .env ``` - :::danger -In normal development, it's a best practice to use a `.env` to protect API keys and other sensitive information. When working with crypto, it's **critical** to be disciplined and always use them, even in test projects or tutorials. If you expose a wallet key, you might lose everything in that wallet immediately, or someone might watch it for years and rug you the day you put something valuable there. +In normal development, it's a best practice to use a `.env` to protect API keys and other sensitive information. When you work with crypto, it's **critical** to always use them, even in test projects or tutorials. If you expose a wallet key, you might lose everything in that wallet immediately, or someone might watch it for years and rob you the day you put something valuable there. ::: +Edit `.env` and add your values. Do **NOT** add this file to version control. -Edit `.env` and add your values. Do NOT add this file to version control. - -### Choose Your Model +### Choose Your model Eliza supports multiple AI models and you set which model to use inside the character JSON file. -But remember, once you chosed a model, you need to set up the relevant configuration. +But remember, after you choose a model, you need to set up the relevant configuration. -Check full list of supported LLMs in origin Eliza: [Models.ts] +Check the full list of supported LLMs in origin Eliza: [Models.ts] Suggested models: -- Use API to access LLM providers - - OpenAI: set modelProvider as `openai`, and set `OPENAI_API_KEY` in `.env` - - Deepseek: set modelProvider as `deepseek`, and set `DEEPSEEK_API_KEY` in `.env` - - Grok: set modelProvider as `grok`, and set `GROK_API_KEY` in `.env` +- Use API to access LLM providers: + - OpenAI: set modelProvider as `openai`, and set `OPENAI_API_KEY` in `.env`. + - Deepseek: set modelProvider as `deepseek`, and set `DEEPSEEK_API_KEY` in `.env`. + - Grok: set modelProvider as `grok`, and set `GROK_API_KEY` in `.env`. - Use local inference - - Ollama: set modelProvider as `ollama`, and set `OLLAMA_MODEL` in `.env` to the model name you are using in ollama. + - Ollama: set modelProvider as `ollama`, and set `OLLAMA_MODEL` in `.env` to the model name you use in ollama. -> To choose model, you need to set in charactor configuration. For example: OPENAI, please set `modelProvider: "openai"` in charactor JSON file or `modelProvider: ModelProviderName.OPENAI` in `charactor.ts` +> To choose a model, you need to set in charactor configuration. For example: OPENAI, set `modelProvider: "openai"` in charactor JSON file or `modelProvider: ModelProviderName.OPENAI` in `charactor.ts` -### Setup Agent's Flow Account +### Setup Agent's Flow account Create a new Flow account for the Agent. Learn more: [doc] @@ -148,9 +146,9 @@ Create a new Flow account for the Agent. Learn more: [doc] flow accounts create ``` -> If you are using Testnet, you can get free tokens from [Flow Faucet] +> If you use Testnet, you can get free tokens from [Flow Faucet] -Set Flow blockchain configuration in `.env` with new generated Flow account. +Set the Flow blockchain configuration in `.env` with a newly-generated Flow account. ```bash FLOW_ADDRESS= @@ -159,16 +157,16 @@ FLOW_NETWORK= # Default: mainnet FLOW_ENDPOINT_URL= # Default: ``` -For testnet, please check Flow's [Networks] for more information. +For testnet, check Flow's [Networks] for more information. -## Create Your First Agent +## Create your first agent -### Create a Character File +### Create a character file -Check out the `deps/eliza/characters/` directory for a number of character files to try out. -Additionally you can override Eliza's `defaultCharacter` by editting `charactor.ts` which will be default used if no character json provided. +View the `deps/eliza/characters/` directory for a number of character files to try out. +Additionally, you can edit `charactor.ts` to override Eliza's `defaultCharacter` file, which is the default character file used if no character json files are provided. -Copy one of the example character files and make it your own +Copy one of the example character files and make it your own: ```bash cp characters/scooby.character.json characters/sample.character.json @@ -178,13 +176,13 @@ cp characters/scooby.character.json characters/sample.character.json ### **Start the Agent** -Inform it which character you want to run: +Tell it which character you want to run: ```bash pnpm start --character="characters/sample.character.json" ``` -Or you can use `pnpm start:debug` for more debugging logs: +Or, you can use `pnpm start:debug` for more debugging logs: ```bash pnpm start:debug --character="characters/sample.character.json" @@ -196,23 +194,23 @@ You can load multiple characters with a comma-separated list: pnpm start --characters="characters/sample.character.json, characters/scooby.character.json" ``` -### Add / Develop Plugins +### Add and develop plugins -run `npx elizaos plugins list` to get a list of available plugins or visit [Eliza Plugins Registry] +Run `npx elizaos plugins list` to get a list of available plugins or visit [Eliza Plugins Registry] -run `npx elizaos plugins add @elizaos-plugins/plugin-NAME` to install the plugin into your instance +Run `npx elizaos plugins add @elizaos-plugins/plugin-NAME` to install the plugin into your instance -To create a new plugin **for your own business**, you can refer to the [plugin development guide]. +To create a new plugin **for your own business**, refer to the [plugin development guide]. -#### Additional Requirements +#### Additional requirements -You may need to install Sharp. If you see an error when starting up, try installing it with the following command: +You may need to install Sharp. If you see an error when you start it up, install it with the following command: ```bash pnpm install --include=optional sharp ``` -### **Interact with the Agent** +### **Interact with the agent** Now you're ready to start a conversation with your agent. @@ -222,23 +220,23 @@ Open a new terminal window and run the client's http server. pnpm start:client ``` -Once the client is running, you'll see a message like this: +After the client is running, you'll see a message like this: ```bash ➜ Local: http://localhost:5173/ ``` -Simply click the link or open your browser to `http://localhost:5173/`. You'll see the chat interface connect to the system, and you can begin interacting with your character. +Click the link or open your browser to `http://localhost:5173/`. You'll see the chat interface connect to the system, and you can now interact with your character. -## Common Issues & Solutions +## Common issues and solutions -Please check the orgin Eliza's [Common Issues & Solutions] +Check the orgin Eliza's [Common Issues & Solutions] ## Conclusion In this tutorial, you've learned how to build and deploy an AI agent on the Flow blockchain using Eliza. You've gained hands-on experience with setting up the development environment, configuring agents, creating character configurations, integrating AI models, and developing custom plugins. -The Eliza framework provides a powerful way to create intelligent agents that can understand and respond to user queries while leveraging Flow's secure and scalable infrastructure. By completing this tutorial, you now have the foundation to build more sophisticated AI agents and create unique user experiences through character customization and plugin development. +The Eliza framework provides a powerful way to create intelligent agents that can understand and respond to user queries while leveraging Flow's secure and scalable infrastructure. Now taht you've completed this tutorial, you now have the foundation to build more sophisticated AI agents and create unique user experiences through character customization and plugin development. [Node.js 23+]: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm [nvm]: https://github.com/nvm-sh/nvm @@ -252,7 +250,7 @@ The Eliza framework provides a powerful way to create intelligent agents that ca [Models.ts]: https://github.com/elizaOS/eliza/blob/main/packages/core/src/models.ts [doc]: https://developers.flow.com/tools/flow-cli/accounts/create-accounts [Flow Faucet]: https://faucet.flow.com/ -[Networks]: https://developers.flow.com/networks/flow-networks +[Networks]: https://developers.flow.com/protocol/flow-networks [Character Documentation]: https://elizaos.github.io/eliza/docs/core/characterfile/ [Eliza Plugins Registry]: https://elizaos.github.io/registry [plugin development guide]: build-plugin.md diff --git a/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/index.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/index.md new file mode 100644 index 0000000000..9c6c0e9cd7 --- /dev/null +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/agents/index.md @@ -0,0 +1,69 @@ +--- +title: AI Agents +description: Learn how to build and deploy intelligent AI agents that can interact with the Flow blockchain, execute smart contracts, and automate complex workflows using modern AI frameworks. +sidebar_position: 3 +keywords: + - AI agents + - AgentKit + - autonomous agents + - Flow blockchain + - smart contracts + - automation + - Langchain + - AI workflows + - blockchain interactions +--- + +# AI Agents + +AI agents represent the next evolution in blockchain interaction. They combine artificial intelligence with blockchain capabilities to create autonomous systems that can execute complex tasks, interact with smart contracts, and automate workflows. This section explores how to build intelligent agents that leverage Flow's unique features to create powerful, self-directed blockchain applications. + +Unlike traditional chatbots or simple AI assistants, blockchain AI agents can autonomously execute transactions, manage digital assets, interact with DeFi protocols, and coordinate complex multi-step operations across the Flow ecosystem. These agents bridge the gap between AI decision-making and blockchain execution, which allows new forms of automated financial services, gaming mechanics, and decentralized applications. + +## [Eliza on Flow] + +Learn how to build conversational AI agents on Flow with [Eliza on Flow], a framework for that you can use to create intelligent agents that interact through natural language. Set up agents with customizable personalities, integrate multiple AI models, and connect to Flow's blockchain infrastructure. + +### [Eliza Plugin Development Guide] + +Extend your Eliza agents with custom plugins for specialized functionality. Create plugin repositories, implement custom actions, and publish to the Eliza Plugin Registry for community sharing. + +## [Build Custom AI Agents on Flow with AgentKit] + +Create autonomous AI agents that interact with Flow's blockchain with AgentKit. Set up agents on Flow's EVM-compatible environment, integrate AI models like Claude and GPT-4, and deploy systems that execute blockchain transactions automatically. + +## Key benefits of AI agents on Flow + +**Autonomous Execution**: Agents can independently execute complex blockchain operations without human intervention, from simple token transfers to sophisticated decentralized finance (DeFi) strategies. + +**Flow-Native Integration**: Leverage Flow's unique multi-role architecture, built-in randomness, and efficient transaction processing for enhanced agent capabilities. + +**EVM Compatibility**: Build agents that work seamlessly with both Flow's native Cadence environment and EVM-compatible tools and frameworks. + +**Intelligent Decision Making**: Combine AI reasoning with real-time blockchain data to make informed decisions about transactions, asset management, and protocol interactions. + +**Scalable Automation**: Create agents that can manage multiple wallets, coordinate complex workflows, and scale operations across the Flow ecosystem. + +## Use cases for AI agents + +**Conversational Interfaces**: Build Eliza-powered agents that can provide natural language interfaces to Flow applications, which helps users navigate complex DeFi protocols or gaming mechanics through conversation. + +**Automated Trading**: Build agents that can analyze market conditions, execute trades, manage portfolios across Flow's DeFi ecosystem, and communicate decisions to users. + +**Gaming Automation**: Create intelligent NPCs or automated players that can interact with Flow-based games, manage in-game assets, and execute complex game mechanics with personality-driven responses. + +**Portfolio Management**: Develop agents that can automatically rebalance portfolios, compound yields, optimize asset allocation based on market conditions, and provide conversational feedback. + +**Protocol Automation**: Build agents that can interact with complex DeFi protocols, execute arbitrage opportunities, and manage liquidity positions with intelligent decision-making capabilities. + +**Asset Management**: Create agents that can automatically mint, transfer, and manage NFTs based on predefined conditions or AI-driven decisions, with customizable personalities and interaction styles. + +## Conclusion + +AI agents combine artificial intelligence with blockchain capabilities to create autonomous systems on Flow. Whether you want to build conversational agents with Eliza or autonomous systems with AgentKit, these tutorials provide the foundation for you to create intelligent blockchain applications that can execute transactions, engage users, and automate complex workflows across the Flow ecosystem. + + + +[Eliza on Flow]: ./eliza/index.md +[Eliza Plugin Development Guide]: ./eliza/build-plugin.md +[Build Custom AI Agents on Flow with AgentKit]: ./agentkit-flow-guide.md \ No newline at end of file diff --git a/docs/tutorials/use-AI-to-build-on-flow/cadence-rules.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/cadence-rules.md similarity index 60% rename from docs/tutorials/use-AI-to-build-on-flow/cadence-rules.md rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/cadence-rules.md index 1b24236a6d..34af126b5d 100644 --- a/docs/tutorials/use-AI-to-build-on-flow/cadence-rules.md +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/cadence-rules.md @@ -1,56 +1,65 @@ --- title: Cadence Rules description: Learn how to use Cursor Rules to enhance AI assistance for Cadence and Flow development with persistent context and automated workflows. -sidebar_position: 4 +sidebar_position: 3 label: Cadence Rules sidebar_label: Cadence Rules keywords: - - Cursor Rules - - AI - - Cursor - - Cadence - - AI_Flow - - Cadence Rules + - Cursor Rules + - AI + - Cursor + - Cadence + - AI_Flow + - Cadence Rules --- # Cadence Rules -## Introduction - -When building with AI, it is hard to make the agent consistently understand what standards it should use when building or generating responses. Cursor Rules mitigates this issue by setting up global rules, project wide rules or document specific rules that are inserted in the agent's context before reading the prompt. With Cursor Rules, you can create an assistant that can consistently understand the intended development process, desired formatted responses, and avoid common mistakes. Consider it your tool to make guard rails for agents that can reduce hallucination and incorrecting development flows. +When you build with AI, it's hard to make the agent consistently understand what standards it should use when it builds or generates responses. To migitate this issue, Cursor Rules sets up global rules, project wide rules or documents specific rules that it inserts in the agent's context before it reads the prompt. With Cursor Rules, you can create an assistant that can consistently understand the intended development process, desired formatted responses, and avoid common mistakes. Consider it your tool to make guard rails for agents that can reduce hallucination and incorrect development flows. In this guide, you'll learn how to configure and use Cursor Rules that transform your AI assistant into a Flow development expert with persistent knowledge of Cadence syntax patterns, NFT standards, project configuration, and development workflows. -## Learning Objectives +
+ +
-After completing this guide, you'll be able to: +## Learning objectives -- Configure and use Cursor Rules to enhance AI assistance for Flow blockchain development -- Apply specialized Cadence syntax patterns and NFT development standards through persistent AI context -- Utilize workflow-based rules to guide project setup, deployment, and debugging processes across the Flow development lifecycle -- Create your own Cadence Rules in order to supercharge your development on Flow +After you complete this guide, you'll be able to: -## What Are Cursor Rules? +- Configure and use Cursor Rules to enhance AI assistance for Flow blockchain development. +- Apply specialized Cadence syntax patterns and NFT development standards through persistent AI context. +- Use workflow-based rules to guide project setup, deployment, and debugging processes across the Flow development lifecycle. +- Create your own Cadence Rules in order to supercharge your development on Flow. -Cursor rules are a way to shape AI behavior with persistent, reusable instructions that guide how Cursor's Agent and Inline Edit assist you. Rules act as continuous context - embedding your preferences, coding standards, and workflows directly into the AI's decision-making process. Since AI models start fresh with each interaction, rules bridge this gap by automatically injecting your preferences and context into every conversation. -When active, rules are included at the beginning of the AI's context, providing consistent guidance for code generation, edit suggestions, and workflow assistance. +## What are Cursor rules? -Cursor offers two rule types: +Cursor rules shape AI behavior with persistent, reusable instructions that guide how Cursor's Agent and Inline Edit assist you. Rules act as continuous context - they embed your preferences, code standards, and workflows directly into the AI's decision-making process. Since AI models start fresh with each interaction, rules automatically inject your preferences and context into every conversation, which bridfges this gap. -- **Project Rules**: Live in `.cursor/rules`, version-controlled with your code, and apply to specific projects -- **User Rules**: Global preferences in Cursor Settings that apply across all your projects +When active, rules are included at the beginning of the AI's context and provide consistent guidance for code generation, edit suggestions, and workflow assistance. +Cursor offers two rule types: + +- **Project Rules**: Live in `.cursor/rules`, version-controlled with your code, and apply to specific projects. +- **User Rules**: Global preferences in Cursor Settings that apply across all your projects. ### Rule anatomy -Each rule file is written in MDC (.mdc), a format supporting metadata and content. Control how rules are applied from the type dropdown which changes properties `description`, `globs`, `alwaysApply`. +Each rule file is written in MDC (`.mdc`), a format supporting metadata and content. Control how rules are applied from the type dropdown which changes properties `description`, `globs`, `alwaysApply`. -|Rule Type |Description | -|------------------------|---------------------------------------------------------------------------------| -|Always Apply |Always included in model context | -|Apply to Specific Files |Included when files matching a glob pattern are referenced | -|Apply Intellegently |Available to AI, which decides whether to include it. Must provide a description | -|Apply Manually |Only included when explicitly mentioned using `@ruleName` | +| Rule Type | Description | +| ----------------------- | --------------------------------------------------------------------------------- | +| Always Apply | Always included in model context. | +| Apply to Specific Files | Included when files matching a glob pattern are referenced. | +| Apply Intellegently | Available to AI, which decides whether to include it. Must provide a description. | +| Apply Manually | Only included when explicitly mentioned using `@ruleName`. | ```mdc --- @@ -59,10 +68,10 @@ globs: ["**/*.cdc", "**/contracts/**", "**/cadence/**"] alwaysApply: false --- -- Always implement NonFungibleToken interface for NFT contracts -- Use MetadataViews for marketplace compatibility -- Follow proper resource handling with @ and & symbols -- Include required standard functions and path conventions +- Always implement NonFungibleToken interface for NFT contracts. +- Use MetadataViews for marketplace compatibility. +- Follow proper resource handling with @ and & symbols. +- Include required standard functions and path conventions. @nft-template.cdc @@ -70,9 +79,9 @@ alwaysApply: false Referenced files like `@nft-template.cdc` are included as additional context when the rule triggers. -## User Rules +## User rules -User rules are global preferences defined in Cursor Settings → Rules that apply across all projects. They’re plain text and perfect for setting preferred communication style or coding conventions: +User rules are global preferences defined in Cursor Settings → Rules that apply across all projects. They’re plain text and perfect for setting preferred communication style or code conventions: ```md Please reply in a concise style. Avoid unnecessary repetition or filler language. @@ -80,17 +89,17 @@ Please reply in a concise style. Avoid unnecessary repetition or filler language ## Project rules -Project rules are stored as individual files in `.cursor/rules` and get version-controlled alongside your code. Each rule can target specific file types using glob patterns, be manually invoked when needed, or automatically activate based on context. You can also create nested rule directories - any folder can have its own `.cursor/rules` directory with rules that apply specifically to that area of your project. +Project rules are stored as individual files in `.cursor/rules` and get version-controlled alongside your code. Each rule can target specific file types with glob patterns, be manually invoked when needed, or automatically activate based on context. You can also create nested rule directories - any folder can have its own `.cursor/rules` directory with rules that apply specifically to that area of your project. -Project rules excel at: +Project rules help: -- Capturing specialized knowledge about your codebase and domain -- Establishing consistent workflows and development patterns -- Enforcing coding standards and architectural decisions across your team +- Capture specialized knowledge about your codebase and domain. +- Establish consistent workflows and development patterns. +- Enforce coding standards and architectural decisions across your team. -### Nested Rules +### Nested rules -Organize rules by placing them in .cursor/rules directories throughout your project. Nested rules automatically attach when files in their directory are referenced. +To organize rules, place them in `.cursor/rules` directories throughout your project. Nested rules automatically attach when files in their directory are referenced. ```mdc project/ @@ -101,17 +110,17 @@ project/ .cursor/rules/ # Frontend-specific rules ``` -## Creating a rule +## Create rules -Create rules using the Cursor Rule command or going to Cursor Settings > Rules. This creates a new rule file in .cursor/rules. From settings you can see all rules and their status. +Create rules with the Cursor Rule command or go to Cursor Settings > Rules. This creates a new rule file in `.cursor/rules`. From settings you can see all rules and their status. -Click on the cog icon on the upper right section of the window. Then click the "Rules and Memories" section on the left side bar. Finally click on the "+ Add Rule" button in the User Rules or Project Rules section (depending on your objective). +Click the cog icon on the upper right section of the window. Then, click "Rules and Memories" on the left side bar. Finally click "+ Add Rule" in the User Rules or Project Rules section (this depends on your objective). ![Creating a Cursor Rule](./imgs/cursor_rules1.png) -### Generating rules +### Generate rules -Generate rules directly in conversations using the `/Generate Cursor Rules` command. Useful when you’ve made decisions about agent behavior and want to reuse them. +Generate rules directly in conversations with the `/Generate Cursor Rules` command. This is useful when you’ve made decisions about agent behavior and want to reuse them. ![Generate Cursor Rules](./imgs/generate_cursor_rules.png) @@ -119,41 +128,41 @@ Generate rules directly in conversations using the `/Generate Cursor Rules` comm Good rules are focused, actionable, and scoped. -- Keep rules under 500 lines -- Split large rules into multiple, composable rules -- Provide concrete examples or referenced files -- Avoid vague guidance. Write rules like clear internal docs -- Reuse rules when repeating prompts in chat +- Keep rules under 500 lines. +- Split large rules into multiple, composable rules. +- Provide concrete examples or referenced files. +- Avoid vague guidance. Write rules like clear internal docs. +- Reuse rules when repeating prompts in chat. -## Cadence Rules +## Cadence rules -Here are a couple of Cursor Rules made by [claucondor] made for Flow development and NFTs +Here are a couple of Cursor Rules made by [claucondor] for Flow development and NFTs. -### Cadence NFT Standards +### Cadence NFT standards -The [cadence-nft-standards.mdc] rule provides comprehensive guidelines for developing NFTs using Cadence on Flow blockchain. It ensures proper implementation of: +The [cadence-nft-standards.mdc] rule provides comprehensive guidelines for NFT development with Cadence on Flow blockchain. It ensures proper implementation of: -- **Core Interface Conformance**: `NonFungibleToken`, `NFT`, and `Collection` interfaces -- **MetadataViews Integration**: Marketplace-compatible metadata standards -- **Modular Architecture**: Patterns for complex NFTs with traits, evolution, and breeding -- **Security Best Practices**: Proper resource handling and capability management -- **Event Standards**: Consistent event emission for off-chain indexing +- **Core Interface Conformance**: `NonFungibleToken`, `NFT`, and `Collection` interfaces. +- **MetadataViews Integration**: Marketplace-compatible metadata standards. +- **Modular Architecture**: Patterns for complex NFTs with traits, evolution, and breeding. +- **Security Best Practices**: Proper resource handling and capability management. +- **Event Standards**: Consistent event emission for off-chain indexing. **Perfect for:** -- New NFT projects on Flow -- NFT marketplace integration -- Complex NFT systems (traits, evolution, breeding) -- Code reviews and standards compliance -- Learning Flow NFT development +- New NFT projects on Flow. +- NFT marketplace integration. +- Complex NFT systems (traits, evolution, breeding). +- Code reviews and standards compliance. +- Learning Flow NFT development. -**Applies to:** `.cdc` files, NFT transactions, collection setup, metadata implementation +**Applies to:** `.cdc` files, NFT transactions, collection setup, metadata implementation. -#### Rule Configuration +#### Rule configuration ```mdc --- -description: Comprehensive standards and best practices for developing Non-Fungible Tokens (NFTs) using Cadence. Ensures proper implementation of NonFungibleToken interfaces, MetadataViews integration for marketplace compatibility, secure resource handling patterns, and advanced modular architectures for complex NFTs with traits, evolution, and breeding mechanics. Includes required standard functions, path conventions, event emission patterns, and security best practices for capability management. +description: Comprehensive standards and best practices for developing Non-Fungible Tokens (NFTs) with Cadence. Ensures proper implementation of NonFungibleToken interfaces, MetadataViews integration for marketplace compatibility, secure resource handling patterns, and advanced modular architectures for complex NFTs with traits, evolution, and breeding mechanics. Includes required standard functions, path conventions, event emission patterns, and security best practices for capability management. globs: ["**/*.cdc", "**/contracts/**", "**/cadence/**"] alwaysApply: false --- @@ -161,56 +170,56 @@ alwaysApply: false Recommended Apply config: `Apply Intelligently` -#### Manual Reference +#### Manual reference ``` @cadence-nft-standards help me implement a new NFT contract ``` -#### Key Benefits +#### Key benefits -- **Ecosystem Compatibility**: Guaranteed marketplace and wallet integration -- **Security**: Proper resource handling and capability management -- **Maintainability**: Modular architecture for complex systems -- **Performance**: Gas-efficient implementations with lazy initialization -- **Standards Compliance**: Follows official Flow NFT patterns +- **Ecosystem Compatibility**: Guaranteed marketplace and wallet integration. +- **Security**: Proper resource handling and capability management. +- **Maintainability**: Modular architecture for complex systems. +- **Performance**: Gas-efficient implementations with lazy initialization. +- **Standards Compliance**: Follows official Flow NFT patterns. -#### Usage Examples +#### Usage examples -- `"Create an NFT contract for collectible cards"` → Guides complete interface implementation -- `"Make my NFT marketplace compatible"` → Provides MetadataViews patterns -- `"Build evolving NFTs with traits"` → Suggests modular architecture patterns -- `"Review my NFT contract"` → Validates against all documented standards +- `"Create an NFT contract for collectible cards"` → Guides complete interface implementation. +- `"Make my NFT marketplace compatible"` → Provides MetadataViews patterns. +- `"Build evolving NFTs with traits"` → Suggests modular architecture patterns. +- `"Review my NFT contract"` → Validates against all documented standards. -### Cadence Syntax Patterns +### Cadence syntax patterns -#### What This Rule Does +#### What this rule does -The [cadence-syntax-patterns.mdc] rule provides comprehensive syntax guidance and error prevention for Cadence development. It covers essential language patterns including: +The [cadence-syntax-patterns.mdc] rule provides comprehensive syntax guidance and error prevention for Cadence development. It covers essential language patterns such as: -- **Resource Type Syntax**: Proper use of `@` and `&` symbols for resources and references -- **Interface Restrictions**: Correct `{}` syntax for interface constraints -- **Transaction Authorization**: Granular `auth` capabilities and permission patterns -- **Contract Member Access**: Accessing deployed contract functions and constants -- **Type Conversion & Arithmetic**: Explicit type handling and numeric operations -- **Access Control**: Field visibility, entitlements, and `view` function purity -- **Language Constructs**: Optional binding, loops, string manipulation, switch cases -- **Debugging Strategies**: Systematic error resolution and prevention techniques +- **Resource Type Syntax**: Proper use of `@` and `&` symbols for resources and references. +- **Interface Restrictions**: Correct `{}` syntax for interface constraints. +- **Transaction Authorization**: Granular `auth` capabilities and permission patterns. +- **Contract Member Access**: Accessing deployed contract functions and constants. +- **Type Conversion & Arithmetic**: Explicit type handling and numeric operations. +- **Access Control**: Field visibility, entitlements, and `view` function purity. +- **Language Constructs**: Optional binding, loops, string manipulation, switch cases. +- **Debugging Strategies**: Systematic error resolution and prevention techniques. **Perfect for:** -- Writing any Cadence contracts or transactions -- Debugging compilation errors with resources (`@`) or references (`&`) -- Fixing authorization issues in transactions -- Learning Cadence syntax and best practices -- Preventing common type system errors -- Understanding Flow blockchain development patterns +- Writing any Cadence contracts or transactions. +- Debugging compilation errors with resources (`@`) or references (`&`). +- Fixing authorization issues in transactions. +- Learning Cadence syntax and best practices. +- Preventing common type system errors. +- Understanding Flow blockchain development patterns. -**Applies to:** `.cdc` files, transaction scripts, contract development, Flow CLI usage, error debugging +**Applies to:** `.cdc` files, transaction scripts, contract development, Flow CLI usage, error debugging. -#### How to Use This Rule +#### How to use this rule -#### Auto Attached Configuration +#### Auto attached configuration ```mdc --- @@ -222,7 +231,7 @@ alwaysApply: false Recommended Apply config: `Apply Intelligently` -#### Manual Reference +#### Manual reference ``` @cadence-syntax-patterns help me fix this authorization error @@ -230,14 +239,14 @@ Recommended Apply config: `Apply Intelligently` #### Key Benefits -- **Error Prevention**: Avoids common syntax mistakes before they happen -- **Faster Debugging**: Systematic approaches to resolve compilation errors -- **Best Practices**: Language-specific patterns that follow Cadence conventions -- **Authorization Mastery**: Proper transaction permission handling -- **Type Safety**: Correct resource handling and type conversions -- **Performance**: Optimized patterns for gas efficiency +- **Error Prevention**: Avoids common syntax mistakes before they happen. +- **Faster Debugging**: Systematic approaches to resolve compilation errors. +- **Best Practices**: Language-specific patterns that follow Cadence conventions. +- **Authorization Mastery**: Proper transaction permission handling. +- **Type Safety**: Correct resource handling and type conversions. +- **Performance**: Optimized patterns for compute unit (gas) efficiency. -#### Usage Examples +#### Usage examples - `"Fix this resource handling error"` → Provides `@` and `&` syntax corrections - `"My transaction authorization is failing"` → Suggests proper `auth` capabilities @@ -246,10 +255,10 @@ Recommended Apply config: `Apply Intelligently` - `"Interface restriction syntax error"` → Corrects to `{}` interface syntax - `"Access control for resource fields"` → Guides `access(self)` vs `access(all)` patterns -#### Key Syntax Patterns Covered +#### Key syntax patterns covered - **Resources**: `@{NonFungibleToken.NFT}` not `@NonFungibleToken.NFT` -- **Authorization**: `auth(Storage) &Account` or granular capabilities +- **Authorization**: `auth(Storage) &Account` or granular capabilities. - **Optional Binding**: `if let` syntax (no `guard let`) - **Variable Initialization**: All `var` declarations must have initial values - **Type Conversion**: Explicit conversion required for arithmetic @@ -257,32 +266,32 @@ Recommended Apply config: `Apply Intelligently` - **String Operations**: Use `.split()` and `.contains()` (no `.indexOf()`) - **Loops**: `while` loops only (no range-based `for` loops) -### Flow Development Workflow +### Flow development workflow -#### What This Rule Does +#### What this rule does -The [flow-development-workflow.mdc] rule provides comprehensive workflow methodology for Flow blockchain development covering the complete development lifecycle. It includes: +The [flow-development-workflow.mdc] rule provides comprehensive workflow methodology for Flow blockchain development that covers the complete development lifecycle. It includes: -- **Documentation-First Approach**: Always reference official Flow documentation and standard examples -- **Development Sequence**: Emulator → Testnet → Mainnet progression with proper validation -- **Transaction Authorization**: Granular `auth` capabilities and permission management -- **Deployment Verification**: Post-deployment validation protocols and testing strategies -- **FCL Integration**: Frontend configuration, network management, and user experience patterns -- **Error Resolution**: Systematic debugging approaches and common error prevention -- **Optimization Techniques**: Computation limit handling and gas efficiency strategies -- **Testnet Validation**: Comprehensive validation protocols before mainnet deployment +- **Documentation-First Approach**: Always reference official Flow documentation and standard examples. +- **Development Sequence**: Emulator → Testnet → Mainnet progression with proper validation. +- **Transaction Authorization**: Granular `auth` capabilities and permission management. +- **Deployment Verification**: Post-deployment validation protocols and testing strategies. +- **FCL Integration**: Frontend configuration, network management, and user experience patterns. +- **Error Resolution**: Systematic debugging approaches and common error prevention. +- **Optimization Techniques**: Computation limit handling and compute unit (gas) efficiency strategies. +- **Testnet Validation**: Comprehensive validation protocols before mainnet deployment. **Perfect for:** -- Starting new Flow projects or need setup guidance -- Moving between development stages (emulator → testnet → mainnet) -- Debugging deployment or transaction authorization issues -- Integrating frontend applications with FCL -- Handling computation limits and gas optimization -- Learning Flow development best practices and official patterns -- Comprehensive project validation strategies +- Starting new Flow projects or need setup guidance. +- Moving between development stages (emulator → testnet → mainnet). +- Debugging deployment or transaction authorization issues. +- Integrating frontend applications with FCL. +- Handling computation limits and compute unit (gas) optimization. +- Learning Flow development best practices and official patterns. +- Comprehensive project validation strategies. -**Applies to:** Complete Flow development lifecycle, project setup, deployment, FCL integration, debugging +**Applies to:** Complete Flow development lifecycle, project setup, deployment, FCL integration, debugging. #### Manual Reference @@ -290,7 +299,7 @@ The [flow-development-workflow.mdc] rule provides comprehensive workflow methodo @flow-development-workflow help me deploy to testnet properly ``` -#### Auto Attached Configuration +#### Auto attached configuration ```mdc --- @@ -302,71 +311,71 @@ alwaysApply: false Recommended Apply config: `Apply Intelligently` -#### Key Benefits +#### Key benefits -- **Systematic Approach**: Step-by-step methodology prevents common mistakes -- **Official Patterns**: Emphasizes Flow documentation and standard examples -- **Error Prevention**: Proactive strategies for avoiding deployment and integration issues -- **Full-Stack Awareness**: Covers both Cadence backend and FCL frontend integration -- **Optimization Focus**: Gas efficiency and computation limit management -- **Validation Protocols**: Comprehensive testing before production deployment +- **Systematic Approach**: Step-by-step methodology prevents common mistakes. +- **Official Patterns**: Emphasizes Flow documentation and standard examples. +- **Error Prevention**: Proactive strategies for avoiding deployment and integration issues. +- **Full-Stack Awareness**: Covers both Cadence backend and FCL frontend integration. +- **Optimization Focus**: Gas efficiency and computation limit management. +- **Validation Protocols**: Comprehensive testing before production deployment. -#### Usage Examples +#### Usage examples -- `"How do I set up a new Flow project?"` → Guides project setup and configuration -- `"My transaction authorization is failing"` → Provides auth capability debugging -- `"Deploy my contract to testnet"` → Shows deployment sequence and verification -- `"FCL integration not working"` → Suggests configuration and network troubleshooting -- `"Computation limit exceeded"` → Recommends optimization strategies -- `"Prepare for mainnet deployment"` → Provides comprehensive validation checklist +- `"How do I set up a new Flow project?"` → Guides project setup and configuration. +- `"My transaction authorization is failing"` → Provides auth capability debugging. +- `"Deploy my contract to testnet"` → Shows deployment sequence and verification. +- `"FCL integration not working"` → Suggests configuration and network troubleshooting. +- `"Computation limit exceeded"` → Recommends optimization strategies. +- `"Prepare for mainnet deployment"` → Provides comprehensive validation checklist. -#### Key Workflow Areas Covered +#### Key workflow areas covered -- **Project Setup**: `flow.json` configuration, FCL setup, environment management -- **Authorization**: `auth(Storage)`, `auth(BorrowValue, SaveValue)`, granular capabilities -- **Development Sequence**: Emulator testing → Frontend integration → Testnet → Validation -- **Error Resolution**: Syntax errors, deployment errors, FCL errors, computation limits -- **FCL Best Practices**: Network configuration, contract address management, user authentication -- **Optimization**: Accumulative processing, loop optimization, gas efficiency -- **Deployment**: Verification protocols, update strategies, multi-network consistency -- **Documentation Usage**: When and how to reference official Flow resources +- **Project Setup**: `flow.json` configuration, FCL setup, environment management. +- **Authorization**: `auth(Storage)`, `auth(BorrowValue, SaveValue)`, granular capabilities. +- **Development Sequence**: Emulator testing → Frontend integration → Testnet → Validation. +- **Error Resolution**: Syntax errors, deployment errors, FCL errors, computation limits. +- **FCL Best Practices**: Network configuration, contract address management, user authentication. +- **Optimization**: Accumulative processing, loop optimization, compute unit (gas) efficiency. +- **Deployment**: Verification protocols, update strategies, multi-network consistency. +- **Documentation Usage**: When and how to reference official Flow resources. -#### Development Philosophy Emphasized +#### Development philosophy emphasized -- **Documentation-Driven**: Reference official sources before creating custom solutions -- **Iterative Approach**: Fix issues one at a time, test frequently at each stage -- **Standard Compliance**: Prefer established Flow patterns over custom implementations -- **Full-Stack Awareness**: Consider entire stack from contracts to frontend UI -- **Error-Driven Learning**: Use errors as opportunities to refine understanding +- **Documentation-Driven**: Reference official sources before creating custom solutions. +- **Iterative Approach**: Fix issues one at a time, test frequently at each stage. +- **Standard Compliance**: Prefer established Flow patterns over custom implementations. +- **Full-Stack Awareness**: Consider entire stack from contracts to frontend UI. +- **Error-Driven Learning**: Use errors as opportunities to refine understanding. -### Flow Project Configuration +### Flow project configuration #### What This Rule Does The [flow-project-config.mdc] rule provides comprehensive guidance for Flow project configuration and `flow.json` management. It covers essential configuration patterns including: -- **`flow.json` Structure**: Accounts, contracts, deployments, and networks configuration -- **Account Management**: Named accounts, addresses, private keys, and signer setup -- **Contract Registration**: Source paths, network-specific aliases, and pre-deployment setup -- **Deployment Configuration**: Network-specific deployments and contract mappings -- **FCL Integration**: Synchronizing backend deployment with frontend address configuration -- **Network Management**: Multi-network consistency across emulator, testnet, and mainnet -- **Error Prevention**: Common configuration mistakes and troubleshooting strategies -- **Address Mapping**: Contract address management and import resolution +- **`flow.json` Structure**: Accounts, contracts, deployments, and networks configuration. +- **Account Management**: Named accounts, addresses, private keys, and signer setup. +- **Contract Registration**: Source paths, network-specific aliases, and pre-deployment setup. +- **Deployment Configuration**: Network-specific deployments and contract mappings. +- **FCL Integration**: Synchronizing backend deployment with frontend address configuration. +- **Network Management**: Multi-network consistency across emulator, testnet, and mainnet. +- **Error Prevention**: Common configuration mistakes and troubleshooting strategies. +- **Address Mapping**: Contract address management and import resolution. **Perfect for:** -- Setting up new Flow projects or configuring `flow.json` -- Debugging deployment or contract resolution issues -- Managing FCL integration and address mapping problems -- Working across different networks (emulator/testnet/mainnet) -- Troubleshooting CLI errors related to signers or contract imports -- Account management and private key handling -- Contract aliasing and deployment configurations +- Setting up new Flow projects or configuring `flow.json`. +- Debugging deployment or contract resolution issues. +- Managing FCL integration and address mapping problems. +- Working across different networks (emulator/testnet/mainnet). +- Troubleshooting CLI errors related to signers or contract imports. +- Account management and private key handling. +- Contract aliasing and deployment configurations. -**Applies to:** `flow.json`, FCL config files, deployment scripts, network switching, contract imports +**Applies to:** `flow.json`, FCL config files, deployment scripts, network switching, contract imports. -#### Auto Attached Configuration +#### Auto attached configuration ```mdc --- @@ -378,133 +387,133 @@ alwaysApply: false Recommended Apply config: `Apply Intelligently` -#### Manual Reference +#### Manual reference ``` @flow-project-config help me configure my flow.json for testnet deployment ``` -#### Key Benefits +#### Key benefits -- **Configuration Accuracy**: Prevents common setup and deployment errors -- **Multi-Network Support**: Seamless switching between emulator, testnet, and mainnet -- **FCL Synchronization**: Ensures frontend and backend configurations stay aligned -- **Error Prevention**: Addresses typos, address mismatches, and path issues proactively -- **Deployment Success**: Proper account setup and contract registration workflows -- **Address Management**: Centralized contract address handling across environments +- **Configuration Accuracy**: Prevents common setup and deployment errors. +- **Multi-Network Support**: Seamless switching between emulator, testnet, and mainnet. +- **FCL Synchronization**: Ensures frontend and backend configurations stay aligned. +- **Error Prevention**: Addresses typos, address mismatches, and path issues proactively. +- **Deployment Success**: Proper account setup and contract registration workflows. +- **Address Management**: Centralized contract address handling across environments. -#### Usage Examples +#### Usage examples -- `"Configure flow.json for new project"` → Provides complete structure and setup guidance -- `"Failed to resolve contract import"` → Suggests address mapping and alias fixes -- `"Wrong signer/network CLI error"` → Guides account and network configuration -- `"FCL can't find my contract"` → Shows frontend address configuration patterns -- `"Deploy contract to testnet"` → Provides deployment configuration and verification -- `"Switch from emulator to testnet"` → Guides network transition and address updates +- `"Configure flow.json for new project"` → Provides complete structure and setup guidance. +- `"Failed to resolve contract import"` → Suggests address mapping and alias fixes. +- `"Wrong signer/network CLI error"` → Guides account and network configuration. +- `"FCL can't find my contract"` → Shows frontend address configuration patterns. +- `"Deploy contract to testnet"` → Provides deployment configuration and verification. +- `"Switch from emulator to testnet"` → Guides network transition and address updates. -#### Key Configuration Areas Covered +#### Key configuration areas covered -- **Account Setup**: Address accuracy, key file paths, network-specific accounts -- **Contract Registration**: Source paths, aliases, pre-deployment requirements -- **Deployment Management**: Signer assignment, contract lists, network specificity -- **Standard Contract Addresses**: Official addresses for NonFungibleToken, MetadataViews, FungibleToken -- **FCL Configuration**: Network settings, contract address mapping, environment variables -- **Error Prevention**: Typo checking, address consistency, permission handling -- **Multi-Network Patterns**: Network-specific aliases and deployment strategies -- **CLI Usage**: Correct `--signer`, `--network`, and `--update` flag usage +- **Account Setup**: Address accuracy, key file paths, network-specific accounts. +- **Contract Registration**: Source paths, aliases, pre-deployment requirements. +- **Deployment Management**: Signer assignment, contract lists, network specificity. +- **Standard Contract Addresses**: Official addresses for NonFungibleToken, MetadataViews, FungibleToken. +- **FCL Configuration**: Network settings, contract address mapping, environment variables. +- **Error Prevention**: Typo checking, address consistency, permission handling. +- **Multi-Network Patterns**: Network-specific aliases and deployment strategies. +- **CLI Usage**: Correct `--signer`, `--network`, and `--update` flag usage. -#### Common Issues Addressed +#### Common issues addressed -- **"failed to get contract"**: Missing or incorrect aliases in `flow.json` -- **"failed to resolve import"**: Address mapping issues in FCL configuration -- **"Permission Denied"**: Key file accessibility and path problems -- **"transaction failed to decode"**: Network mismatch or FCL configuration errors -- **Signer/Network Mismatches**: Using emulator accounts on testnet and vice-versa -- **Address Inconsistencies**: Misaligned addresses between `flow.json` and FCL config +- **"failed to get contract"**: Missing or incorrect aliases in `flow.json`. +- **"failed to resolve import"**: Address mapping issues in FCL configuration. +- **"Permission Denied"**: Key file accessibility and path problems. +- **"transaction failed to decode"**: Network mismatch or FCL configuration errors. +- **Signer/Network Mismatches**: Using emulator accounts on testnet and vice-versa. +- **Address Inconsistencies**: Misaligned addresses between `flow.json` and FCL config. -#### Best Practices Emphasized +#### Best practices emphasized -- **Pre-deployment Registration**: Always add contracts to `flow.json` before deploying -- **Address Consistency**: Ensure addresses match across `flow.json`, FCL config, and imports -- **Environment Variables**: Use `.env` files for network-specific contract addresses -- **Network Separation**: Maintain distinct configurations for each network environment -- **Key Security**: Proper `.gitignore` setup for private key files +- **Pre-deployment Registration**: Always add contracts to `flow.json` before you deploy it. +- **Address Consistency**: Ensure addresses match across `flow.json`, FCL config, and imports. +- **Environment Variables**: Use `.env` files for network-specific contract addresses. +- **Network Separation**: Maintain distinct configurations for each network environment. +- **Key Security**: Proper `.gitignore` setup for private key files. -### User Preferences +### User preferences -#### What This Rule Does +#### What this rule does The [user-preferences.mdc] rule personalizes AI assistance behavior for Flow blockchain development. It defines preferred communication style and development methodology including: -- **Communication Style**: Concise, actionable solutions with proactive error prevention explanations -- **Development Philosophy**: Documentation-driven approach with official Flow patterns preference -- **Problem-Solving Methodology**: Root cause analysis, iterative fixes, and pattern recognition -- **Code Quality Standards**: Standards compliance, consistency, and completeness requirements -- **Workflow Preferences**: Thorough setup, emulator-first testing, and systematic debugging -- **Error Resolution Style**: Reference-based solutions and prevention-focused learning -- **Full-Stack Awareness**: Solutions considering entire stack from Cadence to frontend UI -- **User Experience Focus**: Clear blockchain interaction feedback and user-friendly interfaces +- **Communication Style**: Concise, actionable solutions with proactive error prevention explanations. +- **Development Philosophy**: Documentation-driven approach with official Flow patterns preference. +- **Problem-Solving Methodology**: Root cause analysis, iterative fixes, and pattern recognition. +- **Code Quality Standards**: Standards compliance, consistency, and completeness requirements. +- **Workflow Preferences**: Thorough setup, emulator-first testing, and systematic debugging. +- **Error Resolution Style**: Reference-based solutions and prevention-focused learning. +- **Full-Stack Awareness**: Solutions that consider entire stack from Cadence to frontend UI. +- **User Experience Focus**: Clear blockchain interaction feedback and user-friendly interfaces. **Perfect for:** -- Ensuring consistent AI behavior across all Flow development projects -- Matching AI assistance style to your preferred working methodology -- Getting responses formatted in your preferred communication style -- Maintaining documentation-driven and standards-compliant approaches -- Ensuring full-stack consideration in all solutions provided -- Receiving proactive error prevention guidance with solutions +- Ensuring consistent AI behavior across all Flow development projects. +- Matching AI assistance style to your preferred working methodology. +- Getting responses formatted in your preferred communication style. +- Maintaining documentation-driven and standards-compliant approaches. +- Ensuring full-stack consideration in all solutions provided. +- Receiving proactive error prevention guidance with solutions. **Applies to:** All AI assistance, communication style, problem-solving approach, solution methodology -#### Synergy with Technical Rules +#### Synergy with technical rules This rule works as the **behavioral foundation** for your technical Flow rules: -- **Technical Rules** provide **WHAT** information to apply -- **User Preferences** defines **HOW** to deliver that information -- **Result**: Consistent, personalized assistance across all Flow development scenarios +- **Technical Rules** provide **WHAT** information to apply. +- **User Preferences** defines **HOW** to deliver that information. +- **Result**: Consistent, personalized assistance across all Flow development scenarios. -#### Always Applied Configuration +#### Always applied configuration ```mdc --- -description: Defines personalized development preferences and communication style for Flow blockchain development including concise response formatting, documentation-driven problem solving, iterative workflow methodology, full-stack awareness, and systematic error resolution. Guides AI behavior to match user's preferred development philosophy with emphasis on official Flow patterns, practical solutions, and proactive error prevention across the entire development stack. +description: Defines personalized development preferences and communication style for Flow blockchain development, whcih includes concise response formatting, documentation-driven problem solving, iterative workflow methodology, full-stack awareness, and systematic error resolution. Guides AI behavior to match user's preferred development philosophy with emphasis on official Flow patterns, practical solutions, and proactive error prevention across the entire development stack. alwaysApply: true --- ``` Recommended Apply config: `Always Apply` -#### Key Benefits +#### Key benefits -- **Consistent Communication**: AI responses match your preferred style and level of detail -- **Methodology Alignment**: Solutions follow your preferred development philosophy -- **Error Prevention Focus**: Proactive guidance on avoiding similar issues in the future -- **Efficiency**: Concise but complete responses without unnecessary verbosity -- **Standards Compliance**: Emphasis on official Flow patterns and best practices -- **Full-Stack Perspective**: Solutions consider entire development stack implications +- **Consistent Communication**: AI responses match your preferred style and level of detail. +- **Methodology Alignment**: Solutions follow your preferred development philosophy. +- **Error Prevention Focus**: Proactive guidance on avoiding similar issues in the future. +- **Efficiency**: Concise, but complete responses without unnecessary verbosity. +- **Standards Compliance**: Emphasis on official Flow patterns and best practices. +- **Full-Stack Perspective**: Solutions consider entire development stack implications. -#### How This Rule Affects AI Responses +#### How this rule affects AI responses -- **Response Style**: `"Configure flow.json for testnet"` → Provides direct steps + brief prevention tips -- **Problem-Solving**: `"Authorization error"` → Root cause analysis + pattern to prevent recurrence -- **Code Solutions**: Always includes reference to official documentation when available -- **Error Debugging**: Systematic, one-issue-at-a-time approach with testing checkpoints -- **Architecture Decisions**: Prefer established Flow patterns over custom implementations -- **Learning Approach**: Uses errors as learning opportunities with rule/pattern references +- **Response Style**: `"Configure flow.json for testnet"` → Provides direct steps + brief prevention tips. +- **Problem-Solving**: `"Authorization error"` → Root cause analysis + pattern to prevent recurrence. +- **Code Solutions**: Always includes reference to official documentation when available. +- **Error Debugging**: Systematic, one-issue-at-a-time approach with testing checkpoints. +- **Architecture Decisions**: Prefer established Flow patterns over custom implementations. +- **Learning Approach**: Uses errors as learning opportunities with rule and pattern references. -#### Behavioral Patterns Defined +#### Behavioral patterns defined -- **Conciseness**: Clear, actionable solutions without excessive explanation -- **Practical Focus**: Working code examples prioritized over theoretical explanations -- **Documentation-Driven**: Official Flow, Cadence, FCL docs referenced first -- **Iterative Methodology**: Fix one issue at a time, test frequently -- **Standard Compliance**: Established patterns preferred over custom solutions -- **Root Cause Analysis**: Address underlying issues, not just symptoms -- **Prevention-Oriented**: Include brief explanations of why errors occurred -- **Full-Stack Consideration**: Account for contracts, transactions, FCL, and UI implications +- **Conciseness**: Clear, actionable solutions without excessive explanation. +- **Practical Focus**: Working code examples prioritized over theoretical explanations. +- **Documentation-Driven**: Official Flow, Cadence, FCL docs referenced first. +- **Iterative Methodology**: Fix one issue at a time, test frequently. +- **Standard Compliance**: Established patterns preferred over custom solutions. +- **Root Cause Analysis**: Address underlying issues, not just symptoms. +- **Prevention-Oriented**: Include brief explanations of why errors occurred. +- **Full-Stack Consideration**: Account for contracts, transactions, FCL, and UI implications. -#### Configuration Recommendation +#### Configuration recommendation **Best Setup**: Configure as **"Always"** rule or add to **User Rules** in Cursor Settings for global application across all your Flow development work. @@ -519,8 +528,8 @@ You discovered five specialized Cursor Rules designed specifically for Cadence a Now that you have completed this guide, you should be able to: - Configure and use Cursor Rules to enhance AI assistance for Flow blockchain development -- Apply specialized Cadence syntax patterns and NFT development standards through persistent AI context -- Utilize workflow-based rules to guide project setup, deployment, and debugging processes across the Flow development lifecycle +- Apply specialized Cadence syntax patterns and NFT development standards through persistent AI context +- Utilize workflow-based rules to guide project setup, deployment, and debugging processes across the Flow development lifecycle diff --git a/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/flow-data-sources.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/flow-data-sources.md new file mode 100644 index 0000000000..7c94a4a6e3 --- /dev/null +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/flow-data-sources.md @@ -0,0 +1,169 @@ +--- +title: Flow Data Sources +sidebar_label: Flow Data Sources +sidebar_position: 1 +keywords: + - Flow Data Sources + - AI knowledge base + - Flow documentation + - Cadence documentation + - Flow development + - Flow tools + - Flow AI assistance + - RAG + - Retrieval-Augmented Generation + - comprehensive knowledge base + - Flow ecosystem +--- + +# Flow Data Sources + +Flow Data Sources is a comprehensive repository that automatically aggregates and formats Flow ecosystem content into Markdown files optimized for AI ingestion. This resource serves as a centralized knowledge base for AI tools, chatbots, and RAG (Retrieval-Augmented Generation) pipelines. It contains the most current documentation, examples, and best practices for Flow blockchain development. + +
+ +
+ +## Overview + +The repository contains Python scripts that: + +- Crawl Flow-related documentation sites, GitHub repositories, and discussions. +- Convert HTML content to Markdown format. +- Extract code examples from GitHub repositories. +- Capture community discussions and Q&A content. +- Merge all content into consolidated files for easy consumption. + +Flow Data Sources automatically pulls content from: + +- Official Flow documentation +- Cadence language documentation +- Flow CLI guides +- FCL (Flow Client Library) documentation +- Smart contract examples and tutorials +- Best practices and development patterns +- Community discussions and Q&A content + +## Key features + +- **Daily Updates**: Content is automatically refreshed to ensure the latest information. +- **Structured Format**: All content is converted to Markdown for consistent processing. +- **Comprehensive Coverage**: Includes official documentation, code examples, and community discussions. +- **Optimized for AI**: Designed specifically for AI tools, chatbots, and RAG pipelines. + +## Available files + +The repository provides several merged documentation files optimized for different use cases: + +**Output options:** + +- [All Merged Content]: Complete content +- [Essentials Only]: Streamlined version that only include official documentation and sample codes +- [Cadence Only]: Streamlined version that only includex Cadence related documentation and sample codes + +### All merged documentation + +- **File**: `all_merged.md` +- **Content**: Complete comprehensive documentation that covers all aspects of Flow development. +- **Use Case**: Most comprehensive knowledge base for AI tools and complex development questions. +- **Size**: Very large file - may require powerful systems to process. +- **Documentation**: [All Merged Content] + +### Essentials merged documentation + +- **File**: `essentials_merged.md` +- **Content**: Core Flow and Cadence development essentials. +- **Use Case**: Lighter alternative for systems with resource constraints. +- **Size**: Smaller, more focused content for essential development needs. +- **Documentation**: [Essentials Only] + +### Cadence only documentation + +- **File**: `cadence_docs_merged.md` +- **Content**: Streamlined version that only includes Cadence related documentation and sample codes. +- **Use Case**: Focused on Cadence language development and smart contracts. +- **Size**: Cadence-specific content for specialized development needs. +- **Documentation**: [Cadence Only] + +## How to use + +You can integrate Flow Data Sources with: + +- **ChatGPT Plugins**: Enhance Q&A capabilities with Flow-specific knowledge. +- **Custom Chatbots**: Power Discord and Telegram bots with accurate Flow information. +- **RAG Systems**: Index content in vector databases for semantic search. +- **Development Tools**: Provide context-aware assistance in IDEs like Cursor. + +## Integration with AI tools + +Flow Data Sources is specifically designed to work seamlessly with various AI development tools: + +### [Cursor Integration] + +To add Flow Data Sources to your Cursor documentation, reference the GitHub URL directly. This provides your AI assistant with up-to-date Flow knowledge. + +### [ChatGPT Custom GPTs] + +Upload the merged documentation files to create specialized Flow development assistants that can answer complex questions about Cadence, Flow CLI, and ecosystem tools. + +### [Claude Code Integration] + +Reference Flow Data Sources in your CLAUDE.md files to ensure persistent, comprehensive Flow knowledge across all development sessions. + +## Key Benefits + +**Always Current**: Automatically updated to reflect the latest Flow ecosystem changes and documentation updates. + +**Comprehensive Coverage**: Includes documentation from all major Flow development tools and resources in one place. + +**AI-Optimized Format**: Structured specifically for optimal AI processing and accurate response generation. + +**Multiple Formats**: Different file sizes to accommodate various system requirements and use cases. + +**Community Driven**: Benefits from contributions across the entire Flow developer ecosystem. + +## Best Practices + +**Choose the Right File**: Use `all_merged.md` for comprehensive coverage or `essentials_merged.md` for lighter integration. + +**Regular Updates**: Since the files are continuously updated, refresh your AI tool's knowledge base periodically. + +**Combine with Live Docs**: Use Flow Data Sources alongside live documentation links for the most complete development assistance. + +**Verify Critical Information**: While highly accurate, always verify critical implementation details against official sources. + +## Accessing the Content + +The merged documentation files are available at: + +- [All Merged Content] +- [Essentials Only] +- [Cadence Only] + +For integration with AI tools like Cursor or ChatGPT, use the appropriate URL as described in the respective tutorials. + +## Get Started + +1. **Identify Your Use Case**: Determine whether you need comprehensive or essential documentation coverage +2. **Choose Your AI Tool**: Select the AI platform you want to integrate with Flow Data Sources +3. **Follow Integration Guides**: Use the specific tutorial for your chosen AI tool (ChatGPT, Gemini, Cursor, Claude Code, and so on.) +4. **Test and Validate**: Ask Flow-specific development questions to verify that the integration works. + +The Flow Data Sources repository represents a powerful resource to enhance AI-assisted Flow development, and provides comprehensive and current knowledge that adapts to the rapidly evolving Flow ecosystem. + + + +[Flow Data Sources Repository]: https://github.com/onflow/Flow-Data-Sources +[All Merged Content]: https://github.com/onflow/Flow-Data-Sources/blob/main/merged_docs/all_merged.md +[Essentials Only]: https://github.com/onflow/Flow-Data-Sources/blob/main/merged_docs/essentials_merged.md +[Cadence Only]: https://github.com/onflow/Flow-Data-Sources/blob/main/merged_docs/cadence_docs_merged.md +[Cursor Integration]: ./indexing-docs.md +[ChatGPT Custom GPTs]: ../llms/chatgpt.md +[Claude Code Integration]: ../llms/claude-code.md \ No newline at end of file diff --git a/docs/tutorials/use-AI-to-build-on-flow/imgs/cursor_rules1.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/imgs/cursor_rules1.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/imgs/cursor_rules1.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/imgs/cursor_rules1.png diff --git a/docs/tutorials/use-AI-to-build-on-flow/imgs/generate_cursor_rules.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/imgs/generate_cursor_rules.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/imgs/generate_cursor_rules.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/imgs/generate_cursor_rules.png diff --git a/docs/tutorials/use-AI-to-build-on-flow/cursor/images/use-cursor-1.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/imgs/use-cursor-1.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/cursor/images/use-cursor-1.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/imgs/use-cursor-1.png diff --git a/docs/tutorials/use-AI-to-build-on-flow/cursor/images/use-cursor-2.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/imgs/use-cursor-2.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/cursor/images/use-cursor-2.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/imgs/use-cursor-2.png diff --git a/docs/tutorials/use-AI-to-build-on-flow/cursor/images/use-cursor-3.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/imgs/use-cursor-3.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/cursor/images/use-cursor-3.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/imgs/use-cursor-3.png diff --git a/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/index.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/index.md new file mode 100644 index 0000000000..52348941ed --- /dev/null +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/index.md @@ -0,0 +1,82 @@ +--- +title: Use Flow Knowledge Base in Cursor +sidebar_label: Use Cursor AI +sidebar_position: 2 +keywords: + - Cursor + - AI + - Flow documentation + - Cadence documentation + - Flow development + - Flow tools + - Flow IDE + - Flow setup + - Flow configuration + - Flow AI assistance +--- + +# Use Flow knowledge base in Cursor + +[Cursor] is an AI code editor that makes it easy to write code while you build Flow apps. This section provides comprehensive guidance on how to set up and use Cursor with Flow's extensive documentation ecosystem to enhance your development experience. + +To get the most out of Cursor for Flow development, you'll need to understand three key components: + +1. **Flow Data Sources** - The comprehensive knowledge base that powers AI assistance. +2. **Documentation Indexing** - How to make Flow documentation available within Cursor. +3. **Cadence Rules** - Persistent AI context that provides specialized Flow development guidance. + +## [Flow Data Sources] + +Learn about Flow's comprehensive, auto-generated documentation repository that serves as the foundation for AI-assisted development. This resource contains the most current information about Flow, Cadence, and the broader ecosystem, specifically formatted for optimal AI integration. + +The Flow Data Sources guide covers: +- What Flow Data Sources contains and how it's organized. +- Different file formats available for various use cases. +- Integration strategies with AI tools. +- Best practices to leverage this knowledge base. + +## [Indexing Flow Documentation in Cursor] + +Follow the step-by-step process for how to set up Flow documentation within Cursor's AI system. This detailed guide walks you through how to index multiple documentation sources to create a comprehensive Flow development environment. + +The documentation covers how to: +- Add Flow developer documentation to Cursor. +- Integrate Cadence language documentation. +- Include Flow Data Sources for comprehensive coverage. +- Troubleshoot common indexing issues. +- Apply best pratices for indexed documentation. + +## [Cadence Rules] + +Learn how to use Cursor Rules to enhance AI assistance for Cadence and Flow development with persistent context and automated workflows. This comprehensive guide demonstrates how to create specialized rules that transform your AI assistant into a Flow development expert with continuous knowledge of syntax patterns, NFT standards, and project workflows. + +The Cadence Rules guide covers: +- Cursor Rule basics and how they provide persistent AI context. +- Five specialized rules for Flow development: NFT standards, syntax patterns, development workflows, project configuration, and user preferences. +- How to create custom rules for your specific Flow development needs. +- Best practices for rule organization and team collaboration. +- Integration with current Flow development tools and documentation + +## Get started + +1. **Start with Flow Data Sources**: Understand what documentation is available and how it can enhance your development workflow. +2. **Follow the Indexing Guide**: Set up your Cursor environment with comprehensive Flow documentation. +3. **Configure Cadence Rules**: Implement persistent AI context for consistent Flow development assistance. +4. **Practice with Examples**: Use the indexed documentation and rules to build Flow applications with enhanced AI assistance. + +## Best practices for cursor + flow + +- **Use Specific References**: Target `@Flow`, `@Cadence`, or `@Flow Data Sources` based on your needs. +- **Leverage Cursor Rules**: Apply `@cadence-nft-standards`, `@cadence-syntax-patterns`, or other specialized rules for consistent guidance. +- **Combine Sources**: Leverage multiple documentation sources and rules for comprehensive assistance. +- **Verify AI Output**: Cross-reference generated code with official documentation. +- **Stay Updated**: Refresh your documentation indexes and rules periodically for current information. + +This integrated approach combines comprehensive documentation indexing with persistent AI context through Cursor Rules. This provides you with consistent, accurate, and specialized assistance throughout your Flow development process. + + + +[Cursor]: https://www.cursor.com/ +[Flow Data Sources]: ./flow-data-sources.md +[Indexing Flow Documentation in Cursor]: ./indexing-docs.md +[Cadence Rules]: ./cadence-rules.md diff --git a/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/indexing-docs.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/indexing-docs.md new file mode 100644 index 0000000000..f06d0aa810 --- /dev/null +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/cursor/indexing-docs.md @@ -0,0 +1,182 @@ +--- +title: Indexing Flow Documentation in Cursor +sidebar_label: Indexing Documentation +sidebar_position: 2 +keywords: + - Cursor + - AI + - documentation indexing + - Flow documentation + - Cadence documentation + - Flow development + - AI assistance + - Cursor setup +--- + +# Indexing Flow Documentation in Cursor + +[Cursor] is an AI code editor that makes it easy to write code while building Flow apps. To get the most accurate and helpful responses when developing Flow applications, you need to index the relevant Flow documentation within Cursor. This guide walks you through how to set up comprehensive Flow knowledge in your Cursor environment. + +## Prerequisites + +- [Cursor] installed on your system. +- Active internet connection for documentation indexing. +- Cursor Pro subscription (recommended for full documentation access). + +## Documentation sources + +For optimal Flow development assistance, you'll want to index three key documentation sources: + +1. **Flow Developer Documentation** - Official Flow blockchain and tooling documentation. +2. **Cadence Language Documentation** - Complete Cadence programming language reference. +3. **Flow Data Sources** - Comprehensive, auto-generated knowledge base with current practices. + +## Installation steps + +### Step 1: Access documentation settings + +1. Open Cursor and navigate to **Settings** (or press `Cmd/Ctrl + ,`). +2. Go to **Features > Docs**. +3. Click **"+ Add new doc"** to add documentation sources. + +![Cursor Settings](./imgs/use-cursor-1.png) + +### Step 2: Add Flow developer documentation + +1. In the URL field, enter: `https://developers.flow.com/tools` + - **Note**: Use the `/tools` endpoint as it properly indexes all Flow documentation. + - Cursor will automatically detect and crawl the entire Flow documentation site. +2. Set the name as **"Flow"**. +3. Click **"Confirm"** to add the documentation. +4. Wait for the indexing process to complete. + +![Cursor Settings](./imgs/use-cursor-2.png) + +### Step 3: Add Cadence language documentation + +1. Click **"+ Add new doc"** again. +2. Enter the Cadence documentation URL: `https://cadence-lang.org/docs/` +3. Set the name as **"Cadence"**. +4. Click **"Confirm"** to add the documentation. +5. Allow time for indexing to complete. + +### Step 4: Add Flow data sources + +1. Click **"+ Add new doc"** again. +2. Enter the Flow Data Sources URL: `https://github.com/onflow/Flow-Data-Sources/blob/main/merged_docs/all_merged.md` +3. Set the name as **"Flow Data Sources"**. +4. Click **"Confirm"** to add the documentation. + +:::caution + +Resource Requirements + +The Flow Data Sources file is very large and comprehensive. For older development machines or those with limited resources, we recommend you use the [essentials merged file] instead: +`https://github.com/onflow/Flow-Data-Sources/blob/main/merged_docs/essentials_merged.md` + +::: + +### Step 5: Verify indexing + +1. Monitor the indexing progress in the **Docs** section of Cursor settings. +2. Wait for all three documentation sources to show as "Indexed" or "Ready." +3. Indexing time varies, and depends on your internet connection and system performance. + +## Use indexed documentation + +After indexing finishes, you can reference the documentation in your Cursor prompts: + +### Reference syntax + +- `@Flow` - Reference Flow developer documentation. +- `@Cadence` - Reference Cadence language documentation. +- `@Flow Data Sources` - Reference the comprehensive Flow knowledge base. + +![Cursor Settings](./imgs/use-cursor-3.png) + +### Example usage + +``` +@Flow How do I deploy a contract to Flow Testnet? + +@Cadence What's the syntax for how to create a resource in Cadence? + +@Flow Data Sources How do I implement a marketplace for NFTs with royalties? +``` + +## Best practices + +### When to use each source + +- **@Flow**: Use for Flow-specific concepts, tools, CLI commands, network information, and ecosystem questions. +- **@Cadence**: Use for Cadence programming language syntax, features, patterns, and code examples. +- **@Flow Data Sources**: Use for complex questions, advanced patterns, comprehensive tutorials, or when other sources don't provide satisfactory results. + +### Prompt optimization + +- **Be Specific**: Detailed prompts yield more accurate and relevant responses. +- **Combine Sources**: Use multiple references for cross-VM applications (`@Flow` and `@Cadence`). +- **Context Matters**: Include relevant project context in your prompts. +- **Verify Results**: Use documentation to validate AI-generated code and ensure best practices. + +### Example combined usage + +``` +Using @Flow and @Cadence, help me create a transaction that deploys an NFT contract and mints the first token, then show me how to call this from a React app using FCL. +``` + +## Troubleshooting + +### Common issues and solutions + +**Documentation Not Indexed**: +- Verify all URLs are correct and accessible. +- Check your internet connection stability. +- Try to re-add the documentation source. + +**Outdated Information**: +- Remove and re-add sources to refresh documentation. +- Clear Cursor's cache if available in settings. +- Update to the latest version of Cursor. + +**Slow or Failed Indexing**: +- Verify stable internet connection. +- Try to index during off-peak hours. +- For Flow Data Sources, switch to the essentials merged file if needed. + +**Inaccurate AI Responses**: +- Verify the documentation sources are properly indexed. +- Try more specific prompts with clear context. +- Cross-reference responses with official documentation. + +### Get Help + +If you continue to experience issues: + +1. Check the [Cursor documentation] for additional troubleshooting steps. +2. Verify that all documentation URLs are accessible in your browser. +3. Contact Cursor support through their official channels. +4. Consider an alternative documentation sources if specific URLs are problematic. + +## Maintain your setup + +### Regular maintenance + +- **Refresh Periodically**: Re-index documentation monthly to ensure current information. +- **Monitor Updates**: Stay aware of major Flow or Cadence documentation updates. +- **Clean Up**: Remove unused documentation sources to improve performance. + +### Team collaboration + +For development teams: +- Share the same documentation configuration across team members. +- Document your specific setup in your project README. +- Consider creating team-specific documentation sources for internal patterns and practices. + +If you follow this setup guide, you'll have comprehensive Flow and Cadence documentation available directly within Cursor, which allows more accurate AI assistance and faster development workflows. + + + +[Cursor]: https://www.cursor.com/ +[Cursor documentation]: https://docs.cursor.com/ +[essentials merged file]: https://github.com/onflow/Flow-Data-Sources/blob/main/merged_docs/essentials_merged.md \ No newline at end of file diff --git a/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/index.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/index.md new file mode 100644 index 0000000000..45de82ac50 --- /dev/null +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/index.md @@ -0,0 +1,122 @@ +--- +title: Use AI To Build On Flow +description: Learn how to use AI to build on the Flow Blockchain +sidebar_position: 4 +keywords: + - AI + - ChatGPT + - Cursor + - Cursor Rules + - Claude + - AgentKit + - Flow documentation + - Cadence documentation + - Flow development + - Flow tools + - Flow IDE + - Flow setup + - Flow configuration + - Flow AI assistance +--- + +# Use AI To Build On Flow + +Artificial Intelligence (AI) tools can significantly enhance your Flow development experience with intelligent assistance, code generation, and documentation access. This tutorial series will guide you through how to integrate various AI tools with Flow development to boost your productivity and code quality. + +## What You'll Learn + +In this tutorial series, you'll discover how to: + +- Configure AI-powered development environments for Flow. +- Access Flow documentation directly from AI assistants. +- Generate Cadence and Solidity code with AI assistance. +- Debug and troubleshoot Flow applications with AI support. +- Leverage AI for testing and optimization. +- Build AI agents that interact with Flow using AgentKit. + +# AI tutorials for Flow + +## Use Claude Code with Flow + +Master systematic AI-powered Flow development with Claude Code, a terminal-integrated coding assistant designed for iterative blockchain development. This comprehensive guide teaches you to implement a four-stage development methodology (Idea → Visualization → Planning → Build) while you leverage unlimited context windows, subagent capabilities, and persistent project memory. Learn to configure `CLAUDE.md` files for Flow-specific instructions, integrate MCP servers for blockchain interactions, and implement checkpoint-based workflows that ensure reliable smart contract development from emulator to mainnet deployment. + +Tutorial: [Claude Code for Flow Development] + +## Use Cursor with Flow + +This guide details how you can set up the Cursor AI code editor with custom Flow knowledge bases, which transforms it into a specialized assistant to build powerful applications on the Flow network. When you provide the AI with direct access to the official Flow documentation, Cadence language references, and best-practice examples, you unlock a new tier of intelligent assistance that goes far beyond simple autocompletion + +Tutorial: [Use Flow Knowledge Base in Cursor] + +## Use ChatGPT with Flow + +Build your own expert AI assistant and create a custom GPT specifically engineered to master the Flow blockchain and its Cadence smart contract language. This specialized tool will act as your personal pair programmer and provide highly accurate and context-aware answers to your most challenging development questions. By doing this, you don't just use a generic AI, you create a specialist trained on the exact documentation, code patterns, and best practices relevant to your work. + +Tutorial: [Use Flow Knowledge Base in ChatGPT] + +## Flow Data Sources + +Learn about Flow Data Sources, a meticulously curated library designed to autonomously gather and structure information from the entire Flow ecosystem. This project systematically transforms a wide array of content into clean, AI-ready Markdown files, which establishes a unified source of truth. This collection acts as a foundational knowledge base, perfectly suited to power advanced applications such as custom chatbots and sophisticated Retrieval-Augmented Generation (RAG) systems. + +Tutorial: [Data Sources] + +## Eliza integration + +Learn about how to use Eliza on Flow, a versatile framework you can use to construct sophisticated AI agents that communicate with users through natural language. This guide walks you through how to configure and launch an AI agent built with Eliza directly onto the Flow blockchain. You'll discover how to engineer intelligent agents that can comprehend and address user prompts, all while you harness the power of Flow's inherently secure and scalable onchain infrastructure. + +Tutorial: [Eliza on Flow] + +## Build AI agents with AgentKit + +Learn how to build AI agents on Flow with AgentKit, a versatile and modular developer toolkit that is not tied to any single platform. It's engineered to dramatically accelerate the process of building, deploying, and refining AI agents by supplying pre-configured environments and a library of ready-to-use templates. This guide walks you through how to launch your own custom agent on Flow's EVM-compatible testnet, which lets you leverage the powerful combination of the Langchain framework and Anthropic's Claude large language model. + +Tutorial: [Build AI Agents with AgentKit] + +## MCP guides + +Learn how to construct a custom Flow MCP (Model Context Protocol) server or use a current one to empower your AI tools. These tutorials guide you through how to equip your AI applications with the unique capability to directly interact with the Flow blockchain, which allows them to perform onchain operations and access real-time data. + +Tutorial: [Flow MCP] + +## Cadence rules + +Learn how to establish and use Cursor Rules to transform your AI assistant into a dedicated Flow development expert. This process embeds your AI with persistent, foundational knowledge of essential topics, such as proper Cadence syntax, official NFT standards, project-specific configurations, and established development methodologies. + +Tutorial: [Cadence Rules] + +## Best practices + +When you use AI tools with Flow development: + +- Always verify AI-generated code against Flow documentation. +- Use specific prompts that reference Flow concepts and terminology. +- Combine AI assistance with your own knowledge of Flow architecture. +- Keep your AI tools updated with the latest Flow documentation. +- Test AI-generated code thoroughly before you deploy to production. +- Consider the security implications of AI agents that interact with your contracts. + +## Next steps + +After you complete these tutorials, you'll be equipped to leverage AI tools effectively in your Flow development workflow. We recommend that you explore our other tutorial series to deepen your knowledge of Flow development: + +- [Cross-VM Apps][cross-vm-apps] - Build applications that integrate Flow EVM and Cadence. +- [Native VRF][native-vrf] - Implement verifiable random functions in your applications. +- [Token Launch][token-launch] - Create and launch tokens on Flow. + +## Conclusion + +Flow is the ideal platform for AI-enhanced blockchain development. The combination of Cadence's resource-oriented programming model, comprehensive AI ingestable documentation, and growing AI tooling support creates an unparalleled development experience. With tools like AgentKit, MCP servers, and AI-powered development environments, developers can build consumer applications faster than ever. This is why many believe that Flow is the best Blockchain to build on with AI. + + + +[Claude Code for Flow Development]: ./llms/claude-code.md +[Use Flow Knowledge Base in Cursor]: ./cursor/index.md +[Use Flow Knowledge Base in ChatGPT]: ./llms/chatgpt.md +[Data Sources]: ./cursor/flow-data-sources.md +[Eliza on Flow]: ./agents/eliza/index.md +[Build AI Agents with AgentKit]: ./agents/agentkit-flow-guide.md +[cross-vm-apps]: ../cross-vm-apps/introduction.md +[native-vrf]: ../native-vrf/index.md +[token-launch]: ../tokens/index.md +[Flow MCP]: ./mcp/index.md +[Cadence Rules]: ./cursor/cadence-rules.md diff --git a/docs/tutorials/use-AI-to-build-on-flow/chatgpt/index.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/chatgpt.md similarity index 71% rename from docs/tutorials/use-AI-to-build-on-flow/chatgpt/index.md rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/chatgpt.md index ba8e630d05..65a52959d5 100644 --- a/docs/tutorials/use-AI-to-build-on-flow/chatgpt/index.md +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/chatgpt.md @@ -1,7 +1,7 @@ --- title: Use Flow Knowledge Base in ChatGPT sidebar_label: Use ChatGPT -sidebar_position: 2 +sidebar_position: 1 keywords: - ChatGPT - AI @@ -18,9 +18,9 @@ keywords: # Use Flow Knowledge Base in ChatGPT -[ChatGPT] is an AI assistant developed by [OpenAI] that can help with tasks such as writing, coding, and answering questions. It adapts to context and user input to provide relevant, conversational responses. ChatGPT can be integrated into developer tools or workflows to assist with documentation, debugging, and productivity. +[ChatGPT] is an AI assistant developed by [OpenAI] that can help with tasks such as writing, coding, and answering questions. It adapts to context and user input to provide relevant, conversational responses. You can integrate ChatGPT into developer tools or workflows to assist with documentation, debugging, and productivity. -This guide walks you through creating a **Custom GPT** using ChatGPT that can reference the [Flow Data Sources] file to answer questions. +This guide walks you through how to create a **Custom GPT** with ChatGPT that can reference the [Flow Data Sources] file to answer questions.
+
+ +[Claude Code] (Claude) provides an AI-powered coding assistant specifically designed for iterative, systematic development, which transforms the development experience. Unlike general-purpose AI tools, Claude breaks down tasks into manageable, incremental steps while it maintains context across your entire development lifecycle. + +What makes Claude exceptionally powerful is it can maintain unlimited context windows, which allows it to understand entire codebases without the compression limitations that plague other AI coding tools. This comprehensive knowledge allows Claude to deploy multiple subagent instances that work in parallel on complex tasks, iterate continuously until optimal solutions are achieved, and maintain persistent memory of your project's architecture and coding standards across all development sessions. + +## Learning objectives + +After you complete this guide, you'll be able to: + +- Set up and configure Claude for optimal Flow blockchain development workflows. +- Implement the four-stage development methodology (Idea → Visualization → Planning → Build) for Cadence projects. +- Configure persistent project context with `CLAUDE.md` files with Flow-specific instructions and MCP tools. +- Apply iterative development practices with git-based checkpoint systems for safe blockchain development. +- Use advanced Claude features such subagents, auto-verification, and specialized debugging workflows. +- Integrate Claude with Flow CLI, FCL, and other Flow development tools for comprehensive project management. +- Create and manage team-wide development standards through shared `CLAUDE.md` configurations. + +## Prerequisites + +Before you proceed with this guide, you should have: + +### Technical requirements + +- [Claude Code Subscription]: $200/month plan recommended for comprehensive Flow development features. +- [Flow CLI]: Installed and configured for emulator, testnet, and mainnet interactions. +- [Git]: Version control system for checkpoint-based development workflow. +- [Node.js]: For Claude, FCL integration, and frontend development components. + +## Claude setup and configuration + +### What is Claude? + +Claude is an AI-powered code assitant that integrated directly into your terminal. This allows you to use it in any integrated development environment (IDE) or simply from your terminal. The power of Claude comes from its ability to explain complex and large codebases, manage Git workflows, and iterate for long periods of time to accomplish a task. + +Most IDEs like Cursor rely on their ability to compress the context window that is fed to agents so that their business model justifies a $20 charge while they use expensive LLM models. This naturally decreases the ability of the agents to have a comprehensive understanding of the working codebase when they manage with large or complex codebases. + +This is why Claude can be so powerful, because it can include entire codebases in its context, deploy other instances of Claude to work on multiple actions in parallel, and iterate on its results in order to achieve better results. + +### Installation and subscription + +Claude requires a [subscription] to access its full development capabilities. There are three subscription levels: Pro, Max 5x, and Max 20x. + +The Pro plan is very limited, so expect it to only be sufficient for testing and experimentation. + +The $200/month Max 20x plan is recommended for developers with a lot of projects or if you need to build something quickly where time is crucial. This plan grants you access to: + +- Unlimited context windows for complex smart contract projects. +- Advanced subagent capabilities for parallel development tasks. +- Persistent memory across development sessions. +- Integration with MCP (Model Context Protocol) servers. +- Team collaboration features through shared configurations. + +You can also use the API pricing, but we don't recommend it, since any meaningful implementation of Claude most likely requires more than $100 in API credits. + +### Initial configuration + +To install Claude, run the following command: + +```bash +npm install -g @anthropic-ai/claude-code +``` + +After the installation process completes, navigate to your project and start Claude: + +```bash +cd your-awesome-project +claude +``` + +This automatically installs the extension. Run the `/ide` command in the Claude terminal to make sure your IDE is connected to Claude. With the extension installed, click on the orange Anthropic logo on the upper right hand of the screen in order to launch Claude in a separate window. + +![Claude Code Extension](./imgs/CC_logo.png) + + +### CLAUDE.md files + +`CLAUDE.md` files are configuration files that contain project-specific instructions and context for Claude. They allow you to define development standards, frequently used commands, and project architecture that the AI remembers across all coding sessions. They are similar to Cursor Rules, but they differ in that `CLAUDE.md` only specifies the configuration of Claude. + +If you know what type of information to place in your `CLAUDE.md` file, create your primary `CLAUDE.md` file in the project root. Use the `/init` command in Claude to generate the initial structure, then customize for Flow development: + +Create your Flow project with the standard directory structure: + +``` +flow-project/ +├── .claude/ +│ └── CLAUDE.md # Project-wide AI instructions +├── cadence/ +│ ├── .claude/ +│ │ └── CLAUDE.md # Cadence-specific instructions +│ ├── contracts/ +│ ├── transactions/ +│ └── scripts/ +├── frontend/ +│ ├── .claude/ +│ │ └── CLAUDE.md # Frontend-specific instructions +│ └── src/ +├── flow.json # Flow project configuration +└── package.json +``` + +#### 3. Root CLAUDE.md configuration + +Place `CLAUDE.md` in the root file sets the instructions you want Claude to do frequently, such as: + +- Bash commands you want to run frequently. +- Files it should really know about when it makes changes or big architectural decisions. +- MCP servers. + +This file is great to share across your team so you set it once and everyone has the same extended functionality. + +**Team Configuration Setup**: + +```md + +# Flow Project AI assistant configuration + +## Project overview + +This is a Flow blockchain application with Cadence smart contracts and FCL frontend integration. + +## Team-wide development standards + +- MCP servers standardized across development environments. +- Git workflow and commit message standards enforced. +- Follow official Flow documentation patterns. +- Use incremental, checkpoint-based development. +- Test on emulator before testnet deployment. +- Implement proper resource handling with @ and & syntax +- Follow MetadataViews standards for NFT projects. + +## Frequently used commands + +- `flow emulator start` - Start local development environment. +- `flow project deploy --network emulator` - Deploy contracts locally. +- `flow transactions send ./cadence/transactions/example.cdc --network emulator` - Execute transactions locally. +- `npm run dev` - Start frontend development server. + +## Key files to reference + +- `flow.json` - Project configuration and contract deployments. +- `cadence/contracts/` - Smart contract implementations. +- `frontend/src/config.js` - FCL configuration and contract addresses. + +## MCP servers + +- Use flow-mcp to read blockchain data, manage accounts, check balances, and interact with native contracts. +- Use flow-defi-mcp to check token prices, swap tokens on decentralized exchanges, and interact with ERC20 tokens. + +## Architecture notes + +Document your specific project architecture, contract relationships, and deployment strategies +``` + +#### 3. Nested CLAUDE.md files + +To maintain a more granular control of the capabilities of Claude when you work with different areas of your repo, you can create specialized instructions for different project areas. To do this, place a nested `CLAUDE.md` file in subdirectories in your repo(cadence, frontend, backend, and so on). Claude will automatically read these files when working on these subdirectories. Here is an example: + +**cadence/.claude/CLAUDE.md:** + +```md +# Cadence development instructions + +## Syntax requirements + +- Always use proper resource syntax: @{NonFungibleToken.NFT} +- Implement required interfaces: NonFungibleToken, MetadataViews. +- Use view functions for read-only operations. +- Follow auth capability patterns for transactions. + +## Testing protocol + +- Write unit tests for all contract functions. +- Test resource creation and destruction. +- Verify proper event emission. +- Validate access controls and permissions. +- Test for breaking changes and edge cases. + +## Standard patterns + +Reference the Flow documentation for: + +- Contract deployment and initialization. +- Resource collection patterns. +- Proper error handling and panics. +- Gas optimization techniques. +``` + +**frontend/.claude/CLAUDE.md:** + +```markdown +# Frontend FCL integration instructions + +## Configuration management + +- Keep contract addresses in environment variables. +- Use proper network switching logic. +- Implement user authentication flows. +- Handle transaction status updates. + +## Best practices + +- Show loading states for blockchain interactions. +- Provide clear error messages for failed transactions. +- Cache contract data when appropriate. +``` + +#### Local Claude.md + +You can also create a `CLAUDE.local.md` file that is used just for you and not shared with your team. + +## Workflow strategies + +Claude excels when it follows a structured development approach. We recommend you implement this four-stage methodology: + +### Stage 1: Idea development + +**Objective**: Bounce ideas with Claude to better understand of what you can build and why it would work. + +**Process**: + +1. Click `Shift` + `Tab` to cycle through the different response forms that Claude offers until you reach the Plan Mode. + +![Plan Mode](./imgs/plan_mode.png) + +2. Describe your Flow project concept to Claude. +3. Ask for requirement analysis and technical feasibility assessment. + +**Example conversation**: +``` +User: "I want to create a collectible card game on Flow where players can battle and evolve their cards" + +Claude Response: [Analyzes requirements, suggests NFT architecture, identifies game mechanics, proposes contract structure] +``` + +**Outputs**: +- Detailed project requirements document. +- Technical architecture overview. +- Flow-specific implementation considerations. +- Resource and timeline estimates. + +### Stage 2: Visualization + +**Objective**: Create visual representations and demos to validate project concepts before development. You can use Claude with this process, but it is best to combine LLM models like Gemini 2.5 in order to create the visual representations. + +**Tools and techniques**: + +- **Mermaid Diagrams**: Generate contract relationship diagrams, user flow charts, and system architecture visuals. +- **UI Mockups**: Create interface mockups for frontend applications. +- **Contract Schemas**: Visualize data structures and resource relationships. +- **Transaction Flow Maps**: Diagram user interactions and blockchain state changes. + +**Example workflow**: +``` +User: "Create a diagram showing how card evolution works in my game" + +[Claude generates Mermaid diagram showing contract interactions, resource transformations, and event emissions] +``` + +**Claude code commands**: + +- Use image upload to share visual concepts. +- Request Mermaid diagrams for complex systems. +- Ask for UI mockups based on Flow wallet integration patterns. + +### Stage 3: Planning with Claude code + +**Objective**: Break down the project into manageable, incremental development tasks with Claude's planning capabilities. + +**Planning process**: + +1. **Turn On Planning Mode**: Explicitly tell Claude you're in planning phase or cycle through the different modes (with `Shift` + `Tab`) until you reach Plan Mode. +2. **Confirm Knowledge Comprehension**: Ask Claude to read important files first and then confirm the knowledge with you. Immediately ask it questions about the codebase to verify its knowledge. +3. **Plan Generation**: Tell Claude to generate an action plan that is incremental and has specific goals and checkpoints (this file can be called `T0-DO.md` and placed in a `/tasks` folder that contains relevant information about the completion of specific tasks or steps). +4. **Task Breakdown**: Request comprehensive task decomposition for incremental changes. +5. **Dependency Mapping**: Identify task dependencies and critical path. +6. **Checkpoint Strategy**: Define git commit points and testing milestones. + +**Example planning session**: +``` +User: "Set up a roadmap and plan of the to-do's that need to be completed for my card game NFT contracts" + +Claude Response: +Task 1: Set up basic NFT contract structure +- Implement NonFungibleToken interface +- Add MetadataViews compatibility +- Create basic card resource +- Write deployment transaction +- Checkpoint: Basic NFT functionality + +Task 2: Add game mechanics +- Implement battle system +- Add evolution functionality +- Create game state management +- Write game transaction scripts +- Checkpoint: Core game mechanics + +[Continues with detailed breakdown] +``` + +**Plan outputs**: + +- Generate a detailed to-do list that is thoroughly divided between goals, objectives, checkpoints and tasks that need to be achieved in an incremental manner. +- Dependency graph showing task relationships. +- Test strategies for each development phase. +- Deployment sequence and validation protocols. + +A downside of Claude is that it doesn't have a checkpoint control like the agent chat does in Cursor. If you make frequent git commits and work on separate branches, it can help mitigate this. Never attempt to give Claude a big task as it most likely doesn't have enough knowledge about the task at hand to complete it successfully. + +### Stage 4: Build execution + +**Objective**: Implement planned tasks systematically with Claude's development capabilities. + +**Build process**: + +1. **Task Assignment**: Work on one incremental task at a time. +2. **Implementation**: Use Claude to generate code, debug issues, and optimize solutions. +3. **Reporting**: After it completes a task, Claude generates a report of what it did and why it did it in a `.md` file in the `/tasks` folder so that you can have better understand the changes made. +3. **Validation**: Test each component thoroughly before you proceed. +4. **Documentation**: Generate inline documentation and update project docs. +5. **Checkpoint**: Commit working code with descriptive messages. +6. **Updating**: Ask Claude to update the `TO-DO.md` with the completed steps and changes after the commit is approved. + +**Development workflow**: +``` +User: "Implement Task 1: Basic NFT contract structure" + +[Claude generates contract code, deployment scripts, and tests] + +User: "Test this implementation" + +[Claude provides testing commands and validation scripts] + +User: "Commit this checkpoint" + +[Claude suggests commit message and validates completion] +``` + +## Advanced Claude features + +### Subagent utilization + +For complex Flow projects, leverage Claude's subagent capabilities to handle parallel development tasks: + +**When to use subagents**: + +- To develop multiple contracts simultaneously. +- Frontend and backend development in parallel. +- To test different implementation approaches. +- Documentation generation while coding. +- To deal with a big task so that Claude can deploy subagents to break down the task into smaller components that are running in parallel. + +**Example subagent usage**: +``` +User: "Create subagents to develop the NFT contract and the marketplace contract in parallel" + +[Claude spawns separate conversation threads for each contract, which maintains coordination between them.] +``` + +### Auto-verification and iteration + +Configure Claude to automatically verify its work and iterate for improvements: + +**Verification patterns**: + +- **Compilation Checks**: Automatically test Cadence syntax after code generation. +- **Test Execution**: Run unit tests and integration tests after implementation. +- **Deployment Validation**: Verify contract deployment on emulator before you suggest testnet deployment. + +### Memory and context management + +**Use the # memory mode**: +Press `#` to enter memory mode and specify important information for Claude to remember: + +``` +# Remember that this project uses a modular NFT architecture with separate traits contracts. +# Remember that we need to use a DS Proxy system for contract upgrades. +``` + +**Context optimization**: + +- Use `Ctrl+R` for verbose output when you debug complex issues. +- Compact conversations at natural breakpoints (around 20% context usage). +- Constantly refactor `CLAUDE.md` to take into accounts changes made throughout the development process. +- Maintain focused conversations for specific development tasks. + +## Development workflows and best practices + +Give Claude some sort of tool it can use for feedback (MCP or tool) to check its work and it will iterate by itself to get better results. Claude can iterate for hours if needed, but it needs to be able to analyze its work. These alternative workflows can be very useful as well, but they depend on your ability to close the feedback loop so that Claude can analyze and comprehend the results of its code generation: + +### Test-driven development with Claude + +**Workflow**: Write Tests → Commit → Code → Iterate → Commit + +``` +User: "Write tests for card evolution functionality first" + +[Claude generates comprehensive test suite] + +User: "Now implement the evolution logic to pass these tests" + +[Claude implements feature with test-driven approach] +``` + +### Screenshot-driven development + +**Workflow**: Write Code → Screenshot Result → Iterate + +Particularly useful for frontend development: + +``` +User: "Implement this card display component" + +[Claude generates React component] + +User: [Uploads screenshot of result] + +Claude: "I see the card layout needs improvement. Let me adjust the CSS..." +``` + +### Checkpoint-based development + +**Best practices**: + +- Commit after each completed task. +- Use descriptive commit messages that Claude generates. +- Create branches for experimental features. +- Tag stable releases for easy rollback. + +**Example checkpoint strategy**: + +``` +git commit -m "feat: implement basic NFT contract with MetadataViews + +- Add NonFungibleToken interface implementation +- Include required MetadataViews for marketplace compatibility +- Create basic card resource with metadata +- Add deployment transaction and initialization script +- All tests passing on emulator + +Checkpoint: Basic NFT functionality complete" +``` + +### Error resolution and debugging + +**Systematic debugging approach**: + +1. **Error Analysis**: Provide Claude with complete error messages and context. +2. **Root Cause Investigation**: Let Claude analyze potential causes. +3. **Solution Implementation**: Apply suggested fixes incrementally. +4. **Verification**: Test fixes thoroughly before you proceed. +5. **Documentation**: Update project documentation with lessons learned. + +**Example debugging session**: + +``` +User: "Getting authorization error in my transaction" + +Claude: "Let me analyze the auth capability requirements. I see the issue is with the granular auth pattern. Here's the fix..." + +[Provides corrected transaction with proper auth syntax] +``` + +### Multi-network deployment + +**Deployment workflow with Claude**: + +1. **Emulator Testing**: Comprehensive local testing and validation. +2. **Configuration Update**: Update flow.json and FCL config for testnet. +3. **Testnet Deployment**: Deploy and validate on testnet. +4. **Frontend Integration**: Update frontend configuration and test user flows. +5. **Mainnet Preparation**: Final validation and deployment to mainnet. + + +### MCP server share + +You can set up [MCPs] for Claude to use as tools. These can also be set up in the `CLAUDE.md` file so that every team member consistently uses the same MCPs. Share the `/Claude/mcp.json` files so that the team can use the same MCP servers. + +**Team MCP configuration**: + +To grant Claude Code [access to use an MCP server], run the following commands: + +```bash +# Adding a MCP server +claude mcp add [args...] + +# Adding a local server +claude mcp add my-server -e API_KEY=123 -- /path/to/server arg1 arg2 +``` +You can also try these [MCPs for Flow development]: + +```bash +# Shared MCP servers for team consistency +claude mcp add flow_mcp +claude mcp add flow-defi-mcp +``` + +### Version control for AI configuration + +**Best practices**: + +- Include `CLAUDE.md` files in version control. +- Document MCP server configurations in README. +- Share `CLAUDE.local.md` patterns (and don't commit personal configs). +- Maintain team coding standards through shared AI instructions. + +## Key bindings and shortcuts + +### Essential Claude shortcuts + +| Shortcut | Function | Flow Development Usage | +|-------------|-------------------|------------------------| +| `#` | Memory mode | Store project architecture decisions | +| `Shift+Tab` | Auto-accept edits | Quickly accept generated Cadence code | +| `!` | Bash mode | Execute Flow CLI commands directly | +| `@` | Add file/folder | Reference contracts, transactions, configs | +| `Esc` | Cancel operation | Stop incorrect generation and execution | +| `Ctrl+R` | Verbose output | Detailed debugging for complex issues | + +### Flow-specific usage patterns + +**Memory mode examples**: + +``` +# This project follows the composite NFT pattern with separate trait contracts. +# Gas optimization is critical - avoid loops in public functions. +# All contracts must support MetadataViews for marketplace compatibility. +``` + +**File reference patterns**: + +``` +@flow.json - Project configuration +@cadence/contracts/MyNFT.cdc - Main NFT contract +``` + +## Troubleshooting and optimization + +### Common issues and solutions + +**Context window management**: + +- Compact conversations at natural breakpoints or manually when around 20% of context usage remains. +- Use focused sub-conversations for specific tasks. +- Reference key files rather than copying entire contents. + +**Performance optimization**: + +- Use the $200/month plan for complex Flow projects. +- Turn on auto-compact to prevent context overflow. +- Break large tasks into smaller, focused conversations. +- Hit `Esc` often if you see the agent on the wrong path and ask it to undo its recent action. + +**Integration problems**: + +- Verify MCP server configurations. +- Check Flow CLI integration and permissions. +- Validate `CLAUDE.md` file syntax and structure. + +### Best practices for Flow development + +**Project management**: + +- Maintain clear separation between contracts, transactions, and frontend code. +- Use nested `CLAUDE.md` files for different development areas. +- Keep project documentation synchronized with implementation. + +**Code quality**: + +- Always compile Cadence code before deployment. +- Use Claude for security review suggestions. +- Implement comprehensive testing at each development stage. + +**Deployment management**: + +- Test thoroughly on emulator before testnet deployment. +- Validate FCL configuration changes across networks. +- Use systematic deployment checklists that Claude generates. + +## Conclusion + +In this guide, you explored how to leverage Claude for efficient Flow blockchain and Cadence development. You learned to implement a systematic four-stage development methodology that transforms ideas into production-ready applications through AI-assisted visualization, planning, and execution. + +You discovered how to configure persistent project context through `CLAUDE.md` files, allowing your AI assistant to maintain comprehensive understanding of Flow-specific patterns, project architecture, and team standards across all development sessions. The integration of specialized tools like Flow CLI, FCL configuration management, and MCP servers creates a comprehensive development environment optimized for blockchain application building. + +The systematic approaches covered - from test-driven development and checkpoint-based workflows to subagent utilization and auto-verification - provide a foundation for building complex Flow applications with confidence and efficiency. The emphasis on incremental development, comprehensive testing, and systematic deployment ensures your projects meet the reliability requirements essential for blockchain applications. + +Now that you have completed this guide, you should be able to: + +- Set up and configure Claude for optimal Flow blockchain development workflows with persistent context and specialized tooling. +- Implement the four-stage development methodology (Idea → Visualization → Planning → Build) for systematic Cadence project development. +- Apply advanced Claude features including subagents, auto-verification, and team collaboration patterns for complex Flow applications. +- Integrate Claude seamlessly with Flow CLI, FCL, and other Flow development tools for comprehensive project management across emulator, testnet, and mainnet environments. + +The combination of AI-powered development assistance with Flow's comprehensive toolchain creates an unprecedented opportunity for building sophisticated blockchain applications efficiently and reliably. As you continue developing on Flow, these systematic approaches will help you maintain high code quality while aClaudeelerating your development velocity. + + + + +[Claude Code]: https://docs.anthropic.com/en/docs/claude-code/overview +[Claude Code Subscription]: https://claude.ai/upgrade +[Flow CLI]: https://developers.flow.com/tools/flow-cli +[Git]: https://git-scm.com/downloads +[Node.js]: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm +[subscription]: https://claude.ai/upgrade +[MCPs]: https://docs.anthropic.com/en/docs/claude-code/mcp +[access to use an MCP server]: https://docs.anthropic.com/en/docs/claude-code/mcp +[MCPs for Flow development]: https://github.com/Outblock/flow-mcp-monorepo \ No newline at end of file diff --git a/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/gemini.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/gemini.md new file mode 100644 index 0000000000..629e78d8e0 --- /dev/null +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/gemini.md @@ -0,0 +1,110 @@ +--- +title: Use Flow Knowledge Base in Gemini AI +sidebar_label: Use Gemini AI +sidebar_position: 2 +keywords: + - Gemini AI + - AI + - Google + - Flow documentation + - Cadence documentation + - Flow development + - Flow tools + - Flow IDE + - Flow setup + - Flow configuration + - Flow AI assistance +--- + +# Use Flow Knowledge Base in Gemini AI + +[Gemini AI] is Google's AI assistant that can help with tasks such as writing, coding, and answering questions. It adapts to context and user input to provide relevant, conversational responses. You can integrate Gemini AI into developer workflows to assist with documentation, debugging, and productivity. + +This guide walks you through how to create a **Custom GEM** with Gemini AI that can reference the [Flow Data Sources] file to answer questions. + +:::warning + +You'll need a [Gemini Advanced subscription] to use the **Custom GEM** feature. + +::: + +## Step 1: Access Gem Manager + +1. Log in to [Gemini AI]. +2. In the sidebar on the left, click **Explore Gems**. + +--- + +## Step 2: Create a new Gem + +1. In the **Gem Manager** screen, click **"New Gem"**. + +--- + +## Step 3: Configure your Gem + +Gemini AI will now guide you through how to set up up your custom Gem. Configure the name, description and instructions for your Gem to follow. + +### Suggested configuration + +**Name**: FlowGem + +**Description**: An AI assistant specialized in Flow blockchain development, Cadence smart contracts, and Flow ecosystem tools. + +**Instructions**: + +```text + +You are FlowGem, a specialized AI assistant for Flow blockchain development. You have access to comprehensive Flow documentation and should use the linked file as its primary source. This file changes, so it should reference the live file at least once a day: https://github.com/onflow/Flow-Data-Sources/blob/main/merged_docs/all_merged.md + +Key behaviors: +- Always reference the uploaded Flow documentation when answering questions. +- Provide practical, actionable advice for Flow developers. +- Include relevant code examples when applicable. +- Stay up-to-date with the latest Flow ecosystem developments. +- Be eager to help and imagine you are a knowledgeable Flow developer. + +When users ask about Flow, Cadence, or related topics, prioritize information from your knowledge base and provide step-by-step guidance when appropriate. + +``` + +To further customize your personalized agent, you can provide more files and determine the actions it can do. + +--- + +## Step 4: Upload knowledge base + +1. In the **Knowledge** section, upload the [Flow Data Sources All Merged] file. +2. Configure the Gem to reference this file as its primary knowledge source. + +--- + +## Step 5: Test your Gem + +After you configure the Gem, ask it Flow-related questions to test it: + +- "How do I deploy a smart contract to Flow Testnet?" +- "What's the syntax for Cadence resources?" +- "How do I set up Flow CLI?" + +--- + +## Step 6: Save and deploy + +When you're satisfied with the performance, click **"Create Gem"** to finalize. + +- Your Gem will be available in your Gem Manager. +- You can share it with your team or keep it private. + +--- + +## Conclusion + +You've now created a custom Gem that uses Flow's comprehensive documentation as its knowledge base. Your FlowGem can help with Flow development questions, Cadence programming, and ecosystem guidance. + + + +[Gemini AI]: https://gemini.google.com/ +[Gemini Advanced subscription]: https://gemini.google.com/advanced +[Flow Data Sources]: ../cursor/flow-data-sources.md +[Flow Data Sources All Merged]: https://github.com/onflow/Flow-Data-Sources/blob/main/merged_docs/all_merged.md \ No newline at end of file diff --git a/docs/tutorials/use-AI-to-build-on-flow/imgs/CC_logo.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/imgs/CC_logo.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/imgs/CC_logo.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/imgs/CC_logo.png diff --git a/docs/tutorials/use-AI-to-build-on-flow/chatgpt/create.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/imgs/create.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/chatgpt/create.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/imgs/create.png diff --git a/docs/tutorials/use-AI-to-build-on-flow/chatgpt/explore-gpts.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/imgs/explore-gpts.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/chatgpt/explore-gpts.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/imgs/explore-gpts.png diff --git a/docs/tutorials/use-AI-to-build-on-flow/imgs/plan_mode.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/imgs/plan_mode.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/imgs/plan_mode.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/imgs/plan_mode.png diff --git a/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/index.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/index.md new file mode 100644 index 0000000000..8c02fdc5da --- /dev/null +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/llms/index.md @@ -0,0 +1,44 @@ +--- +title: Large Language Models (LLMs) +description: Learn how to integrate various AI assistants and large language models with Flow development to enhance productivity, code quality, and development workflows. +sidebar_position: 1 +keywords: + - LLMs + - ChatGPT + - Gemini AI + - Claude Code + - AI development + - Flow documentation + - Cadence development + - AI assistance + - Flow blockchain + - Smart contracts +--- + +# Large Language Models (LLMs) + +Large Language Models (LLMs) have revolutionized software development by providing intelligent assistance, code generation, and comprehensive knowledge access. You will learn how to enhance your Flow development experience with these LLMs. Each tutorial demonstrates how to configure specialized AI assistants that understand Flow's unique features, Cadence smart contract development, and the broader Flow ecosystem. + +## [Use Flow Knowledge Base in ChatGPT] + +Learn how to create a Custom GPT with ChatGPT that can reference Flow's comprehensive documentation to answer development questions. This guide walks you through how to set up FlowGPT with OpenAI's platform, configure it with Flow Data Sources, and optimize it for Cadence smart contract development. The tutorial covers the complete GPT creation process, from initial setup through testing and deployment, which allows you to have an AI assistant that understands Flow's architecture, tools, and best practices. + +## [Use Flow Knowledge Base in Gemini AI] + +Discover how to build a Custom GEM using Google's Gemini AI platform that specializes in Flow blockchain development. This tutorial demonstrates how to configure Gemini AI with Flow's documentation as its primary knowledge source, which creates an assistant that can provide practical guidance on Cadence programming, Flow CLI usage, and ecosystem integration. Learn how to set up FlowGem with proper instructions, knowledge base integration, and testing protocols to ensure accurate and helpful responses for your development workflow. + +## [Claude Code for Flow Development] + +Master the comprehensive development approach with Claude Code (Claude) for Flow blockchain applications. This extensive guide covers the four-stage development methodology (Idea → Visualization → Planning → Build), advanced features like subagents and auto-verification, and systematic deployment strategies. Learn how to configure persistent project context through `CLAUDE.md` files, implement checkpoint-based development workflows, and leverage Claude's unlimited context windows for complex Cadence smart contract projects and cross-VM applications. + +--- + +## Conclusion + +These tutorials provide a comprehensive foundation for how to integrate AI assistance into your Flow development workflow. When you leverage ChatGPT's Custom GPTs, Gemini AI's Custom GEMs, and CC's advanced development capabilities, you can significantly enhance your productivity and build on Flow. Each platform offers unique strengths that complement different aspects of blockchain development, from quick documentation queries to comprehensive project management and systematic code generation. + + + +[Use Flow Knowledge Base in ChatGPT]: ./chatgpt.md +[Use Flow Knowledge Base in Gemini AI]: ./gemini.md +[Claude Code for Flow Development]: ./claude-code.md \ No newline at end of file diff --git a/docs/tutorials/use-AI-to-build-on-flow/mcp/contribute-to-mcp.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/contribute-to-mcp.md similarity index 67% rename from docs/tutorials/use-AI-to-build-on-flow/mcp/contribute-to-mcp.md rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/contribute-to-mcp.md index 38191ec6ca..ee3f0a72eb 100644 --- a/docs/tutorials/use-AI-to-build-on-flow/mcp/contribute-to-mcp.md +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/contribute-to-mcp.md @@ -1,7 +1,7 @@ --- title: Contribute to Flow MCP sidebar_label: Contribute to Flow MCP -sidebar_position: 3 +sidebar_position: 2 keywords: - AI - MCP @@ -14,11 +14,11 @@ keywords: # Contribute to Flow MCP -This tutorial will guide you through the process of contributing to the Flow MCP server. The [Model Context Protocol (MCP)] is an open standard developed by Anthropic that enables AI applications to interact seamlessly with external tools, systems, and data sources. +This tutorial will guide you through how to contribute to the Flow MCP server. The [Model Context Protocol (MCP)] is an open standard developed by Anthropic that allows AI applications to interact seamlessly with external tools, systems, and data sources. -## Learning Objectives +## Learning objectives -After completing this tutorial, you should be able to: +After you complete this tutorial, you should be able to: - Set up and build the Flow MCP server development environment. - Create and register a new Action Tool, including schema, handler, and tests. @@ -27,34 +27,34 @@ After completing this tutorial, you should be able to: ## Prerequisites -- [Bun] - the JavaScript runtime -- [Flow MCP server] - the Flow MCP server repository +- [Bun] - the JavaScript runtime. +- [Flow MCP server] - the Flow MCP server repository. ## Installation -1. Fork the [Flow MCP server] repository +1. Fork the [Flow MCP server] repository. -2. Clone the repository +2. Clone the repository: ```bash git clone https://github.com/your-username/flow-mcp.git ``` -3. Install the dependencies +3. Install the dependencies: ```bash bun install ``` -4. Build the project +4. Build the project: ```bash bun build ``` -## Create new Action Tool for Flow MCP +## Create new action tool for Flow MCP -1. Create a new folder in the `src/tools` directory +1. Create a new folder in the `src/tools` directory: ```bash mkdir src/tools/your-tool-name @@ -75,9 +75,9 @@ After completing this tutorial, you should be able to: If you want to add new Cadence files for your new tool, you can add them in the `src/cadence` directory. The `bun` will compile the Cadence files into `String`, so the dedicated Cadence files will help the project to be more organized. - And it is recommended to add a test for your new tool in the `src/tools/your-tool-name/your-tool.test.ts` file. + And we recommended that you add a test for your new tool in the `src/tools/your-tool-name/your-tool.test.ts` file. -3. Add a prompt export in the `src/prompts` directory which is used to ensure MCP client can understand the new tool. You can refer to the existing tools for examples. +3. Add a prompt export in the `src/prompts` directory which is used to confirm that MCP clients can understand the new tool. You can refer to the current tools for examples. 4. Add your new tool to the `src/tools/index.ts` file. @@ -90,7 +90,7 @@ After completing this tutorial, you should be able to: }; ``` -5. Run the test to ensure your new tool works as expected +5. Run the test to confirm your new tool works as expected: ```bash bun test @@ -98,7 +98,7 @@ After completing this tutorial, you should be able to: 6. Commit and push your changes to your forked repository, and create a pull request. -We will review your pull request and merge it if it is ready. +We will review your pull request and merge it if it's ready. [Flow MCP server]: https://github.com/outblock/flow-mcp [Bun]: https://bun.sh/ diff --git a/docs/tutorials/use-AI-to-build-on-flow/mcp/imgs/flow-mcp-enabled.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/imgs/flow-mcp-enabled.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/mcp/imgs/flow-mcp-enabled.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/imgs/flow-mcp-enabled.png diff --git a/docs/tutorials/use-AI-to-build-on-flow/mcp/imgs/mcp-settings-in-curosr.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/imgs/mcp-settings-in-curosr.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/mcp/imgs/mcp-settings-in-curosr.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/imgs/mcp-settings-in-curosr.png diff --git a/docs/tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-1.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-1.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-1.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-1.png diff --git a/docs/tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-2.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-2.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-2.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-2.png diff --git a/docs/tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-3.png b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-3.png similarity index 100% rename from docs/tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-3.png rename to docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/imgs/sample-3.png diff --git a/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/index.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/index.md new file mode 100644 index 0000000000..4f3fa344bd --- /dev/null +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/index.md @@ -0,0 +1,36 @@ +--- +title: Flow MCP +sidebar_label: Flow MCP +sidebar_position: 4 +keywords: + - AI + - MCP + - MCP server + - Flow MCP + - Model Context Protocol + - AI Tools + - Flow AI assistance +--- + +# Flow MCP (Model Context Protocol) + +The Model Context Protocol (MCP) is an open standard that allows AI applications to interact seamlessly with external tools, systems, and data sources. Flow MCP extends this protocol to provide AI tools with direct access to Flow blockchain data, smart contracts, and onchain operations. This integration allows developers to enhance their AI-powered development workflows with real-time blockchain information and automated Flow interactions. + +Flow MCP transforms how developers work with the Flow blockchain. It brings blockchain capabilities directly into AI-powered code editors and development tools, which eliminates the need to switch between different interfaces and allows more efficient, context-aware development experiences. + +## [Use Flow MCP in Cursor] + +Learn how to integrate the Flow MCP server with Cursor to turn on AI-driven blockchain queries directly within your code editor. This tutorial guides you through how to set up Flow MCP in Cursor, which allows the AI to fetch onchain data such as account balances, contract information, and blockchain state without the need to leave your development environment. By the end of this tutorial, you'll be able to ask Cursor's AI to perform Flow blockchain operations, speed up development workflows, and access live blockchain data for enhanced debugging and prototyping. + +## [Contribute to Flow MCP] + +Discover how to create custom Action Tools that add new blockchain interaction capabilities and extend the Flow MCP server. This comprehensive guide walks you through the development process, from how to set up the development environment to how to submit pull requests for new features. Learn to create new tools with proper schemas, handlers, and tests, while you follow Flow MCP's contribution guidelines. This tutorial empowers developers to expand the Flow MCP ecosystem with specialized blockchain tools that benefit the entire Flow developer community. + +## Conclusion + +Flow MCP bridges the gap between AI development tools and blockchain functionality, which allows developers to access Flow's comprehensive blockchain features directly through AI-powered interfaces. Whether you use MCP tools in Cursor or want to contribute new capabilities to the Flow MCP server, these tutorials provide the foundation for you to integrate blockchain operations into your AI-enhanced development workflow. + + + +[Use Flow MCP in Cursor]: ./use-mcp-in-cursor.md +[Contribute to Flow MCP]: ./contribute-to-mcp.md diff --git a/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/use-mcp-in-cursor.md b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/use-mcp-in-cursor.md new file mode 100644 index 0000000000..083e665731 --- /dev/null +++ b/docs/blockchain-development-tutorials/use-AI-to-build-on-flow/mcp/use-mcp-in-cursor.md @@ -0,0 +1,130 @@ +--- +title: Use Flow MCP in Cursor +sidebar_label: Use Flow MCP in Cursor +sidebar_position: 1 +keywords: + - AI + - Cursor + - MCP + - MCP server + - Model Context Protocol + - Flow MCP + - AI Tools + - Flow AI assistance +--- + +# Use Flow MCP in Cursor + +
+ +
+ +When you add Flow MCP to Cursor, it gives you powerful AI-driven tools directly inside your code editor. It allows Cursor's AI to understand, query, and interact with Flow blockchain data and smart contracts through a standard protocol called the Model Context Protocol (MCP). + +Specifically, it lets you: + +- Ask the AI in Cursor to fetch onchain data such as account balances, account information, or contract source code without the need to leave your editor. +- Speed up development when you have AI perform blockchain queries that would normally require manual steps. +- Improve context for AI assistance if you let Cursor to pull real blockchain data when needed. +- Automate routine Flow tasks with tools exposed by the MCP server. +- Prototype and debug faster with direct access to live blockchain information. + +This tutorial will guide you through setting up and using Flow MCP in [Cursor] to enhance your Flow blockchain development experience with AI assistance. + +## Learning objectives + +After you complete this tutorial, you should be able to: + +- Configure Cursor to connect with the Flow MCP server with the MCP protocol. +- Install and launch the Flow MCP server locally through Cursor. +- Identify when Flow MCP tools successfully load and are ready inside Cursor. +- Use Flow MCP tools to retrieve blockchain data such as account balances, account details, and contract source code. +- Troubleshoot common setup and connectivity issues between Cursor and Flow MCP. + +## Prerequisites + +- [Cursor] - the AI code editor. +- [Flow MCP GitHub Repository] - the Flow MCP server repository. + +## Installation + +1. Open Cursor Settings and go to the "MCP" tab. + + ![Cursor Settings](./imgs/mcp-settings-in-curosr.png) + +2. Configure the MCP configuration file in Cursor: + + The MCP configuration file resides at this location based on your operating system: + + - macOS: `~/Library/Application Support/Claude/mcp.json` + - Windows: `%APPDATA%/Claude/mcp.json` + - Linux: `~/.config/Claude/mcp.json` + + Add the following configuration: + + ```json + { + "mcpServers": { + "flow-mcp": { + "command": "npx", + "args": ["-y", "@outblock/flow-mcp"] + } + } + } + ``` + +3. Restart Cursor to load the new MCP configuration. + + You need to wait for the MCP server to start. After it's ready, a green spot appears in the left side of `flow-mcp` server name label, and all tools for Flow MCP display. + + ![Flow MCP server ready](./imgs/flow-mcp-enabled.png) + +## How to use Flow MCP in Cursor + +### Check Flow balance + +![Sample Image 1](./imgs/sample-1.png) + +### View account information + +![Sample Image 2](./imgs/sample-2.png) + +### Get contract source code + +![Sample Image 3](./imgs/sample-3.png) + +## Troubleshoot + +If you encounter any issues: + +1. Ensure the MCP server is properly installed. +2. Verify the configuration file is in the correct location. +3. Check that the paths in the configuration are correct. +4. Try to restart Cursor. +5. Check the console for any error messages. + +## Additional resources + +- [Flow MCP GitHub Repository] +- [Cursor Documentation] +- [Flow Documentation] + +## Support + +For issues or questions: + +- Open an issue on the [Flow MCP GitHub Repository]. +- Join the [Flow Discord] community. + +[Cursor]: https://www.cursor.com/ +[Flow MCP GitHub Repository]: https://github.com/outblock/flow-mcp +[Cursor Documentation]: https://cursor.sh/docs +[Flow Documentation]: https://developers.flow.com/ +[Flow Discord]: https://discord.gg/flow diff --git a/docs/build/advanced-concepts/flix.md b/docs/build/advanced-concepts/flix.md deleted file mode 100644 index c7bc79040f..0000000000 --- a/docs/build/advanced-concepts/flix.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: FLIX (Flow Interaction Templates) -description: Learn about Flow Interaction Templates (FLIX), a standard for creating, auditing, and verifying Flow scripts and transactions with improved security and metadata. -keywords: - - FLIX - - Flow Interaction Templates - - templates - - transactions - - scripts - - smart contracts - - FCL - - interaction templates - - template service -sidebar_position: 3 ---- - -# FLIX (Flow Interaction Templates) - -Flow Interaction Templates is a standard for how contract developers, wallets, users, auditors, and applications can create, audit, and verify the intent, security, and metadata of Flow scripts and transactions, with the goal to improve the understandability and security of authorizing transactions and promote patterns for change resilient composability of applications on Flow. - -Interaction Templates provide a way to use and reuse existing scripts and transactions, as well as to provide more metadata such as a human-readable title and description of what the transaction or script will do, which can be used by the developer as well as the user of the application. - -By using FLIX transactions and scripts, developers don't have to write their own for common operations! - -Read more about the design and purpose of FLIX in the [FLIP](https://github.com/onflow/flips/blob/main/application/20220503-interaction-templates.md) - -## Using FLIX - -Flow makes FLIX available through an API available at flix.flow.com. - -You can query a FLIX API to get an Interaction Template. An example query looks like: https://flix.flow.com/v1/templates?name=transfer-flow - -You can read more about how to query a FLIX API in the documentation available here: [https://github.com/onflow/flow-interaction-template-service](https://github.com/onflow/flow-interaction-template-service) - -:::info - -The FLIX working group is currently working on a protocol to publish FLIX templates on-chain. - -::: - -### Example - -How to integrate FLIX across different developer teams? For this example there are two github repositories. - - (smart contracts) [https://github.com/onflow/hello-world-flix](https://github.com/onflow/hello-world-flix) - - (web development) [https://github.com/onflow/hello-world-web](https://github.com/onflow/hello-world-web) - -The Smart contract developer creates FLIX templates and makes them available in github, these can be versioned. Example is `v0.1.0` release, the templates are available for a specific version. In this example the templates are located at: - - https://github.com/onflow/hello-world-flix/blob/v0.1.0/cadence/templates/ReadHelloWorld.template.json - - https://github.com/onflow/hello-world-flix/blob/v0.1.0/cadence/templates/UpdateHelloWorld.template.json - -Developers can use FLIX templates from the smart contract github to interact with their smart contracts. They simply need the FLIX template URLs to create binding files (TypeScript or JavaScript). One major benefit is the web developers don't need to learn Cadence or copy Cadence to their repository in order to integrate with existing smart contracts. - -TypeScript code generated from templates: -- https://github.com/onflow/hello-world-web/blob/main/app/cadence/readHelloWorld.ts -- https://github.com/onflow/hello-world-web/blob/main/app/cadence/updateHelloWorld.ts - -:::warning - -manually added "@ts-ignore" in generated file because of linting error. 'template' property is typed as "object" when it should also allow strings (url to flix template file). There is current a dev effort that will fix this linting issue. - -::: - -See the `hello-world-web` [README](https://github.com/onflow/hello-world-web/tree/main) for more information on how to generate and execute FLIX templates here [flow-cli flix](../../tools/flow-cli/flix.md) commands - - -### Clients - -There are currently two clients that have integrated with FLIX that you can use: - -**Go client** [https://github.com/onflow/flixkit-go](https://github.com/onflow/flixkit-go) - -**FCL client you** read how to get started [tools/clients/fcl-js/interaction-templates](../../tools/clients/fcl-js/interaction-templates.mdx) - -## (Advanced) Running a FLIX API - -Flow provides an implementation of the Flow interaction template service as an open-source project. If you wish to run your own API, you can find the repository here: [https://github.com/onflow/flow-interaction-template-service](https://github.com/onflow/flow-interaction-template-service) diff --git a/docs/build/advanced-concepts/metadata-views.md b/docs/build/advanced-concepts/metadata-views.md deleted file mode 100644 index a7635e142d..0000000000 --- a/docs/build/advanced-concepts/metadata-views.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: NFT Metadata Views -description: Learn about Flow's standardized way to represent and manage NFT metadata through MetadataViews, enabling consistent metadata interpretation across different platforms and marketplaces. -keywords: - - NFT metadata - - MetadataViews - - NFT standards - - metadata views - - Flow NFT - - ViewResolver - - NFT traits - - NFT royalties - - NFT editions - - contract metadata - - NFT display - - metadata implementation -sidebar_label: NFT Metadata Views ---- - -# NFT Metadata Views on Flow - -`MetadataViews` on Flow offer a standardized way to represent onchain metadata -across different NFTs. Through its integration, developers can ensure -that different platforms and marketplaces can interpret the NFT metadata -in a unified manner. This means that when users visit different websites, -wallets, and marketplaces, -the NFT metadata will be presented in a consistent manner, -ensuring a uniform experience across various platforms. - -:::info - -It is important to understand this document so you can make meaningful decisions -about how to manage your project's metadata as support for metadata views does -not happen by default. Each project has unique metadata and therefore will have to -define how they expose it in unique ways. - -::: - -A view is a standard Cadence struct that represents a specific type of metadata, -such as a [Royalty specification](https://github.com/onflow/flow-nft?tab=readme-ov-file#royalty-view): - -```cadence -access(all) struct Royalty { - /// Where royalties should be paid to - access(all) let receiver: Capability<&{FungibleToken.Receiver}> - - /// The cut of the sale that should be taken for royalties. - access(all) let cut: UFix64 - - /// Optional description of the royalty - access(all) let description: String -} -``` - -or a [rarity description](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L614): - -```cadence -access(all) struct Rarity { - /// The score of the rarity as a number - access(all) let score: UFix64? - - /// The maximum value of score - access(all) let max: UFix64? - - /// The description of the rarity as a string. - access(all) let description: String? -} -``` - -This guide acts as a specification for the correct ways to use each metadata view. -Many of the standard metadata views do not have built-in requirements -for how they are meant to be used, so it is important for developers to understand -the content of this document so third party apps can integrate with their -smart contracts as easily and effectively as possible. - -> If you'd like to follow along while we discuss the concepts below, -> you can do so by referring to -> the [ExampleNFT contract](https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc). -> Additionally, here is the source code for the -> [`ViewResolver` contract](https://github.com/onflow/flow-nft/blob/master/contracts/ViewResolver.cdc) -> and the [`MetadataViews` contract](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc). - -Flowty has also provided [a useful guide](https://docs.flowty.io/developer-docs/) -for how to manage metadata views properly -in order to be compatible with their marketplace. This guide is very useful -because all of their advice is generally good advice for any NFT contract, -regardless of what marketplace it is using. - -## Two Levels of Metadata: An Overview - -Metadata in Cadence is structured at two distinct levels: - -1. **Contract-Level Metadata**: This provides an overarching description - of the entire NFT collection/project. - Any metadata about individual NFTs is not included here. - -2. **NFT-Level Metadata**: Diving deeper, this metadata relates to individual NFTs. - It provides context, describes rarity, and highlights other distinctive attributes - that distinguish one NFT from another within the same collection. - -While these distinct levels describe different aspects of a project, -they both use the same view system for representing the metadata -and the same basic function calls to query the information, -just from different places. - -## Understanding `ViewResolver` and `MetadataViews.Resolver` - -When considering Flow and how it handles metadata for NFTs, -it is crucial to understand two essential interfaces: -`ViewResolver` and `MetadataViews.Resolver`. -[Interfaces](https://cadence-lang.org/docs/language/interfaces) -serve as blueprints for types that specify the required fields and methods -that your contract or [composite type](https://cadence-lang.org/docs/language/composite-types) must adhere to -to be considered a subtype of that interface. -This guarantees that any contract asserting adherence to these interfaces -will possess a consistent set of functionalities -that other applications or contracts can rely on. - -1. **`ViewResolver` for Contract-Level Metadata**: - - This interface ensures that **contracts**, particularly those encapsulating NFT collections, conform to the Metadata Views standard. - - Through the adoption of this interface, contracts can provide dynamic metadata that represents the entirety of the collection. -2. **`MetadataViews.Resolver` (`ViewResolver.Resolver` in Cadence 1.0) for NFT-Level Metadata**: - - Used within **individual NFT resources**, this interface ensures each token adheres to the Metadata standard format. - - It focuses on the distinct attributes of an individual NFT, such as its unique ID, name, description, and other defining characteristics. - -### Core Functions - -Both the `ViewResolver` and `MetadataViews.Resolver` utilize the following core functions: - -### `getViews` Function - -This function provides a list of supported metadata view types, -which can be applied either by the contract (in the case of `ViewResolver`) -or by an individual NFT (in the case of `MetadataViews.Resolver`). - -```cadence -access(all) fun getViews(): [Type] { - return [ - Type(), - Type(), - ... - ] -} -``` - -### `resolveView` Function - -Whether utilized at the contract or NFT level, this function's role -is to deliver the actual metadata associated with a given view type. - -The caller provides the type of the view they want to query as the only argument, -and the view is returned if it exists, and `nil` is returned if it doesn't. - -```cadence -access(all) fun resolveView(_ view: Type): AnyStruct? { - switch view { - case Type(): - ... - ... - } - return nil -} -``` - -As you can see, the return values of `getViews()` can be used as arguments -for `resolveView()` if you want to just iterate through all the views -that an NFT implements. - -## NFT-Level Metadata Implementation - -NFT-level metadata addresses the unique attributes of individual tokens -within a collection. It provides structured information for each NFT, -including its identifier, descriptive elements, royalties, -and other associated metadata. Incorporating this level of detail -ensures consistency and standardization among individual NFTs, -making them interoperable and recognizable across various platforms and marketplaces. - -### Core Properties - -In the code below, an NFT has properties such as -its unique ID, name, description, and others. -When we add the `NonFungibleToken.NFT` and by extension, -the `MetadataViews.Resolver` to our NFT resource, -we are indicating that these variables will adhere to the specifications -outlined in the MetadataViews contract for each of these properties. -This facilitates interoperability within the Flow ecosystem -and assures that the metadata of our NFT can be consistently accessed -and understood by various platforms and services that interact with NFTs. - -```cadence -access(all) resource NFT: NonFungibleToken.NFT { - access(all) let id: UInt64 - access(all) let name: String - access(all) let description: String - access(all) let thumbnail: String - access(self) let royalties: [MetadataViews.Royalty] - access(self) let metadata: {String: AnyStruct} - ... -} -``` - -To make this possible though, it is **vital** that projects -all use the standard metadata views in the same way, so third-party -applications can consume them in standard ways. - -For example, many metadata views have `String`-typed fields. It is difficult -to enforce that these fields are formatted in the correct way, so it is important -for projects to be dilligent about how they use them. Take `Traits` for example, -a commonly misused metadata view: - -```cadence -access(all) struct Trait { - // The name of the trait. Like Background, Eyes, Hair, etc. - access(all) let name: String - ... - ... -} -``` - -The name of the trait should be formatted in a way so that it is easy to display -on a user-facing website. Many projects will use something like CamelCase for -the value, so it looks like "HairColor", which is not pretty on a website. -The correct format for this example would be "Hair Color". -This is just one of many common view uses that projects need to be aware of -to maximize the chance of success for their project. - -## Metadata Views for NFTs - -`MetadataViews` types define how the NFT presents its data. -When invoked, the system knows precisely which view to return, -ensuring that the relevant information is presented consistently across various platforms. -In this section of the document, we will explore each metadata view and describe -how projects should properly use them. - -### Display - -This view provides the bare minimum information about the NFT -suitable for listing or display purposes. When the `Display` type is invoked, -it dynamically assembles the visual and descriptive information -that is typically needed for showcasing the NFT in marketplaces or collections. - -```cadence -case Type(): - return MetadataViews.Display( - name: self.name, - description: self.description, - thumbnail: MetadataViews.HTTPFile( - url: self.thumbnail - ) - ) -``` - -If the thumbnail is a HTTP resource: - -```cadence -thumbnail : MetadataViews.HTTPFile(url: *Please put your url here) -``` - -If the thumbnail is an IPFS resource: - -```cadence -// -thumbnail : MetadataViews.IPFSFile( - cid: thumbnail cid, // Type - path: ipfs path // Type specify path if the cid is a folder hash, otherwise use nil here -) -``` - -![MetadataViews.Display](display.png 'Display') - -:::info - -Note about SVG files on-chain: SVG field should be sent as `thumbnailURL`, -should be base64 encoded, and should have a dataURI prefix, like so: - -``` -data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InJlZCIvPjwvc3ZnPg== -``` - -::: - -### Editions - -The `Editions` view provides intricate details regarding the particular release of an NFT -within a set of NFTs with the same metadata. -This can include information about the number of copies in an edition, -the specific NFT's sequence number within that edition, or its inclusion in a limited series. -When the `Editions` view is queried, it retrieves this data, -providing collectors with the information they need to comprehend -the rarity and exclusivity of the NFT they are interested in. - -An NFT can also be part of multiple editions, which is why the `Editions` view -can hold any number of `Edition` structs in an array. - -For example, if an NFT is number 11 of 30 of an exclusive edition, -the code to return the `Editions` view would look like this: - -```cadence -case Type(): - let editionInfo = MetadataViews.Edition( - name: "Example NFT Edition", - number: 11, - max: 30 - ) - return MetadataViews.Editions([editionInfo]) -``` - -### Serial Number Metadata - -The `Serial` metadata provides the unique serial number of the NFT, -akin to a serial number on a currency note or a VIN on a car. -This serial number is a fundamental attribute that certifies the individuality -of each NFT and is critical for identification and verification processes. -Serial numbers are expected to be unique among other NFTs from the same project. -Many projects are already using the NFT resource's -[globally unique UUID]([resource's globally unique UUID](https://cadence-lang.org/docs/language/resources#resource-identifier)) -as the ID already, so they will typically also use that as the serial number. - -```cadence -case Type(): - return MetadataViews.Serial(self.uuid) -``` - -### Royalties Metadata - -Royalty information is vital for the sustainable economics of the creators in the NFT space. -[The `Royalties` metadata view](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L295) -defines the specifics of any royalty agreements in place, -including the percentage of sales revenue that will go to the original creator -or other stakeholders on secondary sales. - -Each royalty view contains a fungible token receiver capability where royalties should be paid: - -```cadence -access(all) struct Royalty { - - access(all) let receiver: Capability<&{FungibleToken.Receiver}> - - access(all) let cut: UFix64 -} -``` - -here is an example of how an NFT might return a `Royalties` view: - -```cadence -case Type(): - // Assuming each 'Royalty' in the 'royalties' array has 'cut' and 'description' fields - let royalty = - MetadataViews.Royalty( - // The beneficiary of the royalty: in this case, the contract account - receiver: ExampleNFT.account.capabilities.get<&AnyResource{FungibleToken.Receiver}>(/public/GenericFTReceiver), - // The percentage cut of each sale - cut: 0.05, - // A description of the royalty terms - description: "Royalty payment to the original creator" - ) - } - return MetadataViews.Royalties(detailedRoyalties) -``` - -If someone wants to make a listing for their NFT on a marketplace, -the marketplace can check to see if the royalty receiver -accepts the seller's desired fungible token by calling -the `receiver.getSupportedVaultTypes(): {Type: Bool}` -function via the `receiver` reference: - -```cadence -let royaltyReceiverRef = royalty.receiver.borrow() - ?? panic("Could not borrow a reference to the receiver") -let supportedTypes = receiverRef.getSupportedVaultTypes() -if supportedTypes[**royalty.getType()**] { - // The type is supported, so you can deposit - recieverRef.deposit(<-royalty) -} else { - // if it is not supported, you can do something else, - // like revert, or send the royalty tokens to the seller instead -} -``` - -If the desired type is not supported, the marketplace has a few options. -They could either get the address of the receiver by using the -`receiver.owner.address` field and check to see if the account -has a receiver for the desired token, they could perform the sale without a royalty cut, -or they could abort the sale since the token type isn't accepted by the royalty beneficiary. - -You can see example implementations of royalties in the `ExampleNFT` contract -and the associated transactions and scripts. -NFTs are often sold for a variety of currencies, so the royalty receiver should ideally -be a [fungible token switchboard](https://github.com/onflow/flow-ft?tab=readme-ov-file#fungible-token-switchboard) receiver that forwards any received tokens -to the correct vault in the receiving account. - -#### Important instructions for royalty receivers - -If you plan to set your account as a receiver of royalties, -you'll likely want to be able to accept as many token types as possible. -This is possible with the `FungibleTokenSwitchboard`. -If you initialize a switchboard in your account, it can accept any generic fungible token -and route it to the correct vault in your account. - -Therefore, if you want to receive royalties, you should set up your account with the -[`setup_royalty_account_by_paths.cdc`](https://github.com/onflow/flow-ft/blob/master/transactions/switchboard/setup_royalty_account_by_paths.cdc) transaction. - -This will link generic public path from `MetadataViews.getRoyaltyReceiverPublicPath()` -to the capability paths and types that you provide as arguments. -Then you can use that public path and capability for your royalty receiver. - -### External URL Metadata - -The ExternalURL view returns to an associated webpage URL, -providing additional content or information about the NFT. -This can be a website, social media page, or anything else related to the project -that uses a URL. - -```cadence -case Type(): - return MetadataViews.ExternalURL("".concat(self.id.toString())) -``` - -### Traits Metadata - -The [`Trait`](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L655) view type encapsulates the unique attributes of an NFT, like any visual aspects or category-defining properties. These can be essential for marketplaces that need to sort or filter NFTs based on these characteristics. -By returning trait views as recommended, you can fit the data in the places you want. - -```cadence -access(all) struct Trait { - // The name of the trait. Like Background, Eyes, Hair, etc. - access(all) let name: String - - // The underlying value of the trait - access(all) let value: AnyStruct - - // displayType is used to show some context about what this name and value represent - // for instance, you could set value to a unix timestamp, and specify displayType as "Date" to tell - // platforms to consume this trait as a date and not a number - access(all) let displayType: String? - - // Rarity can also be used directly on an attribute. - // This is optional because not all attributes need to contribute to the NFT's rarity. - access(all) let rarity: Rarity? -``` - -The traits view is extremely important to get right, because many third-party apps -and marketplaces are heavily reliant on it to properly display the entirety of your NFTs. -For example, the names and values of the traits are likely going to be displayed -on a user-facing website, so it is important to return them in a presentable form, such as `First Name`, instead of `first_name` or `firstName`. - -Additionally, limit your `value` field to primitive types like `String`, `Int`, or `Bool`. - -Additionally, the `displayType` is important as well, because it tells websites -how to display the trait properly. Developers should not just default -to `String` or `Integer` for all their display types. -When applicable, the display types to accurately reflect the data that needs to be displayed. - -![MetadataViews.Traits](traits_String.png 'traits_String') - -#### Note: Always prefer wrappers over single views - -When exposing a view that could have multiple occurrences on a single NFT, -such as `Edition`, `Royalty`, `Media` or `Trait` the wrapper view should always be used -(such as `Editions`, `Royalties`, etc), even if there is only a single occurrence. -The wrapper view is always the plural version of the single view name -and can be found below the main view definition in the `MetadataViews` contract. - -When resolving the view, the wrapper view should be the returned value, -instead of returning the single view or just an array of several occurrences of the view. - -```cadence -access(all) fun resolveView(_ view: Type): AnyStruct? { - switch view { - case Type(): - let editionInfo = MetadataViews.Edition(name: "Example NFT Edition", number: self.id, max: nil) - let editionList: [MetadataViews.Edition] = [editionInfo] - // return the wrapped view - return MetadataViews.Editions( - editionList - ) - } -} -``` - -## Contract-Level Metadata Implementation - -Contract-level metadata provides a holistic view of an NFT collection, -capturing overarching attributes and contextual information about the entire set, -rather than specifics of individual tokens. These views describe attributes -at the collection or series level rather than individual NFTs. -These views should still should be queryable via individual NFTs though. -One can accomplish this by just forwarding the call -from the NFT's `resolveView()` method to the contract's `resolveView()` method, like so: - -```cadence -/// this line is in `ExampleNFT.NFT.resolveView()` -case Type(): - return ExampleNFT.getCollectionDisplay(nftType: Type<@ExampleNFT.NFT>()) -``` - -### NFTCollectionData - -This view provides paths and types related to the NFT collection's storage -and access within the smart contract. The information in this view -is critical for understanding how to interact with a collection. - -```cadence -case Type(): - return MetadataViews.NFTCollectionData( - // where should the collection be saved? - storagePath: ExampleNFT.CollectionStoragePath, - // where to borrow public capabilities from? - publicPath: ExampleNFT.CollectionPublicPath, - // Important types for how the collection should be linked - publicCollection: Type<&ExampleNFT.Collection>(), - publicLinkedType: Type<&ExampleNFT.Collection>(), - // function that can be accessed to create an empty collection for the project - createEmptyCollectionFunction: (fun(): @{NonFungibleToken.Collection} { - return <-ExampleNFT.createEmptyCollection(nftType: Type<@ExampleNFT.NFT>()) - }) - ) -``` - -Here, `NFTCollectionData` is specifying several important elements -related to how the collection is stored and accessed on the Flow blockchain. -It provides information on storage paths and access control paths -for both public and private data, as well as linked types -that specify what capabilities are publicly available -(like collection, receiver, or provider interfaces). - -### NFTCollectionDisplay - -This view describes the collection with visual elements and metadata -that are useful for display purposes, such as in a marketplace or gallery. -Many third party apps need this in order to display high-level information -about an NFT project properly. - -```cadence -case Type(): - let media = MetadataViews.Media( - file: MetadataViews.HTTPFile( - url: "" - ), - mediaType: "image/svg+xml" - ) - return MetadataViews.NFTCollectionDisplay( - name: "The Example Collection", - description: "This collection is used as an example to help you develop your next Flow NFT.", - externalURL: MetadataViews.ExternalURL(""), - squareImage: media, - bannerImage: media, - socials: { - "twitter": MetadataViews.ExternalURL("") - } - ) -``` - -In the example above, the `NFTCollectionDisplay` not only offers fundamental metadata -like the collection's name and description but also provides image URLs -for visual representations of the collection (`squareImage` and `bannerImage`) -and external links, including social media profiles. - -![MetadataViews.CollectionDisplay](collectionDisplay.png 'CollectionDisplay') - -### Contract-borrowing Metadata - -With the contract borrowing feature, the [ViewResolver](https://github.com/onflow/flow-nft/blob/master/contracts/ViewResolver.cdc) -interface on contracts can be borrowed directly without needing to import the contract first. -Views can be resolved directly from there. -As an example, you might want to allow your contract -to resolve `NFTCollectionData` and `NFTCollectionDisplay` so that platforms -do not need to find an NFT that belongs to your contract -to get information about how to set up or show your collection. - -```cadence -import ViewResolver from 0xf8d6e0586b0a20c7 -import MetadataViews from 0xf8d6e0586b0a20c7 - -access(all) fun main(addr: Address, name: String): StoragePath? { - let t = Type() - let borrowedContract = getAccount(addr).contracts.borrow<&ViewResolver>(name: name) ?? panic("contract could not be borrowed") - - let view = borrowedContract.resolveView(t) - if view == nil { - return nil - } - - let cd = view! as! MetadataViews.NFTCollectionData - return cd.storagePath -} -``` - -Will Return - -```cadence -{"domain":"storage","identifier":"exampleNFTCollection"} -``` - -## More - -Understanding `MetadataViews` and the core functions associated with it -is crucial for developers aiming to deploy NFTs on Flow. -With these views and functions, NFTs can maintain a consistent presentation -across various platforms and marketplaces and foster interoperability -between contracts and applications in the Flow ecosystem. -To gain a deeper understanding of implementing the MetadataView standard, -check out our documentation on "How to Create an NFT Project on Flow". -It provides an introduction to integrating these standards into your NFT contracts. - -- See the [API reference for a complete list of Metadata functions](https://developers.flow.com/build/core-contracts/flow-nft/MetdataViews/MetadataViews) -- Check out [an Example NFT project](https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc) implementing `MetadataViews` -- Read [the NFT Guide](../guides/nft.md) for an introduction to implementation diff --git a/docs/build/app-architecture/app-custody.png b/docs/build/app-architecture/app-custody.png deleted file mode 100644 index 7dad71fa77..0000000000 Binary files a/docs/build/app-architecture/app-custody.png and /dev/null differ diff --git a/docs/build/app-architecture/index.md b/docs/build/app-architecture/index.md deleted file mode 100644 index fb7a7de7b3..0000000000 --- a/docs/build/app-architecture/index.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -sidebar_position: 5 -title: App Architecture -description: Learn about self-custody and app custody architectural patterns for building applications on Flow blockchain, including their benefits, considerations, and ideal use cases. -keywords: - - app architecture - - self custody - - app custody - - Flow blockchain - - walletless onboarding - - account linking - - dApp architecture - - blockchain architecture - - key management - - user experience - - web3 development -sidebar_custom_props: - icon: 🏗️ ---- - -# App Architecture on Flow Blockchain - -The Flow blockchain, with its focus on scalability and user-centric design, offers a unique environment for app development. Designed from the ground up, Flow prioritizes user experience, aiming to bridge the gap to mainstream adoption without compromising on decentralization or security. - -While the Flow blockchain offers various architectural patterns, the recommended approaches for developers are **Self-Custody** and **App Custody**. These choices align with Flow's ethos of user-centric design and flexibility. - -### Self-Custody Architecture - -In a self-custody architecture, users retain direct control over their private keys and assets. This model emphasizes user sovereignty and decentralization, placing the responsibility of asset management squarely on the user's shoulders. While it offers the highest degree of control, it also demands a certain level of technical knowledge and awareness from the user, which can sometimes lead to a more complex user experience. - -![self-custody.png](self-custody.png) - -**Architectural Elements**: - -- **Wallet**: A wallet where users store their private keys and sign transactions. -- **Frontend**: Interfaces directly with the user and their wallet for signing transactions. -- **Method of Talking to Chain**: Through FCL directly. - -**Benefits**: - -- **Control**: Users maintain full ownership of their assets and transactions. -- **Security**: Direct management of private keys reduces potential points of failure. - -**Considerations**: - -- **User Experience**: The direct control model can lead to a more complex user experience, especially for those unfamiliar with blockchain. Typically, all transactions must be approved by the user, which can be cumbersome. -- **Key Management**: Users are solely responsible for managing, backing up, and ensuring the safe generation and storage of their keys. - -**Ideal Use Cases**: - -- **Decentralized Finance (DeFi)**: Users interacting with financial protocols while maintaining full control. -- **Web3 Native Users**: Those familiar with blockchain technology and key management. - -### App Custody Architecture - -App custody on Flow offers a unique approach to key management and user experience. Unlike traditional app custody solutions on other blockchains, Flow's App Custody architecture introduces features like **[account linking](../guides/account-linking/index.md)** and **[walletless onboarding](../guides/account-linking/child-accounts.md)**. These features ensure that while users enjoy a seamless experience, they still have the option to link their accounts and move their assets freely around the Flow ecosystem, providing a balanced approach to key management. - -![app-custody.png](app-custody.png) - -**Architectural Elements**: - -- **Wallet**: Both user custody and app custody wallets coexist. -- **Frontend**: Interfaces for both wallet types and features for account linking and walletless onboarding. -- **Backend**: Manages app-custody user keys and assets. Also supports direct blockchain interactions. -- **Method of Interacting with the Chain**: Both direct FCL calls and backend-managed interactions. -- **Payment Rails**: Flexible methods, accommodating both direct and managed transactions. - -**Benefits**: - -- **Walletless Onboarding**: Users can start interacting with the app using traditional, familiar web2 mechanics without the initial need for a blockchain wallet. -- **Streamlined Experience**: Transactions can be processed without constant user approval, offering a smoother user journey. -- **Open Ecosystem with Account Linking**: Users can link their accounts, ensuring they can move their assets freely around the Flow ecosystem without being locked into a single application. -- **Flexibility**: Cater to both tech-savvy users and newcomers without compromising on security. -- **Platform Versatility**: The abstraction of the user wallet allows for integration with various platforms, including Unity games, consoles, and mobile applications. - -**Considerations**: - -- **Complexity**: Implementing app custody can be more intricate. -- **Trust**: Users need to trust the dApp with certain aspects of their data and assets. -- **Legal Implications**: Operating with app custody may come with legal considerations, depending on jurisdiction and the nature of the dApp. It's essential to consult with legal professionals to ensure compliance. - -**Ideal Use Cases**: - -- **Gaming**: Seamless gaming without constant transaction approvals. -- **Social Media Platforms**: Earning tokens for content without initial blockchain familiarity. -- **Loyalty Programs**: Earning rewards without deep blockchain setup. - -## Wrapping Up - -Selecting the right architecture is crucial when developing an app on the Flow blockchain. Your choice will influence not only the technical aspects but also the user experience and overall trust in your application. While Flow offers the tools and flexibility to cater to various needs, it's up to developers to harness these capabilities effectively. Whether you opt for a self-custody or app custody approach, ensure that your decision aligns with the core objectives of your app and the expectations of your users. Making informed architectural decisions will lay a strong foundation for your app's success. diff --git a/docs/build/app-architecture/self-custody.png b/docs/build/app-architecture/self-custody.png deleted file mode 100644 index 4233cb11ad..0000000000 Binary files a/docs/build/app-architecture/self-custody.png and /dev/null differ diff --git a/docs/build/basics/_category_.yml b/docs/build/basics/_category_.yml deleted file mode 100644 index 4fcde33299..0000000000 --- a/docs/build/basics/_category_.yml +++ /dev/null @@ -1,2 +0,0 @@ -label: Flow Protocol -position: 4 diff --git a/docs/build/basics/_fees_images/Screenshot_2023-08-17_at_17.16.32.png b/docs/build/basics/_fees_images/Screenshot_2023-08-17_at_17.16.32.png deleted file mode 100644 index c5af964523..0000000000 Binary files a/docs/build/basics/_fees_images/Screenshot_2023-08-17_at_17.16.32.png and /dev/null differ diff --git a/docs/build/basics/accounts.md b/docs/build/basics/accounts.md deleted file mode 100644 index 5fc65604ee..0000000000 --- a/docs/build/basics/accounts.md +++ /dev/null @@ -1,242 +0,0 @@ ---- -sidebar_position: 2 -title: Accounts -description: Learn about Flow blockchain accounts, including their structure, key management, multi-sig capabilities, and creation process. Understand how accounts store contracts, manage storage, and handle transaction signing. -keywords: - - Flow accounts - - blockchain accounts - - account keys - - multi-sig - - public keys - - account storage - - account creation - - keyless accounts - - service accounts - - account address - - account balance - - signature algorithms - - hash algorithms - - account contracts ---- - -:::info - -Are you an EVM developer looking for information about EVM Accounts on Flow? If so, check out the EVM specific documentation [here](../../evm/accounts.md) - -::: - -# Accounts - -An account on Flow is a record in the chain state that holds the following information: -- Address: unique identifier for the account -- Public Keys: public keys authorized on the account -- Code: Cadence contracts deployed to the account -- Storage: area of the account used to store resource assets. - -Accounts and their keys are needed to sign transactions that change the Flow blockchain state. To execute a transaction, a small amount of Flow, called a ["Fee"](./fees.md) must be paid by the account or subsidized by a wallet or service. Flow allocates a fixed amount of storage to each account for saving data structures and Resources. Flow allocates a [fixed amount of storage](./fees.md#storage) to each account for saving data structures and Resources. -An account may also contain contract code which transactions and scripts can interact with to query or mutate the state of the blockchain. - -A simple representation of an account: - -![Screenshot 2023-08-16 at 16.43.07.png](_accounts_images/Screenshot_2023-08-16_at_16.43.07.png) - -## Address - -A Flow address is represented as 16 hex-encoded characters (usually prefixed with `0x` to indicate hex encoding). Unlike Bitcoin and Ethereum, Flow addresses are not derived from cryptographic public keys. Instead, each Flow address is assigned by the Flow protocol using an on-chain deterministic sequence. The sequence uses an error detection code to guarantee that all addresses differ with at least 2 hex characters. This makes typos resulting in accidental loss of assets not possible. - -This decoupling is a unique advantage of Flow, allowing for multiple public keys to be associated with one account, or for a single public key to be used across several accounts. - -## Balance - -Each Flow account created on Mainnet will by default [hold a Flow vault that holds a balance and is part of the FungibleToken standard](./flow-token.md). This balance is used to pay for [transaction fees and storage fees](./fees.md). More on that in the fees document. - -:::warning - -The minimum amount of FLOW an account can have is **0.001**. - -::: - -This minimum storage fee is provided by the account creator and covers the cost of storing up to 100kB of data in perpetuity. This fee is applied only once and can be "topped up" to add additional storage to an account. The minimum account reservation ensures that most accounts won't run out of storage capacity if anyone deposits anything (like an NFT) to the account. - - -### Maximum available balance - -Due to the storage restrictions, there is a maximum available balance that user can withdraw from the wallet. The core contract [`FlowStorageFees`](../core-contracts/05-flow-fees.md#flowstoragefees) provides a function to retrieve that value: - -```cadence -import "FlowStorageFees" - -access(all) fun main(accountAddress: Address): UFix64 { - return FlowStorageFees.defaultTokenAvailableBalance(accountAddress) -} -``` - -Alternatively developers can use `availableBalance` property of the `Account` - -```cadence -access(all) fun main(address: Address): UFix64 { - let acc = getAccount(address) - let balance = acc.availableBalance - - return balance -} - -``` - -## Contracts - -An account can optionally store multiple [Cadence contracts](https://cadence-lang.org/docs/language/contracts). The code is stored as a human-readable UTF-8 encoded string which makes it easy for anyone to inspect the contents. - -## Storage - -Each Flow account has an associated storage and capacity. The account's storage used is the byte size of all the data stored in the account's storage. An account's [storage capacity is directly tied to the balance of Flow tokens](./fees.md#storage) an account has. An account can, without any additional cost, use any amount of storage up to its storage capacity. If a transaction puts an account over storage capacity or drops an account's balance below the minimum 0.001 Flow tokens, that transaction fails and is reverted. - -## Account **Keys** - -Flow accounts can be configured with multiple public keys that are used to control access. Owners of the associated private keys can sign transactions to mutate the account's state. - -During account creation, public keys can be provided which will be used when interacting with the account. Account keys can be added, removed, or revoked by sending a transaction. This is radically different from blockchains like Ethereum where an account is tied to a single public/private key pair. - -Each account key has a weight that determines the signing power it holds. - -:::warning - -A transaction is not authorized to access an account unless it has a total signature weight greater than or equal to **1000**, the weight threshold. - -::: - -For example, an account might contain 3 keys, each with 500 weight: - -![Screenshot 2023-08-16 at 16.28.58.png](_accounts_images/Screenshot_2023-08-16_at_16.28.58.png) - -This represents a 2-of-3 multi-sig quorum, in which a transaction is authorized to access the account if it receives signatures from *at least* 2 out of 3 keys. - -An account key contains the following attributes: - -- **ID** used to identify keys within an account -- **Public Key** raw public key (encoded as bytes) -- **Signature algorithm** (see below) -- **Hash algorithm** (see below) -- **Weight** integer between 0-1000 -- **Revoked** whether the key has been revoked or it's active -- **Sequence Number** is a number that increases with each submitted transaction signed by this key - -### Signature and Hash Algorithms - -The signature and hashing algorithms are used during the transaction signing process and can be set to certain predefined values. - -There are two curves commonly used with the ECDSA algorithm, secp256r1 ([OID 1.2.840.10045.3.1.7](http://oid-info.com/get/1.2.840.10045.3.1.7), also called the "NIST P-256." this curve is common for mobile secure enclave support), and secp256k1 ([OID 1.3.132.0.10](http://oid-info.com/get/1.3.132.0.10), the curve used by "Bitcoin"). Please be sure to double-check which parameters you are using before registering a key, as presenting a key using one of the curves under the code and format of the other will generate an error. - -| Algorithm | Curve | ID | Code | -| --------- | --------- | --------------- | ---- | -| ECDSA | P-256 | ECDSA_P256 | 2 | -| ECDSA | secp256k1 | ECDSA_secp256k1 | 3 | - -*Please note that the codes listed here are for the signature algorithms as used by the node API, and they are different from the ones [defined in Cadence](https://cadence-lang.org/docs/language/crypto#signing-algorithms)* - -| Algorithm | Output Size | ID | Code | -| --------- | ----------- | -------- | ---- | -| SHA-2 | 256 | SHA2_256 | 1 | -| SHA-3 | 256 | SHA3_256 | 3 | - -Both hashing and signature algorithms are compatible with each other, so you can freely choose from the set. - -### **Locked / Keyless Accounts** - -An account on Flow doesn't require keys in order to exist, but this makes the account immutable since no transaction can be signed that can change the account. This can be useful if we want to freeze an account contract code and it elegantly solves the problem of having multiple account types (as that is the case for Ethereum). - -![Screenshot 2023-08-16 at 18.59.10.png](_accounts_images/Screenshot_2023-08-16_at_18.59.10.png) - -You can achieve keyless accounts by either removing an existing public key from an account signing with that same key and repeating that action until an account has no keys left, or you can create a new account that has no keys assigned. With account linking you can also have a child account that has no keys but is controlled by the parent. - -:::danger - -Be careful when removing keys from an existing account, because once an account's total key weights sum to less than 1000, it can no longer be modified. - -::: - -### **Multi-Sig Accounts** - -Creating a multi-signature account is easily done by managing the account keys and their corresponding weight. To repeat, in order to sign a transaction the keys used to sign it must have weights that sum up to at least 1000. Using this information we can easily see how we can achieve the following cases: - -#### 2-of-3 multi-sig quorum - -![Screenshot 2023-08-16 at 19.34.44.png](_accounts_images/Screenshot_2023-08-16_at_19.34.44.png) - -#### 3-of-3 multi-sig quorum - -![Screenshot 2023-08-16 at 19.34.55.png](_accounts_images/Screenshot_2023-08-16_at_19.34.55.png) - -#### 1-of-2 signature - -![Screenshot 2023-08-16 at 19.34.51.png](_accounts_images/Screenshot_2023-08-16_at_19.34.51.png) - -### Key Format - -We are supporting ECDSA with the curves `P-256` and `secp256k1`. For these curves, the public key is encoded into 64 bytes as `X||Y` where `||` is the concatenation operator. - -- `X` is 32 bytes and is the big endian byte encoding of the `x`-coordinate of the public key padded to 32, i.e. `X=x_31||x_30||...||x_0` or `X = x_31*256^31 + ... + x_i*256^i + ... + x_0`. -- `Y` is 32 bytes and is the big endian byte encoding of the `y`-coordinate of the public key padded to 32, i.e. `Y=y_31||y_30||...||y_0` or `Y = y_31*256^31 + ... + y_i*256^i + ... + y_0` - - -## Account Creation - -Accounts are created on the Flow blockchain by calling a special [create account Cadence function](https://cadence-lang.org/docs/language/accounts#account-creation). Once an account is created we can associate a new key with that account. Of course, all that can be done within a single transaction. Keep in mind that there is an account creation fee that needs to be paid. Account creation fees are relatively low, and we expect that wallet providers and exchanges will cover the cost when a user converts fiat to crypto for the first time. - -For development purposes, [you can use Flow CLI to easily create emulator, testnet and mainnet accounts.](../../tools/flow-cli/accounts/create-accounts.md) The account creation fee is paid by a funding wallet so you don't need a pre-existing account to create it. - -### **Key Generation** - -Keys should be generated in a secure manner. Depending on the purpose of the keys different levels of caution need to be taken. - -:::warning - -Anyone obtaining access to a private key can modify the account the key is associated with (assuming it has enough weight). Be very careful how you store the keys. - -::: - -For secure production keys, we suggest using key management services such as [Google key management](https://cloud.google.com/security-key-management) or [Amazon KMS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.Keys.html), which are also supported by our CLI and SDKs. Those services are mostly great when integrated into your application. However, for personal use, you can securely use any [existing wallets](../../ecosystem/wallets.md) as well as a [hardware Ledger wallet](../../ecosystem/wallets.md). - -## Service Accounts - -### Flow Service Account -The Service Account is a special account in Flow that has special permissions to manage system contracts. It is able to mint tokens, set fees, and update network-level contracts. - -### Tokens & Fees -The Service Account has administrator access to the FLOW token smart contract, so it has authorization to mint and burn tokens. It also has access to the transaction fee smart contract and can adjust the fees charged for transactions execution on Flow. - -### Network Management -The Service Account administers other smart contracts that manage various aspects of the Flow network, such as epochs and (in the future) validator staking auctions. - -### Governance -Besides its special permissions, the Service Account is an account like any other in Flow. -The service account is currently controlled by a smart contract governed by the Flow community. -No single entity has the ability to unilaterally execute a transaction -from the service account because it requires four signatures from controlling keys. -The Flow foundation only controls 3 of the keys and the others are controlled -by trusted community members and organizations. - - -## Accounts Retrieval - -You can use the Flow CLI to get account data by running: - -```sh -flow accounts get 0xf919ee77447b7497 -n mainnet -``` - -Find [more about the command in the CLI docs](../../tools/flow-cli/accounts/get-accounts.md). - -Accounts can be obtained from the access node APIs, currently, there are two gRPC and REST APIs. You can find more information about them here: - -**gRPC API** [building-on-flow/nodes/access-api#accounts](../../networks/access-onchain-data/index.md#accounts) - -**REST API** [http-api#tag/Accounts](/http-api#tag/Accounts) - -There are multiple SDKs implementing the above APIs for different languages: - -**Javascript SDK** [tools/clients/fcl-js](../../tools/clients/fcl-js/index.md) - -**Go SDK** [tools/clients/flow-go-sdk](../../tools/clients/flow-go-sdk/index.md) - -Find a list of all SDKs here: [tools/clients](../../tools/clients/index.md) diff --git a/docs/build/basics/blocks.md b/docs/build/basics/blocks.md deleted file mode 100644 index 8110e15154..0000000000 --- a/docs/build/basics/blocks.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -sidebar_position: 1 -title: Blocks -description: Learn about Flow blockchain blocks, their structure, lifecycle, and how they maintain the blockchain's state. Understand block headers, payloads, and the finalization process. -keywords: - - blocks - - blockchain blocks - - block header - - block payload - - block seals - - block finalization - - block status - - consensus - - collection guarantees - - block retrieval - - block ID - - block height - - Flow blockchain - - blockchain state ---- - -# Blocks - -## Overview - -Blocks are entities that make up the Flow blockchain. Each block contains a list of [transactions](./transactions.md) that were executed and as a result, changed the global blockchain state. Each block is identified by a unique ID which is a cryptographic hash of the block contents. Block also includes a link to the parent block ID creating a linked list of blocks called the Flow blockchain. - -The unique block ID serves as proof of the block contents which can be independently validated by any observer. Interesting cryptographic properties of the hash that make up the block ID guarantee that if any change is made to the block data it would produce a different hash and because blocks are linked, a different hash would break the link as it would no longer be referenced in the next block. - -A very basic representation of blocks is: - -![Screenshot 2023-08-16 at 15.16.38.png](_blocks_images/Screenshot_2023-08-16_at_15.16.38.png) - -Blocks are ordered starting from the genesis block 0 up to the latest block. Each block contains an ordered list of transactions. This is how the Flow blockchain preserves the complete history of all the changes made to the state from the beginning to the current state. - -Each block contains more data which is divided into **block header** and **block payload**. There are many representations of block data within the Flow protocol. APIs, node types, and specific components within the node may view a block from differing perspectives. For the purpose of this documentation, we will talk about block data we expose through APIs to the clients. - -![Screenshot 2023-08-16 at 10.50.53.png](_blocks_images/Screenshot_2023-08-16_at_10.50.53.png) - -### Block Header - -The Block header contains the following fields: - -- **ID** represents the block's unique identifier, which is derived from the hashing block header including the payload hash. The algorithm used on Flow to hash the content and get an identifier is SHA3 256. This ID is a commitment to all the values in the block staying the same. -- **Parent ID** is a link to the previous block ID in the list making up the blockchain. -- **Height** is the block sequence number, where block 0 was the first block produced, and each next block increments the value by 1. -- **Timestamp** is the timestamp at which this block was proposed by the consensus node. Depending on your use case this time might not be accurate enough, [read more about measuring time on the Flow blockchain](https://cadence-lang.org/docs/measuring-time#time-on-the-flow-blockchain). -- **Payload Hash** represents the payload hash that is included when producing the ID of the block. Payload hash is calculated by taking Merkle root hashes of collection guarantees, seals, execution receipts, and execution results and hashing them together. More on each of the values in the block payload section. - -### Block Payload - -The block payload contains the following fields: - -- **Collection Guarantees** is a list of collection IDs with the signatures from the collection nodes that produced the collections. This acts as a guarantee by collection nodes that [transaction data](./transactions.md) in the collection will be available on the collection node if requested by other nodes at a later time. Flow purposely skips including transaction data in a block, making blocks as small as possible, and the production of new blocks by consensus nodes fast, that is because consensus nodes have to sync the proposed block between nodes, and that data should be the smallest possible. The consensus nodes don't really care what will a transaction do as long as it's valid, they only need to define an order of those transactions in a block. -- **Block Seals** is the attestation by verification nodes that the transactions in a previously executed block have been verified. This seals a previous block referenced by the block ID. It also references the result ID and execution root hash. It contains signatures of the verification nodes that produced the seal. - -## Lifecycle and Status - -Block status is not a value stored inside the block itself but it represents the lifecycle of a block. We derive this value based on the block inclusion in the Flow blockchain and present it to the user as it acts as an important indicator of the finality of the changes the block contains. - -Here we'll give an overview of the different phases a block goes through. [More details can be found in the whitepaper](https://flow.com/technical-paper). Also, a lot of the block states are not necessarily important to the developer but only important to the functioning of the Flow blockchain. - -New blocks are constantly being proposed even if no new transactions are submitted to the network. Consensus nodes are in charge of producing blocks. They use a consensus algorithm (an implementation of HotStuff) to agree on what the new block will be. A block contains the ordered list of collections and each collection contains an ordered list of transactions. This is an important fact to reiterate. A block serves as a list of transitions to the Flow state machine. It documents, as an ordered list, all the changes transactions will make to the state. - -A block that is [agreed upon by the consensus nodes using an implementation of HotStuff consensus algorithm](https://arxiv.org/pdf/2002.07403.pdf) to be the next block is **finalized**. This means the block won't change anymore and it will next be executed by the execution node. Please be careful because until a block is **sealed** the changes are not to be trusted. After verification nodes validate and agree on the correctness of execution results, a block is sealed and consensus nodes will include these seals in the new block. - -In summary, a block can be either **finalized** which guarantees transactions included in the block will stay the same and will be executed, and **sealed** which means the block execution was verified. - -![Screenshot 2023-08-16 at 10.48.26.png](_blocks_images/Screenshot_2023-08-16_at_10.48.26.png) - -## Block Retrieval - -You can use the Flow CLI to get the block data by running: - -```sh -flow blocks get latest -network mainnet -``` - -Find [more about the command in the CLI docs](../../tools/flow-cli/get-flow-data/get-blocks.md). - -Blocks can be obtained from the access node APIs, currently, there are two gRPC and REST APIs. You can find more information about them here: - -[**gRPC Block API**](../../networks/access-onchain-data/index.md#blocks) - -[**REST Block API**](/http-api#tag/Blocks) - -There are multiple SDKs implementing the above APIs for different languages: - -[**Javascript SDK**](../../tools/clients/fcl-js/index.md) - -[**Go SDK**](../../tools/clients/flow-go-sdk/index.md) - -Find a list of all SDKs [here](../../tools/clients/index.md) diff --git a/docs/build/basics/collections.md b/docs/build/basics/collections.md deleted file mode 100644 index 9ccf6cded9..0000000000 --- a/docs/build/basics/collections.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -sidebar_position: 1 -title: Collections -description: Learn about Flow blockchain collections, how they optimize data transfer by linking blocks and transactions, and their role in the network architecture. Understand how collection nodes create and manage transaction collections. -keywords: - - collections - - blockchain collections - - transaction collections - - collection nodes - - HotStuff consensus - - transaction hashes - - network optimization - - collection clusters - - transaction payload - - Flow architecture - - consensus nodes - - collection retrieval - - blockchain scaling - - data optimization ---- - -# Collections - -Collections link blocks and transactions together. Collection node clusters make these collections (using the HotStuff consensus algorithm), made up of an ordered list of one or more hashes of [signed transactions](./transactions.md). In order to optimize data, blocks don't contain transactions (as they do on Ethereum). The benefits are transaction data does not get transferred to consensus nodes on the network which optimizes transfer speed and this architecture allows scaling of ingestion speed by adding collection clusters. Consensus nodes need to only agree on the order of transactions to be executed, they don't need to know the transaction payload, thus making blocks and collections lightweight. Collection nodes hold transaction payloads for anyone who requests them (e.g. execution nodes). - -![Screenshot 2023-08-17 at 19.50.39.png](_collection_images/Screenshot_2023-08-17_at_19.50.39.png) - -## Collection Retrieval - -You can use the Flow CLI to get the collection data by running: - -```sh -flow collections get caff1a7f4a85534e69badcda59b73428a6824ef8103f09cb9eaeaa216c7d7d3f -n mainnet -``` - -Find [more about the command in the CLI docs](../../tools/flow-cli/get-flow-data/get-collections.md). - -Collections can be obtained from the access node APIs, currently, there are two gRPC and REST APIs. You can find more information about them here: - -[**gRPC Collection API**](../../networks/access-onchain-data/index.md#collections) - -[**REST Collection API**](/http-api#tag/Collections) - -There are multiple SDKs implementing the above APIs for different languages: - -[**Javascript SDK**](../../tools/clients/fcl-js/index.md) - -[**Go SDK**](../../tools/clients/flow-go-sdk/index.md) - -Find a list of all SDKs [here](../../tools/clients/index.md) diff --git a/docs/build/basics/flow-token.md b/docs/build/basics/flow-token.md deleted file mode 100644 index 2d6bf6f8f9..0000000000 --- a/docs/build/basics/flow-token.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: FLOW Coin -sidebar_position: 10 -description: Learn about the FLOW coin, its role as the native token of the Flow blockchain, and how to acquire, use, and build with it. Understand staking, delegation, and transaction fee mechanisms. -keywords: - - FLOW coin - - FLOW token - - native token - - fungible token - - staking - - delegation - - transaction fees - - Flow protocol - - Flow rewards - - token utility - - Flow wallet - - token custody - - Flow transactions - - Flow governance - - Flow ecosystem ---- - -## Introduction - -This section contains information about the FLOW Coin for individual backers, wallet providers, custodians and node operators. - -### FLOW as a Native Coin - -FLOW is the default coin for the Flow protocol, meaning it is used for all protocol-level fee payments, -rewards and staking transactions. FLOW implements the standard [Flow Fungible Token interface](https://github.com/onflow/flow-ft), -which all other on-chain fungible tokens also conform to. This interface is defined in Cadence, -Flow's native smart-contract programming language, which makes it easy to write applications that -interact with FLOW. - -## How to Get FLOW - -There are two ways to acquire FLOW Coins as yield: - -1. [Earn FLOW as a Validator or Delegator](../../networks/staking/06-technical-overview.md): Receive newly-minted FLOW as a reward for running a node. -1. [Earn FLOW as a Community Contributor](https://github.com/onflow/developer-grants): Flow offers grants for selected proposals as well as RFPs for teams to submit proposals for funded development - -## How to Use FLOW - -With FLOW, you can: - -- Spend -- Stake -- Delegate -- Hold -- Vote -- Send and share -- Create, develop, and grow your dapp - -### Spending FLOW - -All you need to spend FLOW is an account and a tool for signing transactions -(a wallet, custodian, or other signing service). -The FCL (Flow Client Library) makes it super duper easy to go to any dapp, -login with your account, have a great time, -and then sign with the wallet of your choice only once you decide to make a purchase. - -### Staking FLOW - -[You can use FLOW to operate a staked node.](../../networks/staking/06-technical-overview.md) Node operators receive newly-minted FLOW -as a reward for helping to secure the network. - -### Delegating FLOW - -[You can use FLOW for stake delegation.](../../networks/staking/06-technical-overview.md) Delegators receive newly-minted FLOW -as a reward for helping to secure the network. - -### Holding FLOW - -If you have already purchased FLOW and wish to hold it, you have a couple of options: - -- For relatively small, short term holdings - most people use a wallet. - Wallets are used to help you sign transactions (verify your actions) when using your FLOW tokens. - -- For larger, long term holdings - you may want to use a custody provider to keep your funds safe. - -You can find wallets and custodians supporting Flow in the [Flow Port](https://port.flow.com/) - -### Voting with FLOW - -Participating in the Flow community is more than just running a node or building a dapp. -It's also about engaging in discussion, debate, and decision making about the protocol, -the content on it, and the people impacted by it. -You can use your Flow account to submit votes to community polls and other governance related activities. - -### Sending and Sharing FLOW - -If you simply want to share the love and bring your friends to Flow, it's easier than an edible arrangement. - -It is possible to use the Flow blockchain without holding any FLOW coins yourself. -Free to play games, trials, community polls, -and other community activities can all take place with only an account -(which may be created on a person's behalf) -and a small fixed fee which may be paid by a user agent. - -The protocol requires some FLOW coins to process these transactions, -but (and this is the cool part!) a product can support users who do not themselves hold FLOW -while still providing that user with all the underlying security guarantees the Flow protocol provides. - -Transferring FLOW, creating accounts, and updating keys are all actions made easy on [Flow Port](https://port.flow.com/) - -### Submitting Transactions and Updating Users - -Transactions are submitted using a Flow SDK via the Access API. - -On Flow, a transaction is identified by its hash - the hash that exists as soon as that transaction is signed and submitted to an Access or Collection node. -Results of transactions can be queried by transaction hash through the Access API. -A user can check the status of a transaction at any time via the [Flow Block Explorer](https://flowscan.io/). - -To expose these results natively in your app, you can use a Flow SDK to fetch transaction results, -[for example using the Flow Go SDK](https://github.com/onflow/flow-go-sdk#querying-transaction-results). - -Using a Flow SDK you can also fetch account state by address from a Flow Access API, -[for example using the Flow Go SDK](https://github.com/onflow/flow-go-sdk#querying-accounts). - -Once the transaction is sealed, an event is emitted and you will be able to read transaction events and update the user. - -The Flow SDKs also allow polling for events using the Flow Access API, -[for example using the Flow Go SDK](https://github.com/onflow/flow-go-sdk#querying-events). - -## How to Build with FLOW - -To get started building on Flow, please see the [Flow App Quickstart](../getting-started/fcl-quickstart.md) diff --git a/docs/build/basics/mev-resistance.md b/docs/build/basics/mev-resistance.md deleted file mode 100644 index f8adaf8d9d..0000000000 --- a/docs/build/basics/mev-resistance.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: MEV Resistance -description: How Flow’s unique architecture minimizes Maximal Extractable Value (MEV) to ensure fair and equitable access. -sidebar_position: 5 -keywords: - - MEV - - Maximal Extractable Value - - Flow Blockchain - - Equitable Access - - Transaction Ordering - - Blockchain Security ---- - -# How Flow Suppresses MEV to Ensure Equitable Access - -## The Hidden Cost of MEV in Decentralized Systems - -One of the most under-discussed benefits of decentralization is **equitable access**. Ideally, the value and quality-of-service you receive from a decentralized platform should not depend on your identity, computing power, or personal connections. However, **Maximal Extractable Value (MEV)** poses a significant threat to this principle. - -MEV allows block producers to manipulate transaction ordering for profit—often at the direct expense of users. The ability to front-run, back-run, or sandwich transactions can extract value from ordinary users, reinforcing inequalities rather than eliminating them. In most blockchain networks, MEV is not just an unfortunate side effect; it is structurally embedded in how transactions are processed. - -## Why MEV Persists on Most Blockchains - -MEV is difficult to prevent on most blockchains because **each block has a single builder**. This builder must have: - -- A full copy of the blockchain state -- The ability to simulate transactions before they are finalized -- Absolute control over transaction selection and ordering - -In practice, this means that **the entity responsible for adding your transaction to the blockchain can first simulate it to identify profit opportunities**. They can test hundreds or thousands of ways to rearrange transactions, inserting their own to extract MEV—often at **your** expense. - -For example, if a block builder can earn $10 by sandwiching your transaction, it means **you** likely lose $10 in value. This is functionally theft, and the worst part? If your transaction is airtight and offers no MEV opportunities, the block builder has no obligation to include it at all. Pay the toll, or get locked out. - -## How Flow Accomplishes MEV Resilience - -Unlike many blockchains, **Flow was designed from the ground up to minimize MEV** through a unique multi-role architecture. Flow introduces key design choices that break the typical MEV-enabling structure: - -### 1. **Separating Transaction Selection from Execution** -On Flow, **Collection Nodes** select transactions, but they do not have access to the execution state or computing power to simulate them. Meanwhile, **Execution Nodes** run transactions but cannot choose or reorder them. - -This separation significantly reduces the ability of block builders to test transactions before execution. Even if an attacker controls both a Collection Node and an Execution Node, they cannot easily extract MEV. - -### 2. **Separating Transaction Ordering from Execution** -Flow further decentralizes control by introducing **Consensus Nodes** that determine transaction order. These nodes are separate from both Collection Nodes and Execution Nodes. - -For an attacker to perform MEV, they would need to: -- Control a **Collection Node** to insert a transaction -- Control a **Consensus Node** to place it in the desired order -- Have execution state access to predict its effects - -This makes it vastly more difficult to extract MEV compared to traditional blockchains, where a single entity often controls all three functions. - -### 3. **Strict Transaction Execution Rules** -Execution Nodes on Flow have a **simple, enforceable rule**: -They **must** execute transactions exactly as ordered by Consensus Nodes—or they get slashed. - -Unlike traditional blockchains, where the same party both orders and executes transactions, Flow ensures that Execution Nodes cannot manipulate transaction order for profit. - -### 4. **Parallel Processing for Extra MEV Resistance** -Flow’s unique **pipelined execution model** adds another layer of complexity for potential attackers. - -While one block is being executed, the next block is undergoing consensus, and a third block is still collecting transactions. This means that **to front-run or sandwich attack on Flow, an attacker must successfully predict the outcome of at least two unexecuted blocks—one of which hasn’t even been built yet**. - -Even with significant resources, this makes profitable MEV attacks incredibly difficult. - -## The End Result: A Fairer Blockchain - -Flow’s architecture ensures that: -- The nodes selecting transactions **don’t know** their order -- The nodes ordering transactions **don’t know** the blockchain state -- The nodes executing transactions **can’t** modify the order - -By **intentionally separating powers**, Flow eliminates MEV at its root rather than merely mitigating its effects. - -This level of protection against MEV is not an afterthought—it has been a fundamental design goal of Flow since day one. If equitable access matters, **why settle for anything less?** diff --git a/docs/build/basics/scripts.md b/docs/build/basics/scripts.md deleted file mode 100644 index 20cbfce8b5..0000000000 --- a/docs/build/basics/scripts.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -sidebar_position: 4 -title: Scripts -description: Learn about Flow scripts - read-only Cadence code that can query blockchain state without fees. Understand how to write, execute, and optimize scripts for accessing Flow network data. -keywords: - - scripts - - Cadence scripts - - blockchain queries - - read operations - - Flow scripts - - script execution - - state queries - - Flow API - - script limitations - - best practices - - historic data - - script arguments - - script returns - - Flow CLI - - computation limits ---- - -# Scripts - -A script provides a light-weight method to query chain data. - -It is executable Cadence code that can query for Flow execution state data but cannot modify it in any way. - -Unlike a Flow transaction, a script is not signed and requires no transaction fees. Also unlike a transaction, a script can return a value back to the caller. -You can think of executing a script as a read-only operation, very similar to the `eth_call` RPC method on Ethereum. - -Scripts are currently executed on either the Access Nodes or the Execution Nodes based on the Access node configuration. - -Scripts are defined by the following the Cadence code: - -```cadence -// The 'main' function is the entry point function and every script needs to have one. -access(all) fun main() { - // Cadence statements to be executed go here -} -``` - -Scripts can return a typed value: - -```cadence -access(all) fun main(): Int { - return 1 + 2 -} -``` - -Scripts can also accept arguments: - -```cadence -access(all) fun main(arg: String): String { - return "Hello ".concat(arg) -} -``` - -Scripts can call contract functions and query the state of a contract. To call a function on another contract, import it from its address and invoke the function: - -```cadence -import World from 0x01 - -access(all) fun main(): String { - return World.hello() -} -``` - -Scripts can also be run against previous blocks, allowing you to query historic data from the Flow network. This is particularly useful for retrieving historical states of contracts or tracking changes over time. - -## When to use a script? - -Scripts can be used for the following: - -1. Validating a transaction before submitting it e.g. checking if the payer has sufficient balance, the receiver account is setup correctly to receive a token or NFT etc. -2. Collecting chain data over time. -3. Continuously verifying accounts through a background job e.g. a Discord bot that verifies users by their Flow account. -4. Querying core contracts e.g. see [staking scripts and events](../../networks/staking/07-staking-scripts-events.md) for querying staking and epoch related information, see the scripts directory under each of the [core contract transactions](https://github.com/onflow/flow-core-contracts/tree/master/transactions) for other core contracts related scripts. - -## Executing Scripts - -### Access API - -A script can be executed by submitting it to the Access API provided by access nodes. Currently, there are three API endpoints that allow a user to execute scripts at the latest sealed block, a previous block height, or a previous block ID. - -[**gRPC Script API**](../../networks/access-onchain-data/index.md#scripts) - -[**REST Script API**](/http-api#tag/Scripts) - -There are multiple SDKs implementing the above APIs for different languages: - -[**Javascript SDK**](../../tools/clients/fcl-js/index.md) - -[**Go SDK**](../../tools/clients/flow-go-sdk/index.md) - -Find a list of all SDKs [here](../../tools/clients/index.md) - -### Flow CLI - -You can also execute a script by using the [Flow CLI](../../tools/flow-cli/scripts/execute-scripts): - -```sh -flow scripts execute ./helloWorld.cdc -``` - -A user can define their own scripts or can use already defined scripts by the contract authors that can be found by using the [FLIX](../../tools/flow-cli/flix) service. - -## Best Practices - -Following are some recommendations on how to write efficient scripts: - -1. **Simpler and shorter scripts**: Scripts, like transactions, are subject to computation limits (see [limitations](#limitations)). It is recommended to run shorter and simpler scripts which have low time complexity for a faster response. If you have a script with several nested loops, long iteration, or that queries many onchain fields, consider simplifying the script logic. - - -2. **Fewer state reads**: A script reads execution state and to get a faster response, it is best to limit the amount of state that is read by the script. - - -3. **Smaller length of array or dictionary type arguments**: If your script requires an array or a dictionary as an argument where each element causes a state lookup, instead of making a single script call passing in a long list, make multiple calls with a smaller subset of the array or dictionary. - - -4. **NFTCatalog**: If your script uses the [NFTCatalog](https://github.com/onflow/nft-catalog) functions, ensure that you use the [latest functions](https://github.com/onflow/nft-catalog?tab=readme-ov-file#using-the-catalog-for-marketplaces-and-other-nft-applications) and do not use any of the deprecated functions such as `getCatalog()`. - - -## Limitations - -1. **Rate limit** - Script execution is subjected to API rate-limits imposed by the Access nodes and the Execution nodes. The rate limits for the Public Access nodes hosted by QuickNode are outlined [here](https://www.quicknode.com/docs/flow#endpoint-rate-limits). - - -2. **Computation limit** - Similar to a transaction, each script is also subjected to a computation limit. The specific value can be configured by individual Access and Execution node operators. Currently, the default compute (gas) limit for a script is 100,000. - - -3. **Historic block data limit** - 1. Script execution on execution nodes is restricted to approximately the last 100 blocks. Any request for script execution on an execution node on a past block (specified by block ID or block height) will fail if that block is more than 100 blocks in the past. - 2. Script execution on an access node can go much beyond the last 100 blocks but is restricted to the height when the [last](https://developers.flow.com/networks/node-ops/node-operation/past-upgrades) network upgrade ([HCU](https://developers.flow.com/networks/node-ops/node-operation/hcu) or spork) occurred. - - diff --git a/docs/build/cadence/_category_.yml b/docs/build/cadence/_category_.yml new file mode 100644 index 0000000000..589dfbb27f --- /dev/null +++ b/docs/build/cadence/_category_.yml @@ -0,0 +1,3 @@ +label: Cadence +position: 2 +collapsed: false diff --git a/docs/build/advanced-concepts/_category_.yml b/docs/build/cadence/advanced-concepts/_category_.yml similarity index 100% rename from docs/build/advanced-concepts/_category_.yml rename to docs/build/cadence/advanced-concepts/_category_.yml diff --git a/docs/build/advanced-concepts/account-abstraction.md b/docs/build/cadence/advanced-concepts/account-abstraction.md similarity index 64% rename from docs/build/advanced-concepts/account-abstraction.md rename to docs/build/cadence/advanced-concepts/account-abstraction.md index 304a430f00..2a5db6cf11 100644 --- a/docs/build/advanced-concepts/account-abstraction.md +++ b/docs/build/cadence/advanced-concepts/account-abstraction.md @@ -13,58 +13,64 @@ sidebar_position: 2 # Blockchain Account Abstraction -Flow is a fast blockchain with account abstraction, designed to make Web3 as seamless as Web2. It provides native support for key use cases that are enabled by Account Abstraction, empowering developers to deliver mainstream-ready user experiences. With Cadence, Flow was designed with these use cases in mind through the separation of the contract and transaction layers. This guide demonstrates how Flow supports key use cases that are made possible with Account Abstraction. +Flow is a fast blockchain with account abstraction, designed to make Web3 as seamless as Web2. It provides native support for key use cases that Account Abstraction , which empowers developers to deliver mainstream-ready user experiences. With Cadence, Flow was designed with these use cases in mind through the separation of the contract and transaction layers. This guide demonstrates how Flow supports key use cases that Account Abstraction makes possible. -## Multi-sig Transactions on a Fast Blockchain with Account Abstraction +## Multi-sig transactions on a Fast Blockchain with Account Abstraction Since accounts are smart contracts, they can be defined in order to require multiple signatures in order to execute a transaction, which unlocks a range of new users that improve the user experience for Web3 apps. | Account Abstraction | Flow | | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| The move from from Externally-Owned Accounts (EOAs) to smart contract accounts enables developers to build in logic to require multiple signatures to execute transactions. | Flow has native support for multi-sig transactions since all accounts are defined as smart contracts. Flow provides [support for multiple keys](../basics/accounts.md#account-keys) to be added to an account and weights can be applied to denote relative priority. | +| The move from from Externally-Owned Accounts (EOAs) to smart contract accounts allows developers to build in logic to require multiple signatures to execute transactions. | Flow has native support for multi-sig transactions since all accounts are defined as smart contracts. Flow provides [support for multiple keys] to be added to an account and weights can be applied to denote relative priority. | -## Sponsored Transactions for Mainstream-Ready Web3 Apps +## Sponsored transactions for mainstream-ready Web3 apps -The concept of paying fees to execute transactions in order to use Web3 apps can be a hurdle for newcomers as they begin to explore these experiences. In order to remove this significant point of friction in requiring newcomers to acquire crypto before they can get started with an app, developers can subsidize these costs on behalf of users. +The requirement that users pay fees to execute transactions in order to use Web3 apps can be a hurdle for newcomers as they begin to explore these experiences. In order to remove this significant point of friction that requires newcomers to acquire crypto before they can get started with an app, developers can subsidize these costs on behalf of users. | Account Abstraction | Flow | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| The ERC-4337 standard introduces the concept of [paymasters](https://eips.ethereum.org/EIPS/eip-4337#extension-paymasters), which can enable a developer to pay the fees for a transaction for their users. | Flow has built-in support for [3 different roles](../basics/transactions.md#signer-roles) for transactions which provides native support for sponsored transactions. | +| The ERC-4337 standard introduces the concept of [paymasters], which can allow a developer to pay the fees for a transaction for their users. | Flow has built-in support for [3 different roles] for transactions which provides native support for sponsored transactions. | -## Bundled Transactions for Faster User Experience +## Bundled transactions for faster user experience -Developers can deliver a more streamlined user experience that reduces the amount of interruptions in the form of transaction approvals by bundling multiple transactions together into a single transaction that executes the set of operations with one signature. +To deliver a more streamlined user experience that reduces the amount of interruptions in the form of transaction approvals developers can bundle multiple transactions together into a single transaction that executes the set of operations with one signature. | Account Abstraction | Flow | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| The ERC-4337 standard outlines support for bundled transactions through a new mempool that holds user operations from smart wallets. Bundlers package sets of these user operations into a single transaction on the blockchain and return the result back to each wallet. | Since Cadence has an explicit separation of contracts and transactions, Flow has protocol-level support for bundling transactions across multiple contracts into a single transaction. | +| The ERC-4337 standard outlines support for bundled transactions through a new mempool that holds user operations from smart wallets. Bundlers package sets of these user operations into a single transaction on the blockchain and return the result back to each wallet. | Since Cadence has an explicit separation of contracts and transactions, Flow has protocol-level support to bundle transactions across multiple contracts into a single transaction. | -## Account Recovery +## Account recovery -Account Abstraction enables developers to build more robust account management features for users, addressing the major pain point of losing access to assets forever if the user loses their keys to their account. Apps can enable users to recover access to their accounts and enclosed assets through social recovery or pre-approved accounts. +Account Abstraction allows developers to build more robust account management features for users, which addresses the major pain point where users lose access to assets forever if they lose the keys to their account. Apps can let recover access to their accounts and enclosed assets through social recovery or pre-approved accounts. | Account Abstraction | Flow | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Smart contract accounts can be defined to include account recovery logic that enables users to define custom recovery methods that can rely on specific accounts or other validated sources. | Since all accounts are smart contracts, Flow has native support for account recovery and cycling of keys to help users regain access to accounts in a secure manner. | +| Smart contract accounts can be defined to include account recovery logic that allows users to define custom recovery methods that can rely on specific accounts or other validated sources. | Since all accounts are smart contracts, Flow has native support for account recovery and cycling of keys to help users regain access to accounts in a secure manner. | -## Multi-factor Authentication +## Multi-factor authentication -Multi-factor authentication is a broadly accepted concept in Web2 apps for secure access to accounts and Account Abstraction enables developers to deliver the same benefits to Web3 users. +Multi-factor authentication is a broadly accepted concept in Web2 apps for secure access to accounts and Account Abstraction allows developers to deliver the same benefits to Web3 users. | Account Abstraction | Flow | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Smart contract accounts can require a secondary factor to confirm transactions which can be delivered in the form of familiar confirmation channels such as email or SMS. | Since all accounts are smart contracts, Flow has native support for multi-factor authentication as developers can implement these security mechanisms for their users. | -## Seamless Experience +## Seamless experience -Account Abstraction brings the potential for dramatic improvements to the user experience of Web3 apps. Developers can introduce conditions under which a user can grant a smart contract account to pre-approve transactions under certain conditions, reducing interruptions for the user to explicitly sign each transaction. +Account Abstraction brings the potential for dramatic improvements to the user experience of Web3 apps. Developers can introduce conditions under which a user can grant a smart contract account to pre-approve transactions under certain conditions, which reduces interruptions for the user to explicitly sign each transaction. -These improvements are especially notable on mobile, where users are typically met with the jarring experience of switching between apps in approve transactions. +These improvements are especially notable on mobile, where the previous jarring experience required users to switch between apps in approve transactions. | Account Abstraction | Flow | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Developers can build new features that streamline the user experience of Web3 apps, such as 'session keys' that pre-approve transactions for a period of time or setting custom limits on transaction volume or network fees. | Since all accounts are smart contracts, Flow has support for these new controls that enable apps to sign pre-approved transactions based on user controls and preferences. | +| Developers can build new features that streamline the user experience of Web3 apps, such as 'session keys' that pre-approve transactions for a period of time or set custom limits on transaction volume or network fees. | Since all accounts are smart contracts, Flow has support for these new controls that allow apps to sign pre-approved transactions based on user controls and preferences. | ## Conclusion -Flow delivers more than just developer convenience, it’s a **high-performance blockchain with account abstraction** built directly into its core protocol. By combining speed, scalability, and advanced features like multi-sig, sponsored transactions, bundled operations, account recovery, and multi-factor authentication, Flow empowers developers to create secure, seamless, and mainstream-ready Web3 experiences without sacrificing performance. \ No newline at end of file +Flow delivers more than just developer convenience, it’s a **high-performance blockchain with account abstraction** built directly into its core protocol. Flow combines speed, scalability, and advanced features like multi-sig, sponsored transactions, bundled operations, account recovery, and multi-factor authentication. This empowers developers to create secure, seamless, and mainstream-ready Web3 experiences but not sacrifice performance. + + + +[support for multiple keys]: ../basics/accounts.md#account-keys +[paymasters]: https://eips.ethereum.org/EIPS/eip-4337#extension-paymasters +[3 different roles]: ../basics/transactions.md#signer-roles \ No newline at end of file diff --git a/docs/build/advanced-concepts/collectionDisplay.png b/docs/build/cadence/advanced-concepts/collectionDisplay.png similarity index 100% rename from docs/build/advanced-concepts/collectionDisplay.png rename to docs/build/cadence/advanced-concepts/collectionDisplay.png diff --git a/docs/build/cadence/advanced-concepts/computation-profiling.md b/docs/build/cadence/advanced-concepts/computation-profiling.md new file mode 100644 index 0000000000..d76dbf58a3 --- /dev/null +++ b/docs/build/cadence/advanced-concepts/computation-profiling.md @@ -0,0 +1,508 @@ +--- +title: Cadence Computation Profiling +description: This guide provides comprehensive instructions for using the computation profiling and reporting features in the Flow Emulator. These tools help Cadence developers analyze and optimize their smart contracts by understanding computational costs and identifying performance bottlenecks. +keywords: + - computation profiling + - Flow Emulator + - smart contract optimization + - performance analysis + - computational costs + - Cadence + - profiling + - performance bottlenecks +sidebar_position: 1 +--- + +# Cadence Computation Profiling + +This guide provides comprehensive instructions for using the computation profiling and reporting features in the Flow Emulator. These tools help Cadence developers analyze and optimize their smart contracts by understanding computational costs and identifying performance bottlenecks. + +## Overview + +When developing smart contracts on Flow, understanding computational costs is essential for: + +- **Performance Optimization**: Identify slow operations and optimize your code +- **Cost Awareness**: Understand how much computation your transactions and scripts consume +- **Bottleneck Identification**: Pinpoint exactly where your code spends the most resources + +The Flow CLI provides three complementary approaches for profiling computation: + +| Approach | Output | Best For | +|----------|--------|----------| +| **Transaction Profiling** (`flow transactions profile`) | pprof profile for sealed transactions | Analyzing production transactions on mainnet/testnet | +| **Emulator Computation Reporting** (`flow emulator --computation-reporting`) | JSON report with detailed intensities | Quick numerical analysis, CI/CD integration, automated testing | +| **Emulator Computation Profiling** (`flow emulator --computation-profiling`) | pprof profile for development | Visual analysis during development, flame graphs, call stack exploration | + +:::note + +Before getting started, make sure you have the [Flow CLI installed](../../tools/flow-cli/install.md). + +::: + +## Transaction Profiling + +For analyzing sealed transactions on any Flow network (mainnet, testnet, or emulator), use the `flow transactions profile` command. This is particularly useful for: + +- **Production Analysis**: Profile real transactions on mainnet to understand actual performance +- **Debugging High Costs**: Investigate why a specific transaction used more computation than expected +- **Post-Deployment Optimization**: Analyze live transactions to identify optimization opportunities + +### Basic Usage + +```bash +# Profile a mainnet transaction +flow transactions profile 07a8...b433 --network mainnet + +# Profile with custom output location +flow transactions profile 0xabc123 --network testnet --output my-profile.pb.gz +``` + +### Analyzing Transaction Profiles + +The command generates a pprof profile that can be analyzed with standard tools: + +```bash +# Interactive web interface +go tool pprof -http=:8080 profile-07a8b433.pb.gz + +# Command-line analysis +go tool pprof -top profile-07a8b433.pb.gz +``` + +📖 **[Learn more about transaction profiling](../../tools/flow-cli/transactions/profile-transactions.md)** + +:::info + +Transaction profiling works with sealed transactions on any network, while emulator profiling (described below) is designed for development and provides aggregated profiles across multiple executions. + +::: + +## Computation Reporting + +Computation reporting provides a JSON-based view of computational costs for all executed transactions and scripts. + +### Enabling Computation Reporting + +Start the emulator with the `--computation-reporting` flag: + +```bash +flow emulator --computation-reporting +``` + +:::info + +For more accurate computation numbers that reflect real network conditions, consider using [emulator fork testing](../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md). Forking allows you to profile against actual Mainnet or Testnet state without requiring a full emulator environment setup. + +::: + +### Viewing Computation Reports + +Once enabled, access the computation report at: + +``` +http://localhost:8080/emulator/computationReport +``` + +The report returns a JSON object with the following structure: + +```json +{ + "scripts": { + "": { + "path": "scripts/myScript.cdc", + "computation": 1250, + "intensities": { + "Statement": 45, + "FunctionInvocation": 12, + "GetValue": 8 + }, + "memory": 2048, + "source": "access(all) fun main(): Int { ... }", + "arguments": ["0x1"] + } + }, + "transactions": { + "": { + "path": "transactions/myTransaction.cdc", + "computation": 3500, + "intensities": { + "Statement": 120, + "EmitEvent": 5, + "SetValue": 15 + }, + "memory": 8192, + "source": "transaction { ... }", + "arguments": ["100.0"] + } + } +} +``` + +#### Report Fields + +| Field | Description | +|-------|-------------| +| `path` | Source file path (set via `#sourceFile` pragma) | +| `computation` | Total computation units used | +| `intensities` | Count of each operation type performed | +| `memory` | Estimated memory usage | +| `source` | Original Cadence source code | +| `arguments` | Arguments passed to the transaction/script | + +### Understanding Computation Intensities + +The `intensities` map shows how many times each operation type was performed. The keys are human-readable names like `Statement`, `Loop`, `FunctionInvocation`, `GetValue`, `SetValue`, `EmitEvent`, etc. + +The total `computation` value is calculated by multiplying each intensity by its corresponding weight (defined by the network) and summing the results. When optimizing, look for operations with high counts - reducing these will lower your total computation cost. + +## Computation Profiling (pprof) + +Computation profiling generates pprof-compatible profiles that can be visualized as flame graphs, providing a powerful way to understand your code's execution patterns. + +### Installing pprof + +To visualize computation profiles, you'll need the [pprof tool](https://github.com/google/pprof). See the [pprof installation guide](https://github.com/google/pprof#building-pprof) for instructions. + +### Enabling Computation Profiling + +Start the emulator with the `--computation-profiling` flag: + +```bash +flow emulator --computation-profiling +``` + +> **Note**: You can enable both `--computation-reporting` and `--computation-profiling` simultaneously if you need both types of analysis. + +### Downloading the Profile + +After executing transactions and scripts, download the profile from: + +``` +http://localhost:8080/emulator/computationProfile +``` + +This downloads a `profile.pprof` file containing the aggregated computation profile. + +Using curl: + +```bash +curl -o profile.pprof http://localhost:8080/emulator/computationProfile +``` + +### Viewing Profiles with pprof + +Open the profile in an interactive web interface: + +```bash +pprof -http=:8081 profile.pprof +``` + +Then navigate to `http://localhost:8081` in your browser. + +#### Available Views + +The pprof web interface provides several visualization options: + +| View | Description | +|------|-------------| +| **Flame Graph** | Visual representation of call stacks with computation costs | +| **Graph** | Directed graph showing call relationships | +| **Top** | List of functions sorted by computation usage | +| **Source** | Source code annotated with computation costs | +| **Peek** | Callers and callees of selected functions | + +### Viewing Source Code in pprof + +To see Cadence source code annotated with computation costs: + +1. **Download all deployed contracts**: + + ```bash + curl -o contracts.zip http://localhost:8080/emulator/allContracts + ``` + +2. **Extract the ZIP file into a `contracts` folder**: + + ```bash + mkdir -p contracts + unzip contracts.zip -d contracts + ``` + +3. **Run pprof with the source path**: + + ```bash + pprof -source_path=contracts -http=:8081 profile.pprof + ``` + +Now when you view the "Source" tab in pprof, you'll see your Cadence code with line-by-line computation annotations. + +### Resetting Computation Profiles + +To clear the accumulated profile data (useful between test runs): + +```bash +curl -X PUT http://localhost:8080/emulator/computationProfile/reset +``` + +## Using Source File Pragmas + +The `#sourceFile` pragma improves computation report readability by associating your code with meaningful file paths. Without it, reports show generic identifiers. + +> **Note**: The `#sourceFile` pragma currently only affects **Computation Reporting** (JSON reports). It does not change filenames in **Computation Profiling** (pprof profiles). + +### Usage + +Add the pragma at the beginning of your transaction or script: + +```cadence +#sourceFile("transactions/transfer_tokens.cdc") + +transaction(amount: UFix64, recipient: Address) { + prepare(signer: auth(Storage) &Account) { + // Transfer logic + } +} +``` + +For scripts: + +```cadence +#sourceFile("scripts/get_balance.cdc") + +access(all) fun main(address: Address): UFix64 { + return getAccount(address).balance +} +``` + +### Benefits + +- Computation reports show file paths instead of generic IDs +- Easier to correlate computation costs with source files +- Useful for tracking costs across multiple files in a project + +## Practical Examples + +### Profiling a Simple Transaction + +Let's profile a simple NFT minting transaction. + +**1. Start the emulator with profiling enabled:** + +```bash +flow emulator --computation-profiling --computation-reporting +``` + +**2. Create a transaction file (`transactions/mint_nft.cdc`):** + +```cadence +#sourceFile("transactions/mint_nft.cdc") + +import NonFungibleToken from 0xf8d6e0586b0a20c7 +import ExampleNFT from 0xf8d6e0586b0a20c7 + +transaction { + prepare(signer: auth(Storage) &Account) { + let collection = signer.storage.borrow<&ExampleNFT.Collection>( + from: ExampleNFT.CollectionStoragePath + ) ?? panic("Could not borrow collection") + + collection.deposit(token: <- ExampleNFT.mintNFT()) + } +} +``` + +**3. Execute the transaction:** + +```bash +flow transactions send transactions/mint_nft.cdc +``` + +**4. View the computation report:** + +```bash +curl http://localhost:8080/emulator/computationReport | jq +``` + +**5. Analyze with pprof:** + +```bash +curl -o profile.pprof http://localhost:8080/emulator/computationProfile +pprof -http=:8081 profile.pprof +``` + +### Identifying Performance Bottlenecks + +Consider a script that iterates over a large collection: + +```cadence +#sourceFile("scripts/find_expensive.cdc") + +access(all) fun main(address: Address): [UInt64] { + let account = getAccount(address) + let collection = account.capabilities.borrow<&{NonFungibleToken.Collection}>( + /public/NFTCollection + ) ?? panic("Could not borrow collection") + + let ids = collection.getIDs() + var result: [UInt64] = [] + + // Potentially expensive loop + for id in ids { + let nft = collection.borrowNFT(id) + if nft != nil { + result.append(id) + } + } + + return result +} +``` + +After profiling, you might see high values for: +- `Loop`: Many iterations +- `FunctionInvocation`: Repeated `borrowNFT` calls +- `GetValue`: Multiple storage reads + +**Optimization strategies:** +- Use pagination to limit iterations per call +- Cache results when possible +- Consider restructuring data for more efficient access + +### Comparing Computation Costs + +You can compare two implementation approaches by downloading and comparing profiles: + +**1. Reset the profile:** + +```bash +curl -X PUT http://localhost:8080/emulator/computationProfile/reset +``` + +**2. Run implementation A and save the profile:** + +```bash +flow transactions send approach_a.cdc +curl -o profile_a.pprof http://localhost:8080/emulator/computationProfile +``` + +**3. Reset and test implementation B:** + +```bash +curl -X PUT http://localhost:8080/emulator/computationProfile/reset +flow transactions send approach_b.cdc +curl -o profile_b.pprof http://localhost:8080/emulator/computationProfile +``` + +**4. Compare using pprof:** + +```bash +# View profile A +pprof -top profile_a.pprof + +# View profile B +pprof -top profile_b.pprof +``` + +The `-top` view shows total computation, making it easy to compare the two approaches. + +## API Reference + +| Endpoint | Method | Description | +|----------|--------|-------------| +| `/emulator/computationReport` | GET | View computation report (JSON) | +| `/emulator/computationProfile` | GET | Download pprof profile | +| `/emulator/computationProfile/reset` | PUT | Reset computation profile | +| `/emulator/allContracts` | GET | Download all deployed contracts (ZIP) | + +### Example API Calls + +```bash +# Get computation report +curl http://localhost:8080/emulator/computationReport + +# Download pprof profile +curl -o profile.pprof http://localhost:8080/emulator/computationProfile + +# Reset computation profile +curl -X PUT http://localhost:8080/emulator/computationProfile/reset + +# Download all contracts +curl -o contracts.zip http://localhost:8080/emulator/allContracts +``` + +## Troubleshooting + +### Profile endpoint returns 404 + +**Problem**: Accessing `/emulator/computationProfile` returns a 404 error. + +**Solution**: Make sure you started the emulator with `--computation-profiling`: + +```bash +flow emulator --computation-profiling +``` + +### Empty profile + +**Problem**: The downloaded profile is empty or has no useful data. + +**Solution**: Make sure you've executed at least one transaction or script after starting the emulator. The profile only contains data for executed code. + +### Source code not showing in pprof + +**Problem**: The pprof source view doesn't display your Cadence code. + +**Solution**: +1. Download the contracts ZIP: `curl -o contracts.zip http://localhost:8080/emulator/allContracts` +2. Extract to a `contracts` folder in your working directory +3. Run pprof with the source path: `pprof -source_path=contracts -http=:8081 profile.pprof` + +### High memory usage + +**Problem**: The emulator uses increasing memory over time. + +**Solution**: Periodically reset computation profiles to free accumulated data: + +```bash +curl -X PUT http://localhost:8080/emulator/computationProfile/reset +``` + +### Computation reports not showing file paths + +**Problem**: The `path` field in computation reports is empty. + +**Solution**: Add the `#sourceFile` pragma to your transactions and scripts: + +```cadence +#sourceFile("path/to/your/file.cdc") +``` + +## Related Features + +### Code Coverage Reporting + +The emulator also supports Cadence code coverage reporting, which complements computation profiling: + +```bash +flow emulator --coverage-reporting +``` + +View coverage at: `http://localhost:8080/emulator/codeCoverage` + +Learn more in the [Flow Emulator documentation](../../tools/emulator/index.md). + +### Debugger + +For step-through debugging of Cadence code, use the `#debug()` pragma: + +```cadence +#debug() + +transaction { + prepare(signer: &Account) { + // Execution pauses here for debugging + } +} +``` + +This works with VSCode and Flow CLI debugging tools. diff --git a/docs/build/advanced-concepts/display.png b/docs/build/cadence/advanced-concepts/display.png similarity index 100% rename from docs/build/advanced-concepts/display.png rename to docs/build/cadence/advanced-concepts/display.png diff --git a/docs/build/cadence/advanced-concepts/flix.md b/docs/build/cadence/advanced-concepts/flix.md new file mode 100644 index 0000000000..41840ab104 --- /dev/null +++ b/docs/build/cadence/advanced-concepts/flix.md @@ -0,0 +1,93 @@ +--- +title: FLIX (Flow Interaction Templates) +description: Learn about Flow Interaction Templates (FLIX), a standard for creating, auditing, and verifying Flow scripts and transactions with improved security and metadata. +keywords: + - FLIX + - Flow Interaction Templates + - templates + - transactions + - scripts + - smart contracts + - FCL + - interaction templates + - template service +sidebar_position: 10 +--- + +# Flow Interaction Templates + +Flow Interaction Templates (FLIX) is a standard for how contract developers, wallets, users, auditors, and applications can create, audit, and verify the intent, security, and metadata of Flow scripts and transactions, with the goal to improve the understandability and security of transaction authorizations and promote patterns for change resilient composability of applications on Flow. + +Interaction Templates provide a way to use and reuse current scripts and transactions, as well as to provide more metadata such as a human-readable title and description of what the transaction or script will do, which the developer can use, as well as the application user. + +With FLIX transactions and scripts, developers don't have to write their own for common operations! + +Read more about the design and purpose of FLIX in the [FLIP]. + +## Use FLIX + +Flow makes FLIX available through an API available at flix.flow.com. + +You can query a FLIX API to get an Interaction Template. An example query looks like [this]. + +You can read more about how to query a FLIX API in the documentation available [here]. + +:::info + +The FLIX working group is currently working on a protocol to publish FLIX templates onchain. + +::: + +### Example + +How to integrate FLIX across different developer teams? For this example there are two GitHub repositories. + +- (smart contracts) [https://github.com/onflow/hello-world-flix] +- (web development) [https://github.com/onflow/hello-world-web] + +The Smart contract developer creates FLIX templates and makes them available in GitHub, these can be versioned. Example is `v0.1.0` release, the templates are available for a specific version. In this example the templates are located at: + +- https://github.com/onflow/hello-world-flix/blob/v0.1.0/cadence/templates/ReadHelloWorld.template.json +- https://github.com/onflow/hello-world-flix/blob/v0.1.0/cadence/templates/UpdateHelloWorld.template.json + +Developers can use FLIX templates from the smart contract github to interact with their smart contracts. They simply need the FLIX template URLs to create binding files (TypeScript or JavaScript). One major benefit is the web developers don't need to learn Cadence or copy Cadence to their repository in order to integrate with current smart contracts. + +TypeScript code generated from templates: + +- https://github.com/onflow/hello-world-web/blob/main/app/cadence/readHelloWorld.ts +- https://github.com/onflow/hello-world-web/blob/main/app/cadence/updateHelloWorld.ts + +:::warning + +manually added "@ts-ignore" in generated file because of linting error. 'template' property is typed as "object" when it should also allow strings (url to flix template file). There is current a dev effort that will fix this linting issue. + +::: + +See the `hello-world-web` [README]for more information on how to generate and execute FLIX templates here. + +[flow-cli flix] + +### Clients + +There are currently two clients that have integrated with FLIX that you can use: + +**Go client** [https://github.com/onflow/flixkit-go] + +**FCL client you** read how to get started [tools/clients/fcl-js/interaction-templates] + +## (Advanced) Run a FLIX API + +Flow provides an implementation of the Flow interaction template service as an open-source project. If you wish to run your own API, you can find the repository at [https://github.com/onflow/flow-interaction-template-service]. + + + +[FLIP]: https://github.com/onflow/flips/blob/main/application/20220503-interaction-templates.md +[this]: https://flix.flow.com/v1/templates?name=transfer-flow +[here]: https://github.com/onflow/flow-interaction-template-service +[https://github.com/onflow/hello-world-flix]: https://github.com/onflow/hello-world-flix) +[https://github.com/onflow/hello-world-web]: https://github.com/onflow/hello-world-web) +[README]: https://github.com/onflow/hello-world-web/tree/main +[flow-cli flix]: ../../../build/tools/flow-cli/flix.md +[https://github.com/onflow/flixkit-go]: https://github.com/onflow/flixkit-go +[tools/clients/fcl-js/interaction-templates]: ../../../build/tools/clients/fcl-js/interaction-templates.mdx +[https://github.com/onflow/flow-interaction-template-service]: https://github.com/onflow/flow-interaction-template-service \ No newline at end of file diff --git a/docs/build/cadence/advanced-concepts/flow-cron.md b/docs/build/cadence/advanced-concepts/flow-cron.md new file mode 100644 index 0000000000..264f0068b6 --- /dev/null +++ b/docs/build/cadence/advanced-concepts/flow-cron.md @@ -0,0 +1,415 @@ +--- +title: Cron-Based Recurring Transactions +sidebar_position: 9 +description: Learn how to schedule recurring transactions on Flow using the FlowCron smart contract. +--- + +# Cron-Based Recurring Transactions + +Sometimes you need blockchain logic to run automatically on a schedule: distributing rewards every day, checking conditions every hour, or processing batches every week. Instead of manually triggering these transactions, you can automate them. + +**Cron** is a time-based scheduling system originally from Unix. It lets you define "run this at 9am every Monday" using a simple pattern called a cron expression. The **FlowCron** smart contract brings this same concept onchain, so you can schedule recurring transactions that run automatically without any external triggers. + +For example, with the cron expression `0 0 * * *` (daily at midnight), your transaction executes every day at midnight UTC—indefinitely—until you stop it. + +:::info + +`FlowCron` builds on Flow's Scheduled Transactions. If you haven't worked with scheduled transactions before, check out the [Scheduled Transactions documentation](scheduled-transactions.md) first. + +::: + +## How It Works + +`FlowCron` provides a `CronHandler` resource that wraps your existing [TransactionHandler]. You give it a cron expression (like `*/5 * * * *` for every 5 minutes) and your handler, and `FlowCron` takes care of the rest. Once started, your schedule runs indefinitely without any further action from you. + +### Why Two Transactions? + +A key challenge with recurring schedules is fault tolerance: what happens if your code has a bug? You don't want one failed execution to break the entire schedule. + +`FlowCron` solves this by running two separate transactions each time your cron triggers: + +- **Executor**: Runs your code. If your logic fails, only this transaction reverts. +- **Keeper**: Schedules the next cycle. Runs independently, so even if your code throws an error, the schedule continues. + +**The benefit**: Your recurring schedule won't break if your `TransactionHandler` execution fails. The keeper always ensures the next execution is scheduled, regardless of whether the current one succeeded or failed. + +``` +Timeline ─────────────────────────────────────────────────────────> + T1 T2 T3 + │ │ │ + ├── Executor ──────────►├── Executor ──────────►├── Executor + │ (runs user code) │ (runs user code) │ (runs user code) + │ │ │ + └── Keeper ────────────►└── Keeper ────────────►└── Keeper + (schedules T2) (schedules T3) (schedules T4) + (+1s offset) (+1s offset) (+1s offset) +``` + +## Cron Expressions + +A cron expression is just five numbers (or wildcards) that define when something should run. + +`FlowCron` uses the standard 5-field cron format: + +``` +┌───────────── minute (0-59) +│ ┌───────────── hour (0-23) +│ │ ┌───────────── day of month (1-31) +│ │ │ ┌───────────── month (1-12) +│ │ │ │ ┌───────────── day of week (0-6, Sunday=0) +│ │ │ │ │ +* * * * * +``` + +**Operators:** `*` (any), `,` (list), `-` (range), `/` (step) + +| Pattern | When it runs | +| --- | --- | +| `* * * * *` | Every minute | +| `*/5 * * * *` | Every 5 minutes | +| `0 * * * *` | Top of every hour | +| `0 0 * * *` | Daily at midnight | +| `0 0 * * 0` | Weekly on Sunday | +| `0 9-17 * * 1-5` | Hourly, 9am-5pm weekdays | + +:::note + +When you specify both day-of-month and day-of-week (not `*`), the job runs if **either** matches. So `0 0 15 * 0` fires on the 15th OR on Sundays. + +::: + +## Setup + +Setting up a cron job involves four steps: + +1. **Create a handler**: Write the code you want to run on each tick +2. **Wrap it with FlowCron**: Connect your handler to a cron schedule +3. **Start the schedule**: Kick off the first execution +4. **Monitor**: Check that everything is running + +All transactions and scripts referenced below are available in the [FlowCron GitHub repository]. + +### Prerequisites + +Before you start, make sure you have: + +- **[Flow CLI]** installed: This is the command-line tool you'll use to deploy contracts, send transactions, and run scripts. If you don't have it yet, follow the [installation guide]. +- **FLOW tokens** for transaction fees: Every transaction costs a small amount of FLOW. Get free testnet FLOW from the [Faucet]. +- A **Flow account**: The CLI will help you create one if you don't have one yet. + +### 1. Create Your Handler + +First, you need to write the code that will run on each scheduled tick. In Cadence, this is called a `TransactionHandler`. A `TransactionHandler` is a resource that implements the `FlowTransactionScheduler.TransactionHandler` interface. + +The key part is the `executeTransaction` function. This is where you put whatever logic you want to run on schedule: updating state, distributing tokens, checking conditions, etc. + +For more details on how handlers work, see the [Scheduled Transactions documentation](scheduled-transactions.md#create-a-scheduled-transaction). + +Here's a simple example contract: + +```cadence +import "FlowTransactionScheduler" + +access(all) contract MyRecurringTask { + + access(all) resource Handler: FlowTransactionScheduler.TransactionHandler { + + access(FlowTransactionScheduler.Execute) + fun executeTransaction(id: UInt64, data: AnyStruct?) { + // Your logic here + log("Cron fired at ".concat(getCurrentBlock().timestamp.toString())) + } + + access(all) view fun getViews(): [Type] { + return [Type(), Type()] + } + + access(all) fun resolveView(_ view: Type): AnyStruct? { + switch view { + case Type(): + return /storage/MyRecurringTaskHandler + case Type(): + return /public/MyRecurringTaskHandler + default: + return nil + } + } + } + + access(all) fun createHandler(): @Handler { + return <- create Handler() + } +} +``` + +This example handler simply logs the timestamp when executed. Replace the `log` statement with your own logic. + +#### Deploy Your Contract + +Use the Flow CLI to deploy your `TransactionHandler` contract: + +```bash +flow project deploy --network=testnet +``` + +This command reads your `flow.json` configuration and deploys all configured contracts. If you're new to deploying, see the [deployment guide] for a complete walkthrough. + +#### Create and Store a Handler Instance + +After deploying, you need to create an instance of your handler and save it to your account's **storage**. The **storage** is an area in your account where you can save resources (like your handler) that persist between transactions. + +See [CounterTransactionHandler.cdc] for a complete working example that includes the storage setup. + +### 2. Wrap It with `FlowCron` + +Now you need to wrap your handler with a `CronHandler`. This connects your handler to a cron schedule. + +The following transaction creates a new `CronHandler` resource that holds your cron expression and a reference to your handler: + +```cadence +transaction( + cronExpression: String, + wrappedHandlerStoragePath: StoragePath, + cronHandlerStoragePath: StoragePath +) { + prepare(acct: auth(BorrowValue, IssueStorageCapabilityController, SaveValue) &Account) { + // Issue capability for wrapped handler + let wrappedHandlerCap = acct.capabilities.storage.issue< + auth(FlowTransactionScheduler.Execute) &{FlowTransactionScheduler.TransactionHandler} + >(wrappedHandlerStoragePath) + + // Create and save the CronHandler + let cronHandler <- FlowCron.createCronHandler( + cronExpression: cronExpression, + wrappedHandlerCap: wrappedHandlerCap, + feeProviderCap: feeProviderCap, + schedulerManagerCap: schedulerManagerCap + ) + acct.storage.save(<-cronHandler, to: cronHandlerStoragePath) + } +} +``` + +See [CreateCronHandler.cdc] for the full transaction. + +**Send this transaction using the Flow CLI:** + +```bash +flow transactions send CreateCronHandler.cdc \ + "*/5 * * * *" \ + /storage/MyRecurringTaskHandler \ + /storage/MyCronHandler \ + --network=testnet +``` + +The arguments are: your cron expression, the storage path where your handler lives, and the path where the new `CronHandler` will be stored. + +### 3. Start the Schedule + +This transaction schedules the first executor and keeper, which kicks off the self-perpetuating loop. After this, your cron job runs automatically: + +```cadence +transaction( + cronHandlerStoragePath: StoragePath, + wrappedData: AnyStruct?, + executorPriority: UInt8, + executorExecutionEffort: UInt64, + keeperExecutionEffort: UInt64 +) { + prepare(signer: auth(BorrowValue, IssueStorageCapabilityController, SaveValue) &Account) { + // Calculate next cron tick time + let cronHandler = signer.storage.borrow<&FlowCron.CronHandler>(from: cronHandlerStoragePath) + ?? panic("CronHandler not found") + let executorTime = FlowCronUtils.nextTick(spec: cronHandler.getCronSpec(), afterUnix: currentTime) + } + + execute { + // Schedule executor (runs your code) + self.manager.schedule( + handlerCap: self.cronHandlerCap, + data: self.executorContext, + timestamp: UFix64(self.executorTime), + ... + ) + // Schedule keeper (schedules next cycle) + self.manager.schedule( + handlerCap: self.cronHandlerCap, + data: self.keeperContext, + timestamp: UFix64(self.keeperTime), + ... + ) + } +} +``` + +See [ScheduleCronHandler.cdc] for the full transaction. + +**Send this transaction using the Flow CLI:** + +```bash +flow transactions send ScheduleCronHandler.cdc \ + /storage/MyCronHandler \ + nil \ + 2 \ + 500 \ + 2500 \ + --network=testnet +``` + +**Parameters:** + +| Parameter | Description | +| --- | --- | +| `cronHandlerStoragePath` | Path to your CronHandler | +| `wrappedData` | Optional data passed to handler (`nil` or your data) | +| `executorPriority` | 0 (High), 1 (Medium), or 2 (Low) | +| `executorExecutionEffort` | Computation units for your code (start with `500`) | +| `keeperExecutionEffort` | Computation units for keeper (use `2500`) | + +:::warning[Fees] + +Starting a cron job requires prepaying fees for the scheduled transactions. FLOW will be deducted from your account to cover the executor and keeper fees. Make sure you have enough FLOW before running this transaction. + +::: + +Once this transaction succeeds, **your cron job is live**. The first execution will happen at the next cron tick, and the schedule will continue automatically from there. You don't need to do anything else, unless you want to monitor it or stop it. + +### 4. Check Status + +Use Cadence **scripts** to check your cron job's status. Scripts are read-only queries that inspect blockchain state without submitting a transaction—they're free to run and don't modify anything. Learn more in the [scripts documentation]. + +#### Query Cron Info + +The [GetCronInfo.cdc] script returns metadata about your cron handler: + +```cadence +access(all) fun main(handlerAddress: Address, handlerStoragePath: StoragePath): FlowCron.CronInfo? { + let account = getAuthAccount(handlerAddress) + if let handler = account.storage.borrow<&FlowCron.CronHandler>(from: handlerStoragePath) { + return handler.resolveView(Type()) as? FlowCron.CronInfo + } + return nil +} +``` + +**Run this script using the Flow CLI:** + +```bash +flow scripts execute GetCronInfo.cdc 0xYourAddress /storage/MyCronHandler --network=testnet +``` + +If your cron job is running, you'll see output showing the cron expression, next scheduled execution time, and handler status. + +#### Calculate Next Execution Time + +The [GetNextExecutionTime.cdc] script calculates when your cron expression will next trigger: + +```cadence +access(all) fun main(cronExpression: String, afterUnix: UInt64?): UFix64? { + let cronSpec = FlowCronUtils.parse(expression: cronExpression) + if cronSpec == nil { return nil } + let nextTime = FlowCronUtils.nextTick( + spec: cronSpec!, + afterUnix: afterUnix ?? UInt64(getCurrentBlock().timestamp) + ) + return nextTime != nil ? UFix64(nextTime!) : nil +} +``` + +**Run this script using the Flow CLI:** + +```bash +flow scripts execute GetNextExecutionTime.cdc "*/5 * * * *" nil --network=testnet +``` + +#### Additional Debugging Scripts + +- [GetCronScheduleStatus.cdc] — Returns executor/keeper transaction IDs, timestamps, and current status +- [GetParsedCronExpression.cdc] — Validates and parses a cron expression into a `CronSpec` + +## Stopping a Cron Job + +You might want to stop a cron job for several reasons: + +- **Debugging**: Something isn't working and you need to investigate +- **Updating**: You want to change the schedule or handler logic +- **Cost**: You no longer need the recurring execution +- **Temporary pause**: You want to stop temporarily and restart later + +To stop a running cron job, you need to cancel both the pending executor and keeper transactions. This transaction retrieves the scheduled transaction IDs from your `CronHandler` and cancels them: + +```cadence +transaction(cronHandlerStoragePath: StoragePath) { + prepare(signer: auth(BorrowValue, IssueStorageCapabilityController, SaveValue) &Account) { + let cronHandler = signer.storage.borrow<&FlowCron.CronHandler>(from: cronHandlerStoragePath) + ?? panic("CronHandler not found") + + self.executorID = cronHandler.getNextScheduledExecutorID() + self.keeperID = cronHandler.getNextScheduledKeeperID() + } + + execute { + // Cancel executor and keeper, receive fee refunds + if let id = self.executorID { + let refund <- self.manager.cancel(id: id) + self.feeReceiver.deposit(from: <-refund) + } + if let id = self.keeperID { + let refund <- self.manager.cancel(id: id) + self.feeReceiver.deposit(from: <-refund) + } + } +} +``` + +See [CancelCronSchedule.cdc] for the full transaction. + +**Send this transaction using the Flow CLI:** + +```bash +flow transactions send CancelCronSchedule.cdc /storage/MyCronHandler --network=testnet +``` + +Cancelling refunds 50% of the prepaid fees back to your account. + +## Contract Addresses + +`FlowCron` is deployed on both Testnet and Mainnet: + +| Contract | Testnet | Mainnet | +| --- | --- | --- | +| `FlowCron` | `0x5cbfdec870ee216d` | `0x6dec6e64a13b881e` | +| `FlowCronUtils` | `0x5cbfdec870ee216d` | `0x6dec6e64a13b881e` | + +## Resources + +- [FlowCron GitHub repository] +- [Scheduled Transactions Documentation] + + + +[FlowCron GitHub repository]: https://github.com/onflow/flow-cron +[Scheduled Transactions Documentation]: scheduled-transactions.md +[TransactionHandler]: scheduled-transactions.md#create-a-scheduled-transaction +[Flow CLI]: ../../tools/flow-cli/index.md +[installation guide]: ../../tools/flow-cli/install.md +[Faucet]: https://faucet.flow.com/ +[deployment guide]: ../smart-contracts/deploying.md +[scripts documentation]: ../basics/scripts.md + + + +[CreateCronHandler.cdc]: https://github.com/onflow/flow-cron/blob/main/cadence/transactions/CreateCronHandler.cdc +[ScheduleCronHandler.cdc]: https://github.com/onflow/flow-cron/blob/main/cadence/transactions/ScheduleCronHandler.cdc +[CancelCronSchedule.cdc]: https://github.com/onflow/flow-cron/blob/main/cadence/transactions/CancelCronSchedule.cdc + + + +[GetCronInfo.cdc]: https://github.com/onflow/flow-cron/blob/main/cadence/scripts/GetCronInfo.cdc +[GetNextExecutionTime.cdc]: https://github.com/onflow/flow-cron/blob/main/cadence/scripts/GetNextExecutionTime.cdc +[GetCronScheduleStatus.cdc]: https://github.com/onflow/flow-cron/blob/main/cadence/scripts/GetCronScheduleStatus.cdc +[GetParsedCronExpression.cdc]: https://github.com/onflow/flow-cron/blob/main/cadence/scripts/GetParsedCronExpression.cdc + + + +[CounterTransactionHandler.cdc]: https://github.com/onflow/flow-cron/blob/main/cadence/tests/mocks/contracts/CounterTransactionHandler.cdc diff --git a/docs/build/cadence/advanced-concepts/metadata-views.md b/docs/build/cadence/advanced-concepts/metadata-views.md new file mode 100644 index 0000000000..f324621a63 --- /dev/null +++ b/docs/build/cadence/advanced-concepts/metadata-views.md @@ -0,0 +1,489 @@ +--- +title: Metadata Views +description: Learn about Flow's standardized way to represent and manage NFT metadata through MetadataViews, enabling consistent metadata interpretation across different platforms and marketplaces. +keywords: + - NFT metadata + - MetadataViews + - NFT standards + - metadata views + - Flow NFT + - ViewResolver + - NFT traits + - NFT royalties + - NFT editions + - contract metadata + - NFT display + - metadata implementation +sidebar_label: NFT Metadata Views +--- + +# Metadata views on Flow + +`MetadataViews` on Flow offer a standardized way to represent onchain metadata across different resources. This standard is primarily used for NFTs, but you can use it for any resource that wants a flexible standard for metadata, such as [scheduled transactions] + +Through integration of the metadata views standard, developers can ensure that different platforms and marketplaces can interpret the metadata of their resources in a unified manner. This means that when users visit different websites, wallets, and marketplaces, the metadata will be presented in a consistent manner, which ensures a uniform experience across various platforms. + +:::info + +It is important to understand this document so you can make meaningful decisions about how to manage your project's metadata as support for metadata views does not happen by default. Each project has unique metadata and therefore will have to define how they expose it in unique ways. + +::: + +:::info + +This document primarily uses NFTs as examples for how metadata views can be used, +but metadata views can be used for any kind of project or resource that wants +a standard way to represent metadata. + +::: + +A view is a standard Cadence struct that represents a specific type of metadata, such as a [Royalty specification]: + +```cadence +access(all) struct Royalty { + /// Where royalties should be paid to + access(all) let receiver: Capability<&{FungibleToken.Receiver}> + + /// The cut of the sale that should be taken for royalties. + access(all) let cut: UFix64 + + /// Optional description of the royalty + access(all) let description: String +} +``` + +or a [rarity description]: + +```cadence +access(all) struct Rarity { + /// The score of the rarity as a number + access(all) let score: UFix64? + + /// The maximum value of score + access(all) let max: UFix64? + + /// The description of the rarity as a string. + access(all) let description: String? +} +``` + +This guide acts as a specification for the correct ways to use each metadata view. Many of the standard metadata views do not have built-in requirements for how they are meant to be used, so it is important for developers to understand the content of this document so third party apps can integrate with their smart contracts as easily and effectively as possible. + +> If you'd like to follow along while we discuss the concepts below, see the [ExampleNFT contract]. Additionally, here is the source code for the [`ViewResolver` contract] and the [`MetadataViews` contract]. + +Flowty has also provided [a useful guide] for how to manage metadata views properly in order to be compatible with their marketplace. This guide is very useful because all of their advice is generally good advice for any NFT contract, regardless of what marketplace it uses. + +## Two levels of metadata: an overview + +Metadata in Cadence is structured at two distinct levels: + +1. **Contract-Level Metadata**: This provides an overarching description of the entire collection/project. Any metadata about individual resources is not included here. + +2. **Resource-Level Metadata**: This metadata relates to individual resources, often NFTs. It provides context, describes rarity, and highlights other distinctive attributes that distinguish one object from another within the same contract or collection. + +While these distinct levels describe different aspects of a project, they both use the same view system to represent the metadata and the same basic function calls to query the information, just from different places. + +## Understand `ViewResolver` and `MetadataViews.Resolver` + +When you consider Flow and how it handles metadata for resources, it is crucial to understand two essential interfaces: `ViewResolver` and `MetadataViews.Resolver`. [Interfaces] serve as blueprints for types that specify the required fields and methods that your contract or [composite type] must adhere to be considered a subtype of that interface. This guarantees that any contract that asserts adherence to these interfaces will possess a consistent set of functionalities that other applications or contracts can rely on. + +1. **`ViewResolver` for Contract-Level Metadata**: + - This interface ensures that **contracts**, particularly those encapsulating NFT collections, conform to the Metadata Views standard. + - Through the adoption of this interface, contracts can provide dynamic metadata that represents the entirety of the project. +2. **`MetadataViews.Resolver` (`ViewResolver.Resolver` in Cadence 1.0) for NFT-Level Metadata**: + - Used within **individual resources**, this interface ensures each resource adheres to the Metadata standard format. + - It focuses on the distinct attributes of an individual resource, such as its unique ID, name, description, and other defining characteristics. + +### Core functions + +Both the `ViewResolver` and `MetadataViews.Resolver` use these core functions: + +### The `getViews` function + +This function provides a list of supported metadata view types, which you can apply either by the contract (in the case of `ViewResolver`) or by an individual resource (in the case of `MetadataViews.Resolver`). + +```cadence +access(all) fun getViews(): [Type] { + return [ + Type(), + Type(), + ... + ] +} +``` + +### The `resolveView` function + +Whether used at the contract or resource level, this function's role is to deliver the actual metadata associated with a given view type. + +The caller provides the type of the view they want to query as the only argument, and the view is returned if it exists, and `nil` is returned if it doesn't. + +```cadence +access(all) fun resolveView(_ view: Type): AnyStruct? { + switch view { + case Type(): + ... + ... + } + return nil +} +``` + +As you can see, the return values of `getViews()` can be used as arguments +for `resolveView()` if you want to just iterate through all the views +that a resource implements. + +## Resource-level metadata implementation + +Resource-level metadata addresses the unique attributes of individual tokens within a collection. It provides structured information for each resource, such as its identifier, descriptive elements, royalties, and other associated metadata. When you incorporate this level of detail, it assures consistency and standardization among individual resources, which makes them interoperable and recognizable across various platforms and marketplaces. + +### Core properties + +In the code below, an NFT has properties such as its unique ID, name, description, and others. When we add the `NonFungibleToken.NFT` and by extension, the `MetadataViews.Resolver` to our NFT resource, we indicate that these variables will adhere to the specifications outlined in the MetadataViews contract for each of these properties. This facilitates interoperability within the Flow ecosystem and assures that the metadata of our NFT can be consistently accessed and understood by various platforms and services that interact with NFTs. + +```cadence +access(all) resource NFT: NonFungibleToken.NFT { + access(all) let id: UInt64 + access(all) let name: String + access(all) let description: String + access(all) let thumbnail: String + access(self) let royalties: [MetadataViews.Royalty] + access(self) let metadata: {String: AnyStruct} + ... +} +``` + +To make this possible though, it is **vital** that projects all use the standard metadata views in the same way, so third-party applications can consume them in standard ways. + +For example, many metadata views have `String`-typed fields. It is difficult to enforce that these fields are formatted in the correct way, so it is important for projects to be dilligent about how they use them. Take `Traits` for example, a commonly misused metadata view: + +```cadence +access(all) struct Trait { + // The name of the trait. Like Background, Eyes, Hair, etc. + access(all) let name: String + ... + ... +} +``` + +The name of the trait should be formatted in a way so that it is easy to display on a user-facing website. Many projects will use something like CamelCase for the value, so it looks like "HairColor", which is not pretty on a website. The correct format for this example would be "Hair Color". This is just one of many common view uses that projects need to be aware of to maximize the chance of success for their project. + +## Metadata views for NFTs + +`MetadataViews` types define how the NFT presents its data. When invoked, the system knows precisely which view to return, +which ensures that the relevant information is presented consistently across various platforms. + +In this section of the document, we will explore each metadata view and describe how projects should properly use them. + +### Display + +This view provides the bare minimum information about the NFT suitable for list or display purposes. When the `Display` type is invoked, it dynamically assembles the visual and descriptive information that is typically needed to showcase the NFT in marketplaces or collections. + +```cadence +case Type(): + return MetadataViews.Display( + name: self.name, + description: self.description, + thumbnail: MetadataViews.HTTPFile( + url: self.thumbnail + ) + ) +``` + +If the thumbnail is a HTTP resource: + +```cadence +thumbnail : MetadataViews.HTTPFile(url: *Please put your url here) +``` + +If the thumbnail is an IPFS resource: + +```cadence +// +thumbnail : MetadataViews.IPFSFile( + cid: thumbnail cid, // Type + path: ipfs path // Type specify path if the cid is a folder hash, otherwise use nil here +) +``` + +![MetadataViews.Display](display.png 'Display') + +:::info + +SVG field should be sent as `thumbnailURL`, +should be base64 encoded, and should have a dataURI prefix, like so: + +``` +data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InJlZCIvPjwvc3ZnPg== +``` + +::: + +### Editions + +The `Editions` view provides intricate details about the particular release of an NFT within a set of NFTs with the same metadata. This can include information about the number of copies in an edition, the specific NFT's sequence number within that edition, or its inclusion in a limited series. When the `Editions` view is queried, it retrieves this data, and provides collectors with the information they need to comprehend the rarity and exclusivity of the NFT they are interested in. + +An NFT can also be part of multiple editions, which is why the `Editions` view can hold any number of `Edition` structs in an array. + +For example, if an NFT is number 11 of 30 of an exclusive edition, the code to return the `Editions` view would look like this: + +```cadence +case Type(): + let editionInfo = MetadataViews.Edition( + name: "Example NFT Edition", + number: 11, + max: 30 + ) + return MetadataViews.Editions([editionInfo]) +``` + +### Serial number metadata + +The `Serial` metadata provides the unique serial number of the NFT, akin to a serial number on a currency note or a VIN on a car. This serial number is a fundamental attribute that certifies the individuality of each NFT and is critical for identification and verification processes. Serial numbers are expected to be unique among other NFTs from the same project. +Many projects already use the NFT resource's [resource's globally unique UUID] as the ID, so they will typically also use that as the serial number. + +```cadence +case Type(): + return MetadataViews.Serial(self.uuid) +``` + +### Royalties metadata + +Royalty information is vital for the sustainable economics of the creators in the NFT space. [The `Royalties` metadata view] defines the specifics of any royalty agreements in place, such as the percentage of sales revenue that will go to the original creator or other stakeholders on secondary sales. + +Each royalty view contains a fungible token receiver capability where royalties should be paid: + +```cadence +access(all) struct Royalty { + + access(all) let receiver: Capability<&{FungibleToken.Receiver}> + + access(all) let cut: UFix64 +} +``` + +here is an example of how an NFT might return a `Royalties` view: + +```cadence +case Type(): + // Assuming each 'Royalty' in the 'royalties' array has 'cut' and 'description' fields + let royalty = + MetadataViews.Royalty( + // The beneficiary of the royalty: in this case, the contract account + receiver: ExampleNFT.account.capabilities.get<&AnyResource{FungibleToken.Receiver}>(/public/GenericFTReceiver), + // The percentage cut of each sale + cut: 0.05, + // A description of the royalty terms + description: "Royalty payment to the original creator" + ) + } + return MetadataViews.Royalties(detailedRoyalties) +``` + +If someone wants to make a listing for their NFT on a marketplace, the marketplace can check to see if the royalty receiver accepts the seller's desired fungible token by calling the `receiver.getSupportedVaultTypes(): {Type: Bool}` function via the `receiver` reference: + +```cadence +let royaltyReceiverRef = royalty.receiver.borrow() + ?? panic("Could not borrow a reference to the receiver") +let supportedTypes = receiverRef.getSupportedVaultTypes() +if supportedTypes[**royalty.getType()**] { + // The type is supported, so you can deposit + recieverRef.deposit(<-royalty) +} else { + // if it is not supported, you can do something else, + // like revert, or send the royalty tokens to the seller instead +} +``` + +If the desired type is not supported, the marketplace has a few options. They could either get the address of the receiver with the `receiver.owner.address` field and check to see if the account has a receiver for the desired token, they could perform the sale without a royalty cut, or they could abort the sale since the token type isn't accepted by the royalty beneficiary. + +You can see example implementations of royalties in the `ExampleNFT` contract and the associated transactions and scripts. NFTs are often sold for a variety of currencies, so the royalty receiver should ideally be a [fungible token switchboard] receiver that forwards any received tokens to the correct vault in the receiving account. + +#### Important instructions for royalty receivers + +If you plan to set your account as a receiver of royalties, you'll likely want to be able to accept as many token types as possible. This is possible with the `FungibleTokenSwitchboard`. If you initialize a switchboard in your account, it can accept any generic fungible token and route it to the correct vault in your account. + +Therefore, if you want to receive royalties, you should set up your account with the [`setup_royalty_account_by_paths.cdc`] transaction. + +This will link generic public path from `MetadataViews.getRoyaltyReceiverPublicPath() to the capability paths and types that you provide as arguments. Then you can use that public path and capability for your royalty receiver. + +### External URL metadata + +The ExternalURL view returns to an associated webpage URL, which provides additional content or information about the NFT. This can be a website, social media page, or anything else related to the project that uses a URL. + +```cadence +case Type(): + return MetadataViews.ExternalURL("".concat(self.id.toString())) +``` + +### Traits metadata + +The [`Trait`] view type encapsulates the unique attributes of an NFT, like any visual aspects or category-defining properties. These can be essential for marketplaces that need to sort or filter NFTs based on these characteristics. When you return trait views as recommended, you can fit the data in the places you want. + +```cadence +access(all) struct Trait { + // The name of the trait. Like Background, Eyes, Hair, etc. + access(all) let name: String + + // The underlying value of the trait + access(all) let value: AnyStruct + + // displayType is used to show some context about what this name and value represent + // for instance, you could set value to a unix timestamp, and specify displayType as "Date" to tell + // platforms to consume this trait as a date and not a number + access(all) let displayType: String? + + // Rarity can also be used directly on an attribute. + // This is optional because not all attributes need to contribute to the NFT's rarity. + access(all) let rarity: Rarity? +``` + +The traits view is extremely important to get right, because many third-party apps and marketplaces are heavily reliant on it to properly display the entirety of your NFTs. For example, the names and values of the traits likely display on a user-facing website, so it is important to return them in a presentable form, such as `First Name`, instead of `first_name` or `firstName`. + +Additionally, limit your `value` field to primitive types like `String`, `Int`, or `Bool`. + +Furthermore, the `displayType` is important as well, because it tells websites how to display the trait properly. Developers should not just default to `String` or `Integer` for all their display types. When applicable, the display types to accurately reflect the data that needs to be displayed. + +![MetadataViews.Traits](traits_String.png 'traits_String') + +#### Note: always prefer wrappers over single views + +When you expose a view that could have multiple occurrences on a single NFT, such as `Edition`, `Royalty`, `Media` or `Trait`, always use the wrapper view (such as `Editions`, `Royalties`, etc), even if there is only a single occurrence. The wrapper view is always the plural version of the single view name and can be found below the main view definition in the `MetadataViews` contract. + +When you resolve the view, the wrapper view should be the returned value, instead of return the single view or just an array of several occurrences of the view. + +```cadence +access(all) fun resolveView(_ view: Type): AnyStruct? { + switch view { + case Type(): + let editionInfo = MetadataViews.Edition(name: "Example NFT Edition", number: self.id, max: nil) + let editionList: [MetadataViews.Edition] = [editionInfo] + // return the wrapped view + return MetadataViews.Editions( + editionList + ) + } +} +``` + +## Contract-level metadata implementation + +Contract-level metadata provides a holistic view of an NFT collection. It captures complete attributes and contextual information about the entire set, rather than specifics of individual tokens. These views describe attributes at the collection or series level rather than individual NFTs. These views should still should be queryable via individual NFTs though. To accomplish this, you can forward the call from the NFT's `resolveView()` method to the contract's `resolveView()` method, like so: + +```cadence +/// this line is in `ExampleNFT.NFT.resolveView()` +case Type(): + return ExampleNFT.getCollectionDisplay(nftType: Type<@ExampleNFT.NFT>()) +``` + +### NFTCollectionData + +This view provides paths and types related to the NFT collection's storage and access within the smart contract. The information in this view is critical for you to understand how to interact with a collection. + +```cadence +case Type(): + return MetadataViews.NFTCollectionData( + // where should the collection be saved? + storagePath: ExampleNFT.CollectionStoragePath, + // where to borrow public capabilities from? + publicPath: ExampleNFT.CollectionPublicPath, + // Important types for how the collection should be linked + publicCollection: Type<&ExampleNFT.Collection>(), + publicLinkedType: Type<&ExampleNFT.Collection>(), + // function that can be accessed to create an empty collection for the project + createEmptyCollectionFunction: (fun(): @{NonFungibleToken.Collection} { + return <-ExampleNFT.createEmptyCollection(nftType: Type<@ExampleNFT.NFT>()) + }) + ) +``` + +Here, `NFTCollectionData` specifies several important elements related to how the collection is stored and accessed on the Flow blockchain. It provides information on storage paths and access control paths for both public and private data, as well as linked types that specify what capabilities are publicly available (like collection, receiver, or provider interfaces). + +### NFTCollectionDisplay + +This view describes the collection with visual elements and metadata that are useful for display purposes, such as in a marketplace or gallery. Many third party apps need this in order to display high-level information about an NFT project properly. + +```cadence +case Type(): + let media = MetadataViews.Media( + file: MetadataViews.HTTPFile( + url: "" + ), + mediaType: "image/svg+xml" + ) + return MetadataViews.NFTCollectionDisplay( + name: "The Example Collection", + description: "This collection is used as an example to help you develop your next Flow NFT.", + externalURL: MetadataViews.ExternalURL(""), + squareImage: media, + bannerImage: media, + socials: { + "twitter": MetadataViews.ExternalURL("") + } + ) +``` + +In the example above, the `NFTCollectionDisplay` not only offers fundamental metadata like the collection's name and description but also provides image URLs for visual representations of the collection (`squareImage` and `bannerImage`) and external links, including social media profiles. + +![MetadataViews.CollectionDisplay](collectionDisplay.png 'CollectionDisplay') + +### Contract-borrowing Metadata + +With the contract borrowing feature, the [ViewResolver] interface on contracts can be borrowed directly without needing to import the contract first. Views can be resolved directly from there. + +As an example, you might want to allow your contract to resolve `NFTCollectionData` and `NFTCollectionDisplay` so that platforms do not need to find an NFT that belongs to your contract to get information about how to set up or show your collection. + +```cadence +import ViewResolver from 0xf8d6e0586b0a20c7 +import MetadataViews from 0xf8d6e0586b0a20c7 + +access(all) fun main(addr: Address, name: String): StoragePath? { + let t = Type() + let borrowedContract = getAccount(addr).contracts.borrow<&ViewResolver>(name: name) ?? panic("contract could not be borrowed") + + let view = borrowedContract.resolveView(t) + if view == nil { + return nil + } + + let cd = view! as! MetadataViews.NFTCollectionData + return cd.storagePath +} +``` + +Will Return + +```cadence +{"domain":"storage","identifier":"exampleNFTCollection"} +``` + +## More + +It's crucial that developers who want to deploy NFTs on Flow understand `MetadataViews` and the core functions associated with it With these views and functions, NFTs can maintain a consistent presentation across various platforms and marketplaces and foster interoperability between contracts and applications in the Flow ecosystem. + +To gain a deeper understanding of implementing the MetadataView standard, check out our documentation on "How to Create an NFT Project on Flow". It provides an introduction for how to integrate these standards into your NFT contracts. + +- See the [API reference for a complete list of Metadata functions]. +- Check out [an Example NFT project] which implements `MetadataViews`. +- Read [the NFT Guide]for an introduction to implementation. + + + +[scheduled transactions]: ./scheduled-transactions.md +[Royalty specification]: https://github.com/onflow/flow-nft?tab=readme-ov-file#royalty-view +[rarity description]: https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L614 +[ExampleNFT contract]: https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc +[`ViewResolver` contract]: https://github.com/onflow/flow-nft/blob/master/contracts/ViewResolver.cdc +[`MetadataViews` contract]: https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc +[a useful guide]: https://docs.flowty.io/developer-docs/ +[Interfaces]: https://cadence-lang.org/docs/language/interfaces +[composite type]: https://cadence-lang.org/docs/language/composite-types +[resource's globally unique UUID]: https://cadence-lang.org/docs/language/resources#resource-identifier +[The `Royalties` metadata view]: https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L295 +[fungible token switchboard]:https://github.com/onflow/flow-ft?tab=readme-ov-file#fungible-token-switchboard +[`setup_royalty_account_by_paths.cdc`]: https://github.com/onflow/flow-ft/blob/master/transactions/switchboard/setup_royalty_account_by_paths.cdc +[`Trait`]: https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc#L655 +[ViewResolver]: https://github.com/onflow/flow-nft/blob/master/contracts/ViewResolver.cdc +[API reference for a complete list of Metadata functions]: https://developers.flow.com/build/cadence/core-contracts/flow-nft/MetdataViews/MetadataViews +[an Example NFT project]: https://github.com/onflow/flow-nft/blob/master/contracts/ExampleNFT.cdc +[the NFT Guide]: ../../../blockchain-development-tutorials/tokens/nft-cadence.md \ No newline at end of file diff --git a/docs/build/cadence/advanced-concepts/passkeys.md b/docs/build/cadence/advanced-concepts/passkeys.md new file mode 100644 index 0000000000..45dc46b940 --- /dev/null +++ b/docs/build/cadence/advanced-concepts/passkeys.md @@ -0,0 +1,487 @@ +--- +title: Passkeys +description: Implement passkeys on Flow using WebAuthn, covering key extraction, challenges, signature formatting for Flow, and signature extensions. +keywords: + - passkeys + - WebAuthn + - authentication + - ECDSA P256 + - ES256 + - Flow account keys + - wallet integration + - credential management + - signature verification + - biometric authentication + - FIDO2 + - multi-factor authentication + - passwordless authentication + - Flow transactions + - public key cryptography +sidebar_position: 9 +--- + +# Passkeys + +This is a wallet‑centric, high‑level guide (per [FLIP 264: WebAuthn Credential Support]) with code snippets covering passkey registration and signing on Flow, focusing on nuances for passkey signing and account keys: + +1. Create a passkey and add a Flow account key +2. Sign a transaction with the user's passkey (includes conversion, extension, and submission) + +It accompanies the [PoC demo] for reference and cites the FLIP where behavior is normative. + +:::note Platform-specific APIs + +This tutorial focuses on the **Web Authentication API** (WebAuthn) for browser-based applications. Other platforms such as iOS, Android, and desktop applications will require platform-specific APIs (such as Apple's [Authentication Services] or Android's [Credential Manager]), but the underlying concepts—credential creation, challenge signing, and signature formatting—remain the same across all platforms. + +::: + +## What you'll learn + +After you complete this guide, you'll be able to: + +- Create a passkey and derive a Flow‑compatible public key. +- Generate the correct challenge for signing transactions (wallet sets SHA2‑256(signable)). +- Convert a WebAuthn ECDSA DER signature into Flow's raw `r||s` format and attach the transaction signature extension. + +## Passkey benefits + +**Sign transactions securely** +Users can sign Flow transactions with passkeys while the private key stays securely stored within the authenticator. This reduces the risk of key extraction attacks and phishing attempts. + +**Authenticate across devices** +Users can scan a QR code displayed on a desktop browser with a mobile device to approve transactions. Cloud-synchronized passkeys (such as those stored in Apple iCloud or Google Password Manager) allow authentication across multiple devices without manual key transfers. + +**Authenticate with platform-based security** +Users can sign transactions directly on devices with built-in authenticators, such as Face ID on iPhones or Windows Hello on Windows PCs. This approach allows native transaction signing without the need for an external security key. + +**Recover access with cloud-synced passkeys** +Cloud-synced passkeys help users recover access if they lose a device, though this introduces trade-offs between convenience and self-custody (see [Limitations of passkeys]. + +**Work with multi-key accounts** +Combine passkeys with other authentication types with Flow's native [multi-key account support] to build secure recovery options and shared access patterns with weighted keys. + +## Prerequisites + +- Working knowledge of modern frontend (React/Next.js) and basic backend. +- Familiarity with WebAuthn/Passkeys concepts and platform constraints. +- Flow Command Line (FCL) installed and configured for your app. +- Flow accounts and keys: [Signature and Hash Algorithms]. + +## Registration + +When a user generates a passkey via [navigator.credentials.create()] with `{ publicKey }`, the authenticator returns an attestation that contains the new credential's public key. On Flow, you can register that public key on an account if the algorithm of the requested passkey is either `ES256` or `ES256k`. This guide demonstrates an `ES256` passkey which translates to an `ECDSA_P256` Flow key paired with `SHA2_256` hashing. Alternatively, an `ES256k` passkey translates to an `ECDSA_secp256k1` Flow key paired with `SHA2_256` hashing. + +High‑level steps: + +1. On the client, generate `PublicKeyCredentialCreationOptions` with: + - `pubKeyCredParams`'s `alg` equal to `ES256` (`-7`) + - the RP id is derived from to the web origin + - the challenge equal to an arbitrary constant +2. On the client, call `navigator.credentials.create()`. +3. Verify attestation if necessary and extract the public key (P‑256 in this guide). Convert it to raw uncompressed 64‑byte `X||Y` hex string as expected by Flow. +4. Submit a transaction to add the key to the Flow account with weight and algorithms: + - Signature algorithm: `ECDSA_P256` + - Hash algorithm: `SHA2_256` + +:::info + +Libraries like SimpleWebAuthn can parse the COSE key and produce the raw public key bytes required for onchain registration. Ensure you normalize into the exact raw byte format Flow expects before it writes to the account key. + +::: + +### Build creation options and create credential + +Minimum example — wallet‑mode registration: + +This builds `PublicKeyCredentialCreationOptions` for a wallet RP with a constant registration challenge and ES256 (P‑256) so you can register the newly-created public key on a Flow account. + +```tsx +// In a wallet (RP = wallet origin). The challenge satisfies API & correlates request/response. +// Use a stable, opaque user.id per wallet user (do not randomize per request). + +const rp = { name: "Passkey Wallet", id: window.location.hostname } as const +const user = { + id: getStableUserIdBytes(), // Uint8Array (16–64 bytes) stable per user + name: "flow-user", + displayName: "Flow User", +} as const + +const creationOptions: PublicKeyCredentialCreationOptions = { + challenge: new TextEncoder().encode("flow-wallet-register"), // constant is acceptable in wallet-mode; wallet providers may choose and use a constant value as needed for correlation + rp, + user, + pubKeyCredParams: [ + { type: "public-key", alg: -7 }, // ES256 (ECDSA on P-256 with SHA-256) + // Optionally ES256K (ECDSA on secp256k1 with SHA-256) if the device supports secp256k1 keys: + // { type: "public-key", alg: -47 }, + ], + authenticatorSelection: { userVerification: "preferred" }, + timeout: 60_000, + attestation: "none", +} + +const credential = await navigator.credentials.create({ publicKey: creationOptions }) + +// Send to wallet-core (or local) to extract COSE ECDSA P-256 public key (verify attestation if necessary) +// Then register the raw uncompressed key bytes on the Flow account as ECDSA_P256/SHA2_256 (this guide's choice) +``` + +:::tip RP ID for non-browser platforms + +For web applications, `rpId` is set to `window.location.hostname`. For native mobile and desktop applications, use your app's identifier instead: +- **iOS**: Use your app's bundle identifier (such as `com.example.wallet`) or an associated domain. +- **Android**: Use your app's package name (such as `com.example.wallet`) or an associated domain. +- **Desktop**: Use your application identifier or registered domain. + +The `rpId` should remain consistent across credential creation and assertion for the same user account. However, Flow does not validate or enforce this consistency. +::: + +### Extract and normalize public key + +Client-side example — extract COSE ECDSA public key (no verification) and derive raw uncompressed 64-byte `X||Y` hex suitable for Flow key registration: + +This parses the `attestationObject` to locate the COSE EC2 `credentialPublicKey`, reads the x/y coordinates, and returns raw uncompressed 64-byte `X||Y` hex suitable for Flow key registration. Attestation verification is intentionally omitted here. + +```tsx +// Uses a small CBOR decoder (e.g., 'cbor' or 'cbor-x') to parse attestationObject +import * as CBOR from 'cbor' + +function toHex(bytes: Uint8Array): string { + return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('') +} + +function extractCosePublicKeyFromAttestation(attObj: Uint8Array): Uint8Array { + // attestationObject is a CBOR map with 'authData' + const decoded: any = CBOR.decode(attObj) + const authData = new Uint8Array(decoded.authData) + + // Parse authData (WebAuthn spec): + // rpIdHash(32) + flags(1) + signCount(4) = 37 bytes header + let offset = 37 + // aaguid (16) + offset += 16 + // credentialId length (2 bytes, big-endian) + const credIdLen = (authData[offset] << 8) | authData[offset + 1] + offset += 2 + // credentialId (credIdLen bytes) + offset += credIdLen + // The next CBOR structure is the credentialPublicKey (COSE key) + return authData.slice(offset) +} + +function coseEcP256ToUncompressedXYHex(coseKey: Uint8Array): string { + // COSE EC2 key is a CBOR map; for P-256, x = -2, y = -3 + const m: Map = CBOR.decode(coseKey) + const x = new Uint8Array(m.get(-2)) + const y = new Uint8Array(m.get(-3)) + if (x.length > 32 || y.length > 32) throw new Error('Invalid P-256 coordinate lengths') + const xy = new Uint8Array(64) + xy.set(x, 32 - x.length) + xy.set(y, 64 - y.length) + return toHex(xy) // 64-byte X||Y hex, no 0x or 0x04 prefix +} + +// Usage +const cred = (await navigator.credentials.create({ publicKey: creationOptions })) as PublicKeyCredential +const att = cred.response as AuthenticatorAttestationResponse +const attObj = new Uint8Array(att.attestationObject as ArrayBuffer) +const cosePubKey = extractCosePublicKeyFromAttestation(attObj) +const publicKeyHex = coseEcP256ToUncompressedXYHex(cosePubKey) +``` + + + +### Add key to account + +Now that you have the user's public key, provision a Flow account with that key. Account creation (or to add key to an account) requires payment. In practice, account instantiation typically occurs on the wallet provider's backend service. + +In the PoC demo, we used a test API to provision an account with the public key: + +```ts +const ACCOUNT_API = "https://wallet.example.com/api/accounts/provision" + +export async function createAccountWithPublicKey( + publicKeyHex: string, + _opts?: {signAlgo?: number; hashAlgo?: number; weight?: number} +): Promise { + const trimmed = publicKeyHex + const body: ProvisionAccountRequest = { + publicKey: trimmed, + signatureAlgorithm: "ECDSA_P256", + hashAlgorithm: "SHA2_256", + } + const res = await fetch(ACCOUNT_API, { + method: "POST", + headers: {Accept: "application/json", "Content-Type": "application/json"}, + body: JSON.stringify(body), + }) + if (!res.ok) throw new Error(`Account API error: ${res.status}`) + const json = (await res.json()) as ProvisionAccountResponse + if (!json?.address) throw new Error("Account API missing address in response") + return json.address +} +``` + +:::note + +In production, this would be a service owned by the wallet provider that creates the account and attaches the user's public key, for reasons like payment handling, abuse prevention, telemetry, and correlation as needed. + +::: + +## Signing + +### Generate the challenge + +- Assertion (transaction signing): Wallet sets `challenge` to the SHA2‑256 of the signable transaction message (payload or envelope per signer role). No server‑sent or random challenge is used. Flow includes a domain‑separation tag in the signable bytes. + +Minimal example — derive signable message and hash (per FLIP): + +Compute the signer‑specific signable message and hash it with SHA2‑256 to produce the WebAuthn `challenge` (no server‑generated nonce is used in wallet mode). + +```tsx +// Imports for helpers used to build the signable message +import { encodeMessageFromSignable, encodeTransactionPayload } from '@onflow/fcl' +// Hash/encoding utilities (example libs) +import { sha256 } from '@noble/hashes/sha256' +import { hexToBytes } from '@noble/hashes/utils' + +// Inputs: +// - signable: object containing the voucher/payload bytes (e.g., from a ready payload) +// - address: the signing account address (hex string) + +declare const signable: any +declare const address: string + +// 1) Encode the signable message for this signer (payload vs envelope) +const msgHex = encodeMessageFromSignable(signable, address) +const payloadMsgHex = encodeTransactionPayload(signable.voucher) +const role = msgHex === payloadMsgHex ? "payload" : "envelope" + +// 2) Compute SHA2-256(msgHex) -> 32-byte challenge +const signableHash: Uint8Array = sha256(hexToBytes(msgHex)) + +// 3) Call navigator.credentials.get with challenge = signableHash +// (see next subsection for a full getAssertion example) +``` + +:::info + +`encodeMessageFromSignable` and `encodeTransactionPayload` are FCL‑specific helpers. If you don't use FCL, construct the Flow signable transaction message yourself (payload for proposer/authorizer, envelope for payer, prepended by the transaction domain tag), then compute `SHA2‑256(messageBytes)` for the challenge. The payload encoding shown here applies regardless of wallet implementation; the helper calls are simply conveniences from FCL. + +::: + +### Request assertion + +Minimal example — wallet assertion: + +Build [PublicKeyCredentialRequestOptions] and request an assertion with the transaction hash as `challenge`. `rpId` must match the wallet domain. When the wallet has mapped the active account to a credential, include `allowCredentials` with that credential ID to avoid extra prompts. You can omit it, which is permissible for discoverable credentials. You will invoke [navigator.credentials.get()]. + +```tsx +// signableHash is SHA2-256(signable message: payload or envelope) +declare const signableHash: Uint8Array +declare const credentialId: Uint8Array // Credential ID for the active account (from prior auth) + +const requestOptions: PublicKeyCredentialRequestOptions = { + challenge: signableHash, + rpId: window.location.hostname, + userVerification: "preferred", + timeout: 60_000, + allowCredentials: [ + { + type: "public-key", + id: credentialId, + }, + ], +} + +const assertion = (await navigator.credentials.get({ + publicKey: requestOptions, +})) as PublicKeyCredential + +const { authenticatorData, clientDataJSON, signature } = + assertion.response as AuthenticatorAssertionResponse +``` + +:::info + +- **Credential selection**: Wallets typically know which credential corresponds to the user's active account (selected during authentication/authorization), so they should pass that credential via `allowCredentials` to scope selection and minimize prompts. For discoverable credentials, you can omit `allowCredentials`, which lets the authenticator surface available credentials. See [WebAuthn specifications] for guidance. +- **RP ID consistency**: The `rpId` used here should match what was used during credential creation. However, Flow does not validate or enforce this (transactions would still pass even if different). For non-browser platforms, use the same app identifier (bundle ID, package name, and so on.) as in registration. + +::: + +### Convert and attach signature + +WebAuthn assertion signatures in this guide are ECDSA P‑256 over SHA‑256 and are typically returned in ASN.1/DER form. Flow expects raw 64‑byte signatures: `r` and `s` each 32 bytes, concatenated (`r || s`). + +- Convert the DER `signature` to Flow raw `r||s` (64 bytes) and attach with `addr` and `keyId`. +- Build the transaction signature extension as specified: `extension_data = 0x01 || RLP([authenticatorData, clientDataJSON])`. + +Minimal example — convert and attach for submission: + +Convert the DER signature to Flow raw `r||s` and build `signatureExtension = 0x01 || RLP([authenticatorData, clientDataJSON])` per the FLIP, then compose the Flow transaction signature object for inclusion in your transaction. + +```tsx +import { encode as rlpEncode } from 'rlp' +import { bytesToHex } from '@noble/hashes/utils' + +// Inputs from previous steps +declare const address: string // 0x-prefixed Flow address +declare const keyId: number // Account key index used for signing +declare const signature: Uint8Array // DER signature from WebAuthn assertion +declare const clientDataJSON: Uint8Array +declare const authenticatorData: Uint8Array + +// 1) DER -> raw r||s (64 bytes), implementation below or similar +const rawSig = derToRawRS(signature) + +// 2) Build extension_data per FLIP: 0x01 || RLP([authenticatorData, clientDataJSON]) +const rlpPayload = rlpEncode([authenticatorData, clientDataJSON]) as Uint8Array | Buffer +const rlpBytes = rlpPayload instanceof Uint8Array ? rlpPayload : new Uint8Array(rlpPayload) +const extension_data = new Uint8Array(1 + rlpBytes.length) +extension_data[0] = 0x01 +extension_data.set(rlpBytes, 1) + +// 3) Compose Flow signature object +const flowSignature = { + addr: address, // e.g., '0x1cf0e2f2f715450' + keyId, // integer key index + signature: '0x' + bytesToHex(rawSig), + signatureExtension: extension_data, +} +``` + +#### Submit the signature + +Return the signature data to the application that initiated signing. The application should attach it to the user transaction for the signer (`addr`, `keyId`) and submit the transaction to the network. + +See [Transactions] for how signatures are attached per signer role (payload vs envelope) and how submissions are finalized. + +#### Helper: derToRawRS + +```tsx +// Minimal DER ECDSA (r,s) -> raw 64-byte r||s +function derToRawRS(der: Uint8Array): Uint8Array { + let offset = 0 + if (der[offset++] !== 0x30) throw new Error("Invalid DER sequence") + const seqLen = der[offset++] // assumes short form + if (seqLen + 2 !== der.length) throw new Error("Invalid DER length") + + if (der[offset++] !== 0x02) throw new Error("Missing r INTEGER") + const rLen = der[offset++] + let r = der.slice(offset, offset + rLen) + offset += rLen + if (der[offset++] !== 0x02) throw new Error("Missing s INTEGER") + const sLen = der[offset++] + let s = der.slice(offset, offset + sLen) + + // Strip leading zeros and left-pad to 32 bytes + r = stripLeadingZeros(r) + s = stripLeadingZeros(s) + const r32 = leftPad32(r) + const s32 = leftPad32(s) + const raw = new Uint8Array(64) + raw.set(r32, 0) + raw.set(s32, 32) + return raw +} + +function stripLeadingZeros(bytes: Uint8Array): Uint8Array { + let i = 0 + while (i < bytes.length - 1 && bytes[i] === 0x00) i++ + return bytes.slice(i) +} + +function leftPad32(bytes: Uint8Array): Uint8Array { + if (bytes.length > 32) throw new Error("Component too long") + const out = new Uint8Array(32) + out.set(bytes, 32 - bytes.length) + return out +} +``` +## Notes from the PoC + +- The [PoC demo] demonstrates reference flows for passkey creation and assertion, such as: + - Extract and normalize the ECDSA P‑256 public key for Flow. + - Build the correct challenge . + - Convert DER signatures to raw `r||s`. + - Package WebAuthn fields as signature extension data. + +> Align your implementation with the FLIP to ensure your extension payloads and verification logic match network expectations. + +## Security and UX considerations + +- Use `ES256` or `ES256k` as algorithms to create Flow account compatible keys. +- Clearly communicate platform prompts and recovery paths; passkeys UX can differ across OS/browsers. +- Replay protection: Flow uses on‑chain proposal‑key sequence numbers; see [Replay attacks]. +- Optional wallet backend: store short‑lived correlation data or rate‑limits as needed (not required). + +## Limitations of passkeys + +**Functionality varies by authenticator** +Some security keys do not support biometric authentication, which requires users to enter a PIN instead. Because WebAuthn does not provide access to private keys, users must either store their passkey securely or turn on cloud synchronization for recovery. + +**Cloud synchronization introduces risks** +Cloud-synced passkeys improve accessibility but also create risks if a cloud provider is compromised or if a user loses access to their cloud account. Users who prefer full self-custody can use hardware-based passkeys that do not rely on cloud synchronization. + +**Passkeys cannot be exported** +Users cannot transfer a passkey between different authenticators. For example, a passkey created on a security key cannot move to another device unless it syncs through a cloud provider. To avoid losing access, users should set up authentication on multiple devices or combine passkeys with [multi-key account configurations] for additional recovery options. + + +## Credential management (wallet responsibilities) + +Wallet providers should persist credential metadata to support seamless signing, rotation, and recovery: + +- Map `credentialId` ↔ Flow `addr` (and `keyId`) for the active account. +- Store `rpId`, user handle, and (optionally) `aaguid`/attestation info for risk decisions. +- Support multiple credentials per account and revocation/rotation workflows. +- Enforce nonce/sequence semantics and rate limits server-side as needed. + +See [WebAuthn Credential Support (FLIP)] for rationale and wallet‑mode guidance. + +## Conclusion + +In this tutorial, you integrated passkeys (WebAuthn) with Flow for both registration and signing. + +Now that you have completed the tutorial, you should be able to: + +- Create a WebAuthn credential and derive a Flow‑compatible public key. +- Generate the correct challenge for signing transactions (wallet sets SHA2‑256(signable)). +- Convert a WebAuthn ECDSA DER signature into Flow's raw `r||s` format and attach the transaction signature extension. + +### Further reading + +- Review signing flows and roles: [Transactions] +- Account keys: [Signature and Hash Algorithms] +- Web Authentication API (MDN): [Web Authentication API] +- Flow Client Library (FCL): [Flow Client Library] +- Wallet Provider Spec: [Wallet Provider Spec] +- Track updates: [FLIP 264: WebAuthn Credential Support] + + + +[WebAuthn Credential Support (FLIP)]: https://github.com/onflow/flips/blob/cfaaf5f6b7c752e8db770e61ec9c180dc0eb6543/protocol/20250203-webauthn-credential-support.md +[PoC demo]: https://github.com/onflow/passkey-wallet-demo +[FLIP 264: WebAuthn Credential Support]: https://github.com/onflow/flips/blob/cfaaf5f6b7c752e8db770e61ec9c180dc0eb6543/protocol/20250203-webauthn-credential-support.md +[Authentication Services]: https://developer.apple.com/documentation/authenticationservices, +[Credential Manager]: https://developer.android.com/identity/sign-in/credential-manager +[Web Authentication API]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API +[navigator.credentials.create()]: https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/create +[PublicKeyCredentialCreationOptions]: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions +[PublicKeyCredentialRequestOptions]: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialRequestOptions +[navigator.credentials.get()]: https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get +[PublicKeyCredential]: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential +[AuthenticatorAttestationResponse]: https://developer.mozilla.org/en-US/docs/Web/API/AuthenticatorAttestationResponse +[AuthenticatorAssertionResponse]: https://developer.mozilla.org/en-US/docs/Web/API/AuthenticatorAssertionResponse +[Replay attacks]: https://github.com/onflow/flips/blob/cfaaf5f6b7c752e8db770e61ec9c180dc0eb6543/protocol/20250203-webauthn-credential-support.md#replay-attacks +[Transactions]: ../basics/transactions.md +[Signature and Hash Algorithms]: ../basics/accounts.md +[Flow Client Library]: ../../tools/clients/fcl-js/index.md +[Wallet Provider Spec]: ../../tools/wallet-provider-spec/index.md +[WebAuthn specifications]: https://www.w3.org/TR/webauthn-3 +[Limitations of passkeys]: #limitations-of-passkeys +[multi-key account support]: ../basics/accounts.md#account-keys +[PoC demo]: https://github.com/onflow/passkey-wallet-demo +[multi-key account configurations]: ../basics/accounts.md#account-keys + + + diff --git a/docs/build/advanced-concepts/randomness.md b/docs/build/cadence/advanced-concepts/randomness.md similarity index 53% rename from docs/build/advanced-concepts/randomness.md rename to docs/build/cadence/advanced-concepts/randomness.md index 70d5c03953..5c4020026f 100644 --- a/docs/build/advanced-concepts/randomness.md +++ b/docs/build/cadence/advanced-concepts/randomness.md @@ -1,10 +1,10 @@ --- -title: Flow On-chain Randomness in Cadence -description: Learn how Flow provides native, secure on-chain randomness at the protocol level, enabling developers to build applications with verifiable, unpredictable outcomes without external oracles. +title: Flow Onchain Randomness in Cadence +description: Learn how Flow provides native, secure onchain randomness at the protocol level, enabling developers to build applications with verifiable, unpredictable outcomes without external oracles. keywords: - randomness - VRF - - on-chain randomness + - onchain randomness - revertibleRandom - random beacon - commit-reveal @@ -19,35 +19,31 @@ sidebar_label: VRF (Randomness) in Cadence # Randomness on FLOW -Flow enhances blockchain functionality and eliminates reliance on external oracles by providing native onchain randomness at the protocol level. This secure, decentralized feature empowers developers to build a variety of applications with truly unpredictable, transparent, and fair outcomes, achieved with greater efficiency. +Flow provides native onchain randomness at the protocol level, which enhances blockchain functionality and eliminates reliance on external oracles. This secure, decentralized feature empowers developers to build a variety of applications with truly unpredictable, transparent, and fair outcomes, achieved with greater efficiency. -Flow onchain randomness delivers immediate random values within transactions, bypassing the latency and complexity of oracle integration. Developers can obtain verifiably random results with a single line of Cadence code, streamlining the development process and enhancing the performance of decentralized applications. +Flow onchain randomness delivers immediate random values within transactions and bypasses the latency and complexity of oracle integration. Developers can obtain verifiably random results with a single line of Cadence code, which streamlines the development process and enhances the performance of decentralized applications. -## Use Cases of Onchain Randomness +## Use Cases of onchain randomness -- **Gaming:** Integrates fairness and unpredictability into gameplay, enhancing user engagement without delays. -- **NFTs:** Facilitates the creation of uniquely randomized traits in NFTs quickly, adding to their rarity and value. -- **Lotteries & Draws:** Offers instant and verifiably fair random selection for lotteries, solidifying trust in real-time. -- **DeFi Protocols:** Enables rapid and innovative random reward systems within decentralized finance. +- **Gaming:** Integrates fairness and unpredictability into gameplay, which enhances user engagement without delays. +- **NFTs:** Facilitates the creation of uniquely randomized traits in NFTs quickly, which adds to their rarity and value. +- **Lotteries & Draws:** Offers instant and verifiably fair random selection for lotteries, which solidifies trust in real-time. +- **DeFi Protocols:** Allows rapid and innovative random reward systems within decentralized finance. - **DAOs:** Assists in unbiased voting and task assignments through immediate randomness. - **Broad Applications:** Extends to any domain requiring impartial randomization, from asset distribution to security mechanisms, all with the added benefit of on-demand availability. - **Flow protocol:** Contributes to the proof of stake consensus security by selecting which validator gets to propose the next block, and assigns verification nodes to check block computations. -## Flow Distributed Randomness Beacon +## Flow distributed randomness beacon -Within the Flow protocol, the heart of randomness generation lies in the "Distributed Randomness Beacon". -This module generates randomness that is distributed across the network while adhering to established cryptographic and security standards. -The output from the randomness beacon is a random source for each block that is unpredictable and impartial. -Any node or external client can validate the block random source and verify it was generated fairly, making the randomness beacon a Verifiable Random function (VRF). +Within the Flow protocol, the heart of randomness generation lies in the "Distributed Randomness Beacon". This module generates randomness that is distributed across the network and adheres to established cryptographic and security standards. The output from the randomness beacon is a random source for each block that is unpredictable and impartial. Any node or external client can validate the block random source and verify it was generated fairly, which makes the randomness beacon a Verifiable Random function (VRF). -Since Flow mainnet launch, the beacon has ensured protocol security by selecting which consensus node gets to propose the next block and assigning verification nodes to oversee block computations. For those interested in a more detailed exploration of the randomness beacon and its inner workings, you can read [the technical deep dive on the Flow forum](https://forum.flow.com/t/secure-random-number-generator-for-flow-s-smart-contracts/5110). +Since Flow mainnet launched, the beacon has ensured protocol security. To do this, it selects which consensus node gets to propose the next block and assigns verification nodes to oversee block computations. For those interested in a more detailed exploration of the randomness beacon and its inner workings, you can read [the technical deep dive on the Flow forum]. -The randomness beacon is also used to provide the Flow Virtual Machine (FVM) with random numbers allowing both Cadence and EVM to access fresh, secure and instant randomness at every block and transaction. +The randomness beacon is also used to provide the Flow Virtual Machine (FVM) with random numbers, which allows both Cadence and EVM to access fresh, secure and instant randomness at every block and transaction. -## Revertible Randomness +## Revertible randomness -For usage of randomness where result abortion is not an issue, it is recommended to use the built-in function `revertibleRandom.` `revertibleRandom` returns a pseudo-random number and is backed by the Distributed Randomness Beacon. -The function is available for both Cadence and EVM. +For usage of randomness where result abortion is not an issue, it is recommended to use the built-in function `revertibleRandom.` `revertibleRandom` returns a pseudo-random number and is backed by the Distributed Randomness Beacon. The function is available for both Cadence and EVM. ```cadence // Language reference: @@ -61,16 +57,17 @@ access(all) fun main(): UInt64 { It is notable that the random number generation process is unpredictable (for miners unpredictable at block construction time and for cadence logic unpredictable at time of call), verifiable, uniform, as well as safe from bias by miners and previously-running Cadence code. -Check the [Cadence documentation](https://cadence-lang.org/docs/language/built-in-functions#revertiblerandom) for more details about the function usage. +See the [Cadence documentation]for more details about the function usage. Although Cadence and EVM exposes safe randomness generated by the Flow protocol via `revertibleRandom`, there is an additional safety-relevant aspect that developers need to be mindful about. -The `revertibleRandom` function can be used safely in some applications where the transaction results are _not_ deliberately reverted after the random number is revealed (i.e. a trusted contract distributing random NFTs to registered users or onchain lucky draw). -However, if applications require a non-trusted party (for instance app users) to submit a transaction calling a randomized (non-deterministic) contract, the developer must explicitly protect the stream of random numbers to not break the security guarantees: +The `revertibleRandom` function can be used safely in some applications where the transaction results are _not_ deliberately reverted after the random number is revealed (such as a trusted contract that distributes random NFTs to registered users or onchain lucky draw). + +However, if applications require a non-trusted party (for instance app users) to submit a transaction that calls a randomized (non-deterministic) contract, the developer must explicitly protect the stream of random numbers to not break the security guarantees: :::warning -🚨 A transaction can atomically revert all its action during its runtime and abort. Therefore, it is possible for a transaction calling into your smart contract to post-select favorable results and revert the transaction for unfavorable results. +🚨 A transaction can atomically revert all its action during its runtime and abort. Therefore, it is possible for a transaction that calls into your smart contract to post-select favorable results and revert the transaction for unfavorable results. In other words, if you write a lottery function that immediately draws a random number that may or may not be a winner, a clever attacker can get infinite guesses for free. Use commit-reveal and sell them a ticket instead! @@ -80,30 +77,27 @@ In other words, transactions submitted by a non-trusted party are able to reject :::info -**Post-selection** - the ability for transactions to reject results they don't like - is inherent to any smart contract platform that allows transactions to roll back atomically. See this very similar [Ethereum example](https://consensys.github.io/smart-contract-best-practices/development-recommendations/general/public-data/). +**Post-selection** - the ability for transactions to reject results they don't like - is inherent to any smart contract platform that allows transactions to roll back atomically. See this very similar [Ethereum example]. ::: The risky scenario that a contract developer needs to think about is the following: -- Imagine an adversarial user that is sending a transaction that calls your smart contract. +- Imagine an adversarial user that sends a transaction that calls your smart contract. - The transaction includes code that runs after your smart contract returns and inspects the outcome. - If the outcome is unfavorable (based on some criteria codified in the transaction), the transaction aborts itself. As an example, consider a simple coin toss randomized contract where users can bet any amount of tokens against a random binary output. If the coin toss contract outputs `1`, the user doubles their bet. If the coin toss contract outputs `0`, the user loses their bet in favor of the coin toss. -Although the user (or the honest coin toss contract) cannot predict or bias the outcome, the user transaction can check the randomized result and cancel the transaction if they are losing their bet. This can be done by calling an exception causing the transaction to error (division by zero for instance). All temporary state changes are cancelled and the user can repeat the process till they double their bet. - -## Commit-Reveal Scheme +Although the user (or the honest coin toss contract) cannot predict or bias the outcome, the user transaction can check the randomized result and cancel the transaction if they are losing their bet. To do this, call an exception that causes the transaction to error (such as division by zero). All temporary state changes are cancelled and the user can repeat the process until they double their bet. -The recommended way to mitigate the problems above is via a commit-reveal scheme. The scheme involves two steps: commit and reveal. During the commit phase, the user transaction commits to accepting the future output of a smart contract where the last remaining input is an unknown random source. The user transaction does not know the random source at the time of committing. The smart contract stores this commitment on the blockchain. The reveal phase can start as early as the next block, when the committed beacon's source of randomness becomes available. The reveal phase can be executed at any block after that, now that the commitment to a past block is stored on-chain. With a second transaction, the smart contract can be executed to explicitly generate the random outputs. +## Commit-reveal scheme -There are ideas how to further optimize the developer experience in the future. For example, a transaction could delegate part of its gas to an independent transaction it spawns. Conceptually, also this future solution would be a commit-and-reveal scheme, just immediately happening within the same block. Until we eventually get to this next level, developers can implement their own commit-reveal using the tools available to them on Cadence and EVM. +The recommended way to mitigate the problems above is via a commit-reveal scheme. The scheme involves two steps: commit and reveal. During the commit phase, the user transaction commits to accept the future output of a smart contract where the last input is an unknown random source. The user transaction does not know the random source at commit time. The smart contract stores this commitment on the blockchain. The reveal phase can start as early as the next block, when the committed beacon's source of randomness becomes available. The reveal phase can be executed at any block after that, now that the commitment to a past block is stored onchain. With a second transaction, the smart contract can be executed to explicitly generate the random outputs. -### Commit-Reveal pattern on Flow +### Commit-reveal pattern on Flow -[FLIP 123: On-chain Random beacon history for commit-reveal schemes](https://github.com/onflow/flips/blob/main/protocol/20230728-commit-reveal.md#flip-123-on-chain-random-beacon-history-for-commit-reveal-schemes) was introduced to provide a safe pattern to use randomness in transactions so that it's not possible to revert unfavorable randomized transaction results. -We recommend this approach as a best-practice example for implementing a commit-reveal scheme in Cadence or EVM. The `RandomBeaconHistory` contract provides a convenient archive, where for each past block height (starting Nov 2023) the respective "source of randomness" can be retrieved. The `RandomBeaconHistory` contract is automatically executed by the system at each block to store the next source of randomness. The history table can be used to query the user's committed random source from the past. +[FLIP 123: Onchain Random beacon history for commit-reveal schemes] was introduced to provide a safe pattern to use randomness in transactions so that it's not possible to revert unfavorable randomized transaction results. We recommend this approach as a best-practice example for implementing a commit-reveal scheme in Cadence or EVM. The `RandomBeaconHistory` contract provides a convenient archive, where for each past block height the respective "source of randomness" can be retrieved. The `RandomBeaconHistory` contract is automatically executed by the system at each block to store the next source of randomness. The history table can be used to query the user's committed random source from the past. :::info @@ -114,9 +108,9 @@ While the commit-and-reveal scheme mitigates post-selection of results by advers A commit-reveal scheme can be implemented as follows. To illustrate, we'll revisit the coin toss example discussed earlier: - When a user submits a bidding transaction, the bid amount is transferred to the coin toss contract, and the block height where the bid was made is stored. This is a commitment by the user to use the Source of Randomness (`SoR`) at the current block. Note that the current block's `SoR` isn't known to the transaction execution environment, and therefore the transaction has no way to inspect the random outcome and predict the coin toss result. The current block's `SoR` is only available once added to the history core-contract, which only happens at the end of the block's execution. The user may also commit to using an SoR of some future block, which is equally unknown at the time the bid is made. -- The coin toss contract may grant the user a limited window of time (i.e a block height range) to send a second transaction for resolving the results and claim any winnings. Failing to do so, the bid amount remains in the coin toss contract. +- The coin toss contract may grant the user a limited window of time (such as a block height range) to send a second transaction for resolving the results and claim any winnings. If it fails to do so, the bid amount remains in the coin toss contract. - Within that reveal transaction, the user calls the coin toss contract, looks us up the block height at which the block was committed and checks that it has already passed. The contract queries that block's `SoR` from the core-contract `RandomBeaconHistory` via block height. -- The coin toss contract uses a PRG seeded with the queried `SoR` and diversified using a specific information to the use-case (a user ID or resource ID for instance). Diversification does not add new entropy, but it avoids generating the same outcome for different use-cases. If a diversifier (or salt) isn't used, all users that committed a bid on the same block would either win or lose. +- The coin toss contract uses a PRG seeded with the queried `SoR` and diversified with a specific information to the use-case (a user ID or resource ID for instance). Diversification does not add new entropy, but it avoids generating the same outcome for different use-cases. If a diversifier (or salt) isn't used, all users that committed a bid on the same block would either win or lose. - The PRG is used to generate the random result and resolve the bid. Note that the user can make the transaction abort after inspecting a losing result. However, the bid amount would be lost anyway when the allocated window expires. The following lines of code illustrate a random coin toss that cannot be gamed or biased. The commit-reveal scheme prevent clients from post-selecting favorable outcomes. @@ -178,25 +172,24 @@ access(all) fun revealCoin(receipt: @Receipt): @FungibleToken.Vault { } ``` -## Revertible Random or Commit-Reveal? +## Revertible random or commit-reveal? -While both methods are backed by the Flow Randomness Beacon, -it is important for developers to mindfully choose between `revertibleRandom` or seeding a PRNG using the `RandomBeaconHistory` smart contract: +While both methods are backed by the Flow Randomness Beacon, it is important for developers to mindfully choose between `revertibleRandom` or seeding a PRNG using the `RandomBeaconHistory` smart contract: - With `revertibleRandom` a user has the power to abort and revert if it doesn't like `revertibleRandom`'s outputs. - `revertibleRandom` is only suitable for smart contract functions that exclusively run within trusted transactions emitted by trusted parties. You can think of a lottery contract picking a winning user, where the picking transaction is emitted by the lottery developer who is trusted to not add the abortion logic into the transaction. Users are able to check the transaction code after it is submitted and make sure the lottery developer acted fairly. -- In contrast, the commit-reveal method using the `RandomBeaconHistory` is necessary in cases where the transaction is submitted by non-trusted users and may revert the random outputs. - You can think of a user minting a randomized NFT and is able to add a logic to their transaction to check the random traits and abandon the NFT if they are not happy with the result. + `revertibleRandom` is only suitable for smart contract functions that exclusively run within trusted transactions emitted by trusted parties. You can think of a lottery contract that picks a winning user, where that transaction is emitted by the lottery developer who is trusted to not add the abortion logic into the transaction. Users are able to check the transaction code after it is submitted and make sure the lottery developer acted fairly. +- In contrast, the commit-reveal method with the `RandomBeaconHistory` is necessary in cases where the transaction is submitted by non-trusted users and may revert the random outputs. + You can think of a user minting a randomized NFT and can add a logic to their transaction to check the random traits and abandon the NFT if they are not happy with the result. Another user playing a betting game, adds a logic to check the bet result and abort whenever they lose the bet. General users are not guaranteed to act honestly when they submit transactions to play. Commit-reveal patterns are the way to limit their actions. During the commit phase, the user commits to proceed with a future source of randomness, which is only revealed after the commit transaction concluded. -Adding a safe pattern to reveal randomness without the possibility of conditional transaction reversion unlocks applications relying on randomness. By providing examples of commit-reveal implementations we hope to foster a more secure ecosystem of decentralized applications and encourage developers to build with best practices. +If you add a safe pattern to reveal randomness without the possibility of conditional transaction reversion, it unlocks applications that rely on randomness. Since we've provided examples of commit-reveal implementations, we hope to foster a more secure ecosystem of decentralized applications and encourage developers to build with best practices. -## An Invitation to Build +## An invitation to build -Flow onchain randomness opens new doors for innovation, offering developers the tools to create fair and transparent decentralized applications. With this feature, new possibilities emerge—from enhancing gameplay in decentralized gaming to ensuring the integrity of smart contract-driven lotteries or introducing novel mechanisms in DeFi. +Flow onchain randomness opens new doors for innovation, and offers developers the tools to create fair and transparent decentralized applications. With this feature, new possibilities emerge—from enhanced gameplay in decentralized gaming to confirmed integrity of smart contract-driven lotteries or introducing novel mechanisms in DeFi. This is an invitation for builders and creators: leverage onchain randomness on Flow to distinguish your projects and push the boundaries of what's possible. Your imagination and code have the potential to forge new paths in the web3 landscape. So go ahead and build; the community awaits the next big thing that springs from true randomness. @@ -204,8 +197,19 @@ This is an invitation for builders and creators: leverage onchain randomness on If you'd like to dive deeper into onchain randomness on Flow, here's a list of resources: -- To learn more about how the randomness beacon works under the hood, see [the forum post](https://forum.flow.com/t/secure-random-number-generator-for-flow-s-smart-contracts/5110). +- To learn more about how the randomness beacon works under the hood, see [the forum post]. - These FLIPs provide a more in-depth technical understanding of recent updates related to randomness: - - **[FLIP 120: Update unsafeRandom function:](https://github.com/onflow/flips/blob/main/cadence/20230713-random-function.md#flip-120-update-unsaferandom-function)** describes how the beacon provides randoms to `revertibleRandomness`. - - **[FLIP 123: On-chain Random beacon history for commit-reveal schemes:](https://github.com/onflow/flips/blob/main/protocol/20230728-commit-reveal.md#flip-123-on-chain-random-beacon-history-for-commit-reveal-schemes)** describes the commit-reveal design and why it is secure. -- To see working Cadence and EVM code, explore the [coin toss example on GitHub](https://github.com/onflow/random-coin-toss). + - **[FLIP 120: Update unsafeRandom function:]** describes how the beacon provides randoms to `revertibleRandomness`. + - **[FLIP 123: Onchain Random beacon history for commit-reveal schemes:]** describes the commit-reveal design and why it is secure. +- To see funcational Cadence and EVM code, explore the [coin toss example on GitHub]. + + + +[coin toss example on GitHub]: https://github.com/onflow/random-coin-toss +[FLIP 123: Onchain Random beacon history for commit-reveal schemes:]: https://github.com/onflow/flips/blob/main/protocol/20230728-commit-reveal.md#flip-123-onchain-random-beacon-history-for-commit-reveal-schemes +[FLIP 120: Update unsafeRandom function:]: https://github.com/onflow/flips/blob/main/cadence/20230713-random-function.md#flip-120-update-unsaferandom-function +[the forum post]: https://forum.flow.com/t/secure-random-number-generator-for-flow-s-smart-contracts/5110 +[the technical deep dive on the Flow forum]: https://forum.flow.com/t/secure-random-number-generator-for-flow-s-smart-contracts/5110 +[Cadence documentation]: https://cadence-lang.org/docs/language/built-in-functions#revertiblerandom +[Ethereum example]: https://consensys.github.io/smart-contract-best-practices/development-recommendations/general/public-data/ +[FLIP 123: Onchain Random beacon history for commit-reveal schemes]: https://github.com/onflow/flips/blob/main/protocol/20230728-commit-reveal.md#flip-123-onchain-random-beacon-history-for-commit-reveal-schemes \ No newline at end of file diff --git a/docs/build/advanced-concepts/scaling-example-account.png b/docs/build/cadence/advanced-concepts/scaling-example-account.png similarity index 100% rename from docs/build/advanced-concepts/scaling-example-account.png rename to docs/build/cadence/advanced-concepts/scaling-example-account.png diff --git a/docs/build/advanced-concepts/scaling.md b/docs/build/cadence/advanced-concepts/scaling.md similarity index 67% rename from docs/build/advanced-concepts/scaling.md rename to docs/build/cadence/advanced-concepts/scaling.md index 7e13cbf930..fa824546d9 100644 --- a/docs/build/advanced-concepts/scaling.md +++ b/docs/build/cadence/advanced-concepts/scaling.md @@ -24,24 +24,24 @@ Flow is designed for consumer-scale internet applications and is one of the fast These are transactions initiated by users, such as: - - Buying or selling NFTs - - Transferring tokens - - Swapping tokens on decentralized exchanges (DEXs) - - Staking or unstaking tokens + - Buying or selling NFTs. + - Transferring tokens. + - Swapping tokens on decentralized exchanges (DEXs). + - Staking or unstaking tokens. - In this category, each transaction originates from a unique account and is sent to the Flow network from a different machine. Developers don't need to take special measures to scale for this category, beyond ensuring their logic is primarily on-chain and their supporting systems (e.g., frontend, backend) can handle scaling if they become bottlenecks. Flow's protocol inherently manages scaling for user transactions. + In this category, each transaction originates from a unique account and is sent to the Flow network from a different machine. Developers don't need to take special measures to scale for this category, beyond ensuring their logic is primarily onchain and their supporting systems (for example, frontend, backend) can handle scaling if they become bottlenecks. Flow's protocol inherently manages scaling for user transactions. 2. **System Transactions** These are transactions initiated by an app's backend or various tools, such as: - - Minting thousands of tokens from a single minter account - - Creating transaction workers for custodians - - Running maintenance jobs and batch operations + - Minting thousands of tokens from a single minter account. + - Creating transaction workers for custodians. + - Running maintenance jobs and batch operations. In this category, many transactions originate from the same account and are sent to the Flow network from the same machine, which can make scaling tricky. This guide focuses on strategies for scaling transactions from a single account. -In the following sections, we'll explore how to execute concurrent transactions from a single account on Flow using multiple proposer keys. +In the following sections, we'll explore how to execute concurrent transactions from a single account on Flow with multiple proposer keys. :::info @@ -51,67 +51,67 @@ This guide is specific to non-EVM transactions. For EVM-compatible transactions, ## Problem -Blockchains use sequence numbers, also known as nonces, for each transaction to prevent [replay attacks](https://en.wikipedia.org/wiki/Replay_attack) and allow users to specify the order of their transactions. The Flow network requires a specific sequence number for each incoming transaction and will reject any transaction where the sequence number does not exactly match the expected next value. +Blockchains use sequence numbers, also known as nonces, for each transaction to prevent [replay attacks] and allow users to specify the order of their transactions. The Flow network requires a specific sequence number for each incoming transaction and will reject any transaction where the sequence number does not exactly match the expected next value. -This behavior presents a challenge for scaling, as sending multiple transactions does not guarantee that they will be executed in the order they were sent. This is a fundamental aspect of Flow's resistance to MEV (Maximal Extractable Value), as transaction ordering is randomized within each block. +This behavior challenges scaling, as sending multiple transactions does not guarantee that the netwrok executes them in the order users send them. This is a fundamental aspect of Flow's resistance to MEV (Maximal Extractable Value), as transaction ordering is randomized within each block. -If a transaction arrives out of order, the network will reject it and return an error message similar to the following: +If a transaction arrives out of order, the network rejects it and return an error message similar to the following: ``` * checking sequence number failed: [Error Code: 1007] invalid proposal key: public key X on account 123 has sequence number 7, but given 6 ``` -Our objective is to execute multiple concurrent transactions without encountering the sequence number error described above. While designing a solution, we must consider the following key factors: +Our objective is to execute multiple concurrent transactions and not encounter the sequence number error described above. When we design a solution, we must consider the following key factors: - **Reliability** Ideally, we want to avoid local sequence number management, as it is error-prone. In a local sequence number implementation, the sender must determine which error types increment the sequence number and which do not. For instance, network issues do not increment the sequence number, but application errors do. Furthermore, if the sender's sequence number becomes unsynchronized with the network, multiple transactions may fail. - The most reliable approach to managing sequence numbers is to query the network for the latest sequence number before signing and sending each transaction. + The most reliable approach to manage sequence numbers is to query the network for the latest sequence number before you sign and send each transaction. - **Scalability** - Allowing multiple workers to manage the same sequence number can introduce coupling and synchronization challenges. To address this, we aim to decouple workers so that they can operate independently without interfering with one another. + If you allow multiple workers to manage the same sequence number, it can introduce coupling and synchronization challenges. To address this, we aim to decouple workers so that they can operate independently and not interfere with one another. - **Capacity Management** - To ensure reliability, the system must recognize when it has reached capacity. Additional transactions should be queued and executed once there is sufficient throughput. Fire-and-forget strategies are unreliable for handling arbitrary traffic, as they do not account for system capacity. + To ensure reliability, the system must recognize when it has reached capacity. Additional transactions should be queued and executed when there is sufficient throughput. Fire-and-forget strategies are unreliable to handle arbitrary traffic, as they do not account for system capacity. ## Solution -Flow's transaction model introduces a unique role called the proposer. Each Flow transaction is signed by three roles: authorizer, proposer, and payer. The proposer key determines the sequence number for the transaction, effectively decoupling sequence number management from the authorizer and enabling independent scaling. You can learn more about this concept [here](https://developers.flow.com/build/basics/transactions#proposal-key). +Flow's transaction model introduces a unique role called the proposer. Each Flow transaction is signed by three roles: authorizer, proposer, and payer. The proposer key determines the sequence number for the transaction, which effectively decouples sequence number management from the authorizer and allows independent scaling. You can learn more about this concept [here]. We can leverage this model to design an ideal system transaction architecture as follows: - **Multiple Proposer Keys** - Flow accounts can have multiple keys. By assigning a unique proposer key to each worker, each worker can independently manage its own sequence number without interference from others. + Flow accounts can have multiple keys. If you assign a unique proposer key to each worker, each worker can independently manage its own sequence number without interference from others. - **Sequence Number Management** - Each worker ensures it uses the correct sequence number by fetching the latest sequence number from the network. Since workers operate with different proposer keys, there are no conflicts or synchronization issues. + To ensure each worker uses the correct sequence number, they fetch the latest sequence number from the network. Since workers operate with different proposer keys, there are no conflicts or synchronization issues. -- **Queue and Processing Workflow** +- **Queue and Process Workflow** - Each worker picks a transaction request from the incoming requests queue, signs it with its assigned proposer key, and submits it to the network. - The worker remains occupied until the transaction is finalized by the network. - If all workers are busy, the incoming requests queue holds additional requests until there is enough capacity to process them. -- **Key Reuse for Optimization** +- **Key reuse for optimization** To simplify the system further, we can reuse the same cryptographic key multiple times within the same account by adding it as a new key. These additional keys can have a weight of 0 since they do not need to authorize transactions. -Here's a visual example of how such an [account configuration](https://www.flowscan.io/account/18eb4ee6b3c026d2?tab=keys) might look: +Here's a visual example of how such an [account configuration] might look: ![Example.Account](scaling-example-account.png 'Example Account') As shown, the account includes additional weightless keys designated for proposals, each with its own independent sequence number. This setup ensures that multiple workers can operate concurrently without conflicts or synchronization issues. -In the next section, we'll demonstrate how to implement this architecture using the [Go SDK](https://github.com/onflow/flow-go-sdk). +In the next section, we'll demonstrate how to implement this architecture with the [Go SDK]. -## Example Implementation +## Example implementation -An example implementation of this architecture can be found in the [Go SDK Example](https://github.com/onflow/flow-go-sdk/blob/master/examples/transaction_scaling/main.go). +An example implementation of this architecture can be found in the [Go SDK Example]. This example deploys a simple `Counter` contract: @@ -134,24 +134,24 @@ access(all) contract Counter { } ``` -The goal is to invoke the `increase()` function 420 times concurrently from a single account. By adding 420 concurrency keys and using 420 workers, all these transactions can be executed almost simultaneously. +The goal is to invoke the `increase()` function 420 times concurrently from a single account. When you add 420 concurrency keys and use 420 workers, all these transactions can be executed almost simultaneously. ### Prerequisites -We're using Testnet to demonstrate real network conditions. To run this example, you need to create a new testnet account. Start by generating a key pair: +We use Testnet to demonstrate real network conditions. To run this example, you need to create a new testnet account. To start, generate a key pair: ```bash flow keys generate ``` -You can use the generated key with the [faucet](https://faucet.flow.com/fund-account) to create a testnet account. Update the corresponding variables in the `main.go` file: +You can use the generated key with the [faucet] to create a testnet account. Update the corresponding variables in the `main.go` file: ```go const PRIVATE_KEY = "123" const ACCOUNT_ADDRESS = "0x123" ``` -### Code Walkthrough +### Code walkthrough When the example starts, it will deploy the `Counter` contract to the account and add 420 proposer keys with the following transaction: @@ -254,9 +254,9 @@ func IncreaseCounter(ctx context.Context, flowClient *grpc.Client, account *flow } ``` -The above code is executed concurrently by each worker. Since each worker operates with a unique proposer key, there are no conflicts or synchronization issues. Each worker independently manages its sequence number, ensuring smooth execution of all transactions. +The above code is executed concurrently by each worker. Since each worker operates with a unique proposer key, there are no conflicts or synchronization issues. Each worker independently manages its sequence number, which ensures smooth execution of all transactions. -Finally, the `RunTransaction` function serves as a helper utility to send transactions to the network and wait for them to be finalized. It is important to note that the proposer key sequence number is set within the `IncreaseCounter` function before calling `RunTransaction`. +Finally, the `RunTransaction` function serves as a helper utility to send transactions to the network and wait for them to be finalized. It is important to note that the proposer key sequence number is set within the `IncreaseCounter` function before it calls `RunTransaction`. ```go // Run a transaction and wait for it to be sealed. Note that this function does not set the proposal key. @@ -287,9 +287,9 @@ func RunTransaction(ctx context.Context, flowClient *grpc.Client, account *flow. } ``` -### Running the Example +### Run the Example -Running the example will execute 420 transactions at the same time: +Run the example to execute 420 transactions at the same time: ```bash → cd ./examples @@ -302,3 +302,12 @@ Final Counter: 420 ``` It takes roughly the time of 1 transaction to run all 420 without any errors. + + + +[replay attacks]: https://en.wikipedia.org/wiki/Replay_attack +[here]: https://developers.flow.com/build/cadence/basics/transactions#proposal-key +[account configuration]: https://www.flowscan.io/account/18eb4ee6b3c026d2?tab=keys +[Go SDK]: https://github.com/onflow/flow-go-sdk +[Go SDK Example]: https://github.com/onflow/flow-go-sdk/blob/master/examples/transaction_scaling/main.go +[faucet]: https://faucet.flow.com/fund-account \ No newline at end of file diff --git a/docs/build/cadence/advanced-concepts/scheduled-transactions.md b/docs/build/cadence/advanced-concepts/scheduled-transactions.md new file mode 100644 index 0000000000..061637d2ad --- /dev/null +++ b/docs/build/cadence/advanced-concepts/scheduled-transactions.md @@ -0,0 +1,451 @@ +--- +title: Scheduled Transactions +description: Learn about Flow Scheduled Transactions, enabling smart contracts to autonomously execute predefined logic at specific future times without external triggers. +keywords: + - scheduled transactions + - autonomous execution + - Flow blockchain + - smart contracts + - transaction scheduling + - FlowTransactionScheduler + - time-based automation + - transaction handlers + - blockchain automation +sidebar_position: 8 +--- + +# Flow Scheduled Transactions Documentation + +## Introduction + +:::info + +Scheduled transactions were part of the Forte network upgrade and are available on Flow Mainnet, Flow Emulator (CLI v2.7.0+) and Flow Testnet. For more information, see [Forte: Introducing Actions & Agents]. + +::: + +Scheduled transactions on the Flow blockchain allow users and smart contracts to autonomously execute predefined logic at specific future times without external triggers. This powerful feature allows developers to create "wake up" patterns where contracts can schedule themselves to run at predetermined block timestamps, which allows novel blockchain automation patterns. + +Key benefits include: +- **Autonomous execution**: no need for external services or manual intervention. +- **Time-based automation**: execute transactions based on blockchain time. +- **Predictable scheduling**: guaranteed execution within specified time windows. + +Common use cases include recurring payments, automated arbitrage, time-based contract logic, delayed executions, and periodic maintenance tasks. + +:::info + +Flow provides a scheduled transaction manager to help you manage your scheduled transactions more easily. Check out the [scheduled transactions intro] for a tutorial on how to schedule some basic transactions with the manager. + +::: + +## Concepts + +### Create a scheduled transaction + +To create a scheduled transaction, the logic that executes in the transaction must already be defined in a function that the scheduler calls when it is time for the transaction to execute. + +Therefore, all scheduled transactions must include a capability to a resource that conforms to this Transaction Handler interface defined in the Scheduler contract and includes getters that conform to the [Flow metadata views standard]: + +```cadence +access(all) resource interface TransactionHandler { + // Called by the protocol to executed the scheduled transaction + // **Transaction ID**: Unique identifier for tracking, returned during scheduling + // **Data**: The optional data provided during scheduling that may relate + // to the specific scheduled transaction + access(Execute) fun executeTransaction(id: UInt64, data: AnyStruct?) + + // Allows querying this handler to get metadata about it + // See the flow metadata views standard for more info + access(all) view fun getViews(): [Type] + access(all) fun resolveView(_ view: Type): AnyStruct? +} +``` + +To schedule a transaction, store an instance of this resource in your account storage and pass a capability to the scheduler contract as part of the schedule request. + +Here is a simple example implementation for a Handler's `executeTransaction()` function that transfers FLOW at the scheduled time: + +```cadence +access(all) contract TransferFLOWHandler { + + access(all) let HandlerStoragePath: StoragePath + access(all) let HandlerPublicPath: PublicPath + + access(all) resource Handler: FlowTransactionScheduler.TransactionHandler { + + access(all) var from: Capability + + access(all) var amount: UFix64 + + // other functions left out for simplicity + + // The actual logic that is executed when the scheduled transaction + // is executed + access(FlowTransactionScheduler.Execute) + fun executeTransaction(id: UInt64, data: AnyStruct?) { + if let to = data as Address { + let providerRef = self.from.borrow() + ?? panic("Could not borrow a reference to the provider FlowToken Vault") + + // Get a reference to the recipient's Receiver + let receiverRef = getAccount(to) + .capabilities.borrow<&{FungibleToken.Receiver}>(/public/flowTokenReceiver) + ?? panic("Could not borrow a Receiver reference to the FlowToken Vault in account \(to.toString())") + + // Deposit the withdrawn tokens in the recipient's receiver + receiverRef.deposit(from: <-providerRef.withdraw(amount: self.amount)) + + } else { + panic("Unable to transfer FLOW because the data provided when scheduling the transaction is not a Flow address!") + } + } + } + + // A user would call this to get an instance of this handler + // for their own scheduling use + access(all) fun createHandler(amount: UFix64, from: Capability): @Handler { + return <- create Handler(name: "Transfer FLOW Handler Resource", amount: amount, from: from) + } + + // other functions left out for simplicity +} +``` + +### Scheduling + +In scheduling, you create the transaction that executes at a specified future timestamp. The system uses three priority levels: + +- **High Priority**: guarantees execution in the first block with the scheduled time or fails scheduling, requires the highest fees. +- **Medium Priority**: best-effort execution as close as possible to the scheduled time known during scheduling. +- **Low Priority**: opportunistic execution when network capacity allows, lowest fees but no guarantee about timing. + +Each transaction requires: +- **Handler Capability**: a capability to a resource implementing `TransactionHandler` interface, like the FLOW transfer one above. +- **Timestamp**: future Unix timestamp when execution should occur (fractional seconds ignored). +- **Execution Effort**: computational resources allocated (computation unit limit for the transaction). +- **Fees**: Flow tokens to cover execution costs and storage costs for the transaction data. +- **Optional Data**: arbitrary data that's possibly relevant to the transaction forwarded to the handler during execution. + +These arguments are required by the [`FlowTransactionScheduler.schedule()` function]. This function returns a `ScheduledTransaction` resource object. + +The Scheduled Transaction Manager standard (mentioned in the intro) provides an easy way for developers and users to manage their scheduled transactions from a central place in their account. Users are strongly encouraged to use this. + +More information about the Scheduled Transaction manager is in the [section at the end of this document]. + +When a transaction is scheduled, the [`FlowTransactionScheduler.Scheduled` event] is emitted with information about the scheduled transaction and handler. + +### Fees + +Fee calculation includes: +- **Base execution fee**: based on computational effort with standard Flow fee structure. +- **Priority multiplier**: higher priorities pay more (High: 10x, Medium: 5x, Low: 2x base rate). +- **Storage fee**: cost to store transaction data on-chain. + +Fees are paid upfront and are used in full. There are no refunds if the cost of execution was lower. + +Please keep in mind the priority multiplier can change in the future. You can obtain the fee configuration from the contract, and you can use the estimate function check the fees upfront. + +### Execution of transaction handlers + +When the scheduled time arrives, the Flow blockchain calls the `executeTransaction` method on your handler resource. + +If the transaction succeeds, the [`FlowTransactionScheduler.Executed` event] is emitted with information about the executed transaction. + +If the scheduled transaction fails at any point during execution, the `Executed` event is not emitted. + +### Cancel transactions + +You can cancel scheduled transactions before execution. When you cancel a transaction, it returns a portion of the fees (configurable refund percentage, 50% as of now). Please keep in mind the refund percentage can change in the future. + +To cancel, you need the `ScheduledTransaction` resource that was returned during scheduling. The scheduled transaction manager also makes scheduled transaction cancellation easier. + +### Transaction lifecycle + +Scheduled transactions follow a specific lifecycle with corresponding events: + +1. **Scheduled**: Transaction is created and queued for future execution. + - Event: `FlowTransactionScheduler.Scheduled` + - Status: `Scheduled` + +2. **Pending Execution**: Transaction timestamp has arrived and it's ready for execution. + - Event: `FlowTransactionScheduler.PendingExecution` + - Status: `Executed` (Executed does not necessarily mean it succeeded, just that execution was attempted.) + +3. **Executed**: The blockchain processed the transaction. + - Event: `FlowTransactionScheduler.Executed` + - Status: `Executed` + +4. **Canceled**: Transaction was canceled before execution (optional path). + - Event: `FlowTransactionScheduler.Canceled` + - Status: `Canceled` + +### Contracts + +The `FlowTransactionScheduler` contract is deployed to the service account and manages all scheduled transactions across the network. + +The `FlowTransactionSchedulerUtils` contract provides utilities for scheduled transactions, such as the transaction `Manager` resource, common handlers, and metadata views related to scheduled transactions. + +Below are listed the addresses of both transaction scheduler contracts on each network they are deployed: + +- **Emulator**: `0xf8d6e0586b0a20c7` +- \*\*Cadence Testing Framework: `0x0000000000000001` +- **Testnet**: `0x8c5303eaa26202d6` + +## Examples + +### 1. Example test handler contract + +This contract implements the `TransactionHandler` interface and is used in the following examples. It emits events when scheduled transactions are executed. + +```cadence +// TestFlowCallbackHandler.cdc - Simple test handler +import "FlowTransactionScheduler" + +access(all) contract TestFlowScheduledTransactionHandler { + access(all) let HandlerStoragePath: StoragePath + access(all) let HandlerPublicPath: PublicPath + + access(all) event TransactionExecuted(data: String) + + access(all) resource Handler: FlowTransactionScheduler.TransactionHandler { + + access(FlowTransactionScheduler.Execute) + fun executeTransaction(id: UInt64, data: AnyStruct?) { + if let string: String = data as? String { + emit TransactionExecuted(data: string) + } else { + emit TransactionExecuted(data: "bloop") + } + } + + // public functions that anyone can call to get information about + // this handler + access(all) view fun getViews(): [Type] { + return [Type(), Type(), Type()] + } + + access(all) fun resolveView(_ view: Type): AnyStruct? { + switch view { + case Type(): + return TestFlowScheduledTransactionHandler.HandlerStoragePath + case Type(): + return TestFlowScheduledTransactionHandler.HandlerPublicPath + case Type(): + return MetadataViews.Display( + name: "Basic Scheduled Transaction Handler", + description: "Emits a TransactionExecuted event when the scheduled transaction is executed", + thumbnail: MetadataViews.HTTPFile( + url: "" + ) + ) + default: + return nil + } + } + } + + access(all) fun createHandler(): @Handler { + return <- create Handler() + } + + init() { + self.HandlerStoragePath = /storage/testCallbackHandler + self.HandlerPublicPath = /public/testCallbackHandler + } +} +``` + +### 2. Schedule a transaction with the scripts manager + +This example shows how to create and schedule a transaction that will execute at a future timestamp with the [`TestFlowCallbackHandler`] from Example 1. + +```cadence +// schedule.cdc +import "FlowTransactionScheduler" +import "FlowTransactionSchedulerUtils" +import "TestFlowScheduledTransactionHandler" +import "FlowToken" +import "FungibleToken" + +transaction(timestamp: UFix64, feeAmount: UFix64, effort: UInt64, priority: UInt8, testData: AnyStruct?) { + + prepare(account: auth(BorrowValue, SaveValue, IssueStorageCapabilityController, PublishCapability, GetStorageCapabilityController) &Account) { + + // if a transaction scheduler manager has not been created for this account yet, create one + if !account.storage.check<@{FlowTransactionSchedulerUtils.Manager}>(from: FlowTransactionSchedulerUtils.managerStoragePath) { + let manager <- FlowTransactionSchedulerUtils.createManager() + account.storage.save(<-manager, to: FlowTransactionSchedulerUtils.managerStoragePath) + + // create a public capability to the callback manager + let managerRef = account.capabilities.storage.issue<&{FlowTransactionSchedulerUtils.Manager}>(FlowTransactionSchedulerUtils.managerStoragePath) + account.capabilities.publish(managerRef, at: FlowTransactionSchedulerUtils.managerPublicPath) + } + + // If a transaction handler has not been created for this account yet, create one, + // store it, and issue a capability that will be used to create the transaction + if !account.storage.check<@TestFlowScheduledTransactionHandler.Handler>(from: TestFlowScheduledTransactionHandler.HandlerStoragePath) { + let handler <- TestFlowScheduledTransactionHandler.createHandler() + + account.storage.save(<-handler, to: TestFlowScheduledTransactionHandler.HandlerStoragePath) + account.capabilities.storage.issue(TestFlowScheduledTransactionHandler.HandlerStoragePath) + + let publicHandlerCap = account.capabilities.storage.issue<&{FlowTransactionScheduler.TransactionHandler}>(TestFlowScheduledTransactionHandler.HandlerStoragePath) + account.capabilities.publish(publicHandlerCap, at: TestFlowScheduledTransactionHandler.HandlerPublicPath) + } + + // Get the entitled capability that will be used to create the transaction + // Need to check both controllers because the order of controllers is not guaranteed + var handlerCap: Capability? = nil + + if let cap = account.capabilities.storage + .getControllers(forPath: TestFlowScheduledTransactionHandler.HandlerStoragePath)[0] + .capability as? Capability { + handlerCap = cap + } else { + handlerCap = account.capabilities.storage + .getControllers(forPath: TestFlowScheduledTransactionHandler.HandlerStoragePath)[1] + .capability as! Capability + } + + // borrow a reference to the vault that will be used for fees + let vault = account.storage.borrow(from: /storage/flowTokenVault) + ?? panic("Could not borrow FlowToken vault") + + let fees <- vault.withdraw(amount: feeAmount) as! @FlowToken.Vault + let priorityEnum = FlowTransactionScheduler.Priority(rawValue: priority) + ?? FlowTransactionScheduler.Priority.High + + // borrow a reference to the callback manager + let manager = account.storage.borrow(from: FlowTransactionSchedulerUtils.managerStoragePath) + ?? panic("Could not borrow a Manager reference from \(FlowTransactionSchedulerUtils.managerStoragePath)") + + // Schedule the regular transaction with the main contract + manager.schedule( + handlerCap: handlerCap!, + data: testData, + timestamp: timestamp, + priority: priorityEnum, + executionEffort: effort, + fees: <-fees + ) + } +} +``` + +### 3. Query transaction information + +Get Status: [The get_status script] demonstrates how to check the current status of a scheduled transaction with the global status function. + +Get all Tx Info: [The get_transaction_data script] gets all the internal information about a scheduled transaction. + +#### Manager scripts + +The manager provides many different ways to get information about all of your scheduled transactions. Check out all the scripts you can use with your [manager]. + +### 4. Cancel a scheduled transaction + +This transaction shows how to cancel a scheduled transaction and receive a partial refund of the fees paid. + +```cadence +// cancel_transaction.cdc +import "FlowTransactionScheduler" +import "FlowToken" + +transaction(transactionId: UInt64) { + prepare(account: auth(BorrowValue, SaveValue, LoadValue) &Account) { + + // borrow a reference to the manager + let manager = account.storage.borrow(from: FlowTransactionSchedulerUtils.managerStoragePath) + ?? panic("Could not borrow a Manager reference from \(FlowTransactionSchedulerUtils.managerStoragePath)") + + // Get the vault where the refund should be deposited + let vault = account.storage.borrow(from: /storage/flowTokenVault) + ?? panic("Could not borrow FlowToken vault") + + // cancel the transaction + vault.deposit(from: <-manager.cancel(id: id)) + } +} +``` + +### 5. Fee estimation + +This script helps estimate the cost of scheduling a transaction before you actually submit it. This is useful for budget and validation. + +```cadence +// estimate_fees.cdc - Script to estimate scheduling costs +import "FlowTransactionScheduler" + +access(all) fun main( + dataSize: AnyStruct?, + timestamp: UFix64, + priority: UInt8, + executionEffort: UInt64 +): FlowTransactionScheduler.EstimatedScheduledTransaction { + + let priorityEnum = FlowTransactionScheduler.Priority(rawValue: priority) + ?? FlowTransactionScheduler.Priority.Medium + + return FlowTransactionScheduler.estimate( + data: dataSize, + timestamp: timestamp, + priority: priorityEnum, + executionEffort: executionEffort + ) +} +``` + +### 6. Monitor execution events + +Use the Flow Command Line Interface (CLI) to monitor all scheduled transaction events in real-time (example for testnet - account addresses may differ): + +```bash +flow events get \ + A.8c5303eaa26202d6.FlowTransactionScheduler.Scheduled \ + A.8c5303eaa26202d6.FlowTransactionScheduler.PendingExecution \ + A.8c5303eaa26202d6.FlowTransactionScheduler.Executed \ + A.8c5303eaa26202d6.FlowTransactionScheduler.Canceled \ + A.373ce83aef691d2d.TestFlowCallbackHandler.TransactionExecuted \ + --last 200 \ + -n testnet +``` + +This command fetches the last 200 blocks of events for: +- **Scheduled**: when a transaction is scheduled. +- **PendingExecution**: when a transaction is ready for execution. +- **Executed**: when a transaction has been executed. +- **Canceled**: when a transaction is canceled. +- **TransactionExecuted**: custom event from the test handler. + +These examples demonstrate the complete lifecycle of scheduled transactions: create handlers, schedule execution, monitor events, and manage cancellations. The system provides flexibility for various automation scenarios while you maintain network stability through resource limits and priority management. + +## Tools + +Support for scheduled transactions in different tools is still work in progress and is coming soon. The Flow CLI and Access Node API will support specific commands and APIs to query scheduled transactions by ID, which it easier to manage and monitor your scheduled transactions programmatically. + +The [flow-go-sdk] will also add support for these new commands. It provides native integration for Go applications that work with scheduled transactions. + +Block explorer support for scheduled transactions is also coming, which will provide a visual interface to view and track scheduled transaction execution on the Flow blockchain. + +For feature requests and suggestions for scheduled transaction tooling, visit [github.com/onflow/flow] and create an issue with the tag `scheduled_transactions`. + + +Read [FLIP 330: Scheduled Callbacks] for more details. + + + +[FLIP 330: Scheduled Callbacks]: https://github.com/onflow/flips/blob/main/protocol/20250609-scheduled-callbacks.md +[flow-go-sdk]: ../../tools/clients/flow-go-sdk/index.md +[Flow metadata views standard]: metadata-views.md +[Forte: Introducing Actions & Agents]: https://flow.com/post/forte-introducing-actions-agents-supercharging-composability-and-automation +[github.com/onflow/flow]: https://github.com/onflow/flow +[manager]: https://github.com/onflow/flow-core-contracts/tree/master/transactions/transactionScheduler/scripts/manager +[The get_status script]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/transactionScheduler/scripts/get_status.cdc +[The get_transaction_data script]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/transactionScheduler/scripts/get_transaction_data.cdc +[`TestFlowCallbackHandler`]: #1-example-test-handler-contract +[`FlowTransactionScheduler.Executed` event]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowTransactionScheduler.cdc#L78 +[`FlowTransactionScheduler.Scheduled` event]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowTransactionScheduler.cdc#L52 +[section at the end of this document]: #2-scheduling-a-transaction-with-the-manager +[`FlowTransactionScheduler.schedule()` function]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowTransactionScheduler.cdc#L732 +[scheduled transactions intro]: ../../../blockchain-development-tutorials/forte/scheduled-transactions/scheduled-transactions-introduction.md diff --git a/docs/build/advanced-concepts/traits_String.png b/docs/build/cadence/advanced-concepts/traits_String.png similarity index 100% rename from docs/build/advanced-concepts/traits_String.png rename to docs/build/cadence/advanced-concepts/traits_String.png diff --git a/docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_16.28.58.png b/docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_16.28.58.png similarity index 100% rename from docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_16.28.58.png rename to docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_16.28.58.png diff --git a/docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_16.43.07.png b/docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_16.43.07.png similarity index 100% rename from docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_16.43.07.png rename to docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_16.43.07.png diff --git a/docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_18.59.10.png b/docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_18.59.10.png similarity index 100% rename from docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_18.59.10.png rename to docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_18.59.10.png diff --git a/docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.44.png b/docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.44.png similarity index 100% rename from docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.44.png rename to docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.44.png diff --git a/docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.51.png b/docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.51.png similarity index 100% rename from docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.51.png rename to docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.51.png diff --git a/docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.55.png b/docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.55.png similarity index 100% rename from docs/build/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.55.png rename to docs/build/cadence/basics/_accounts_images/Screenshot_2023-08-16_at_19.34.55.png diff --git a/docs/build/basics/_blocks_images/Screenshot_2023-08-16_at_10.48.26.png b/docs/build/cadence/basics/_blocks_images/Screenshot_2023-08-16_at_10.48.26.png similarity index 100% rename from docs/build/basics/_blocks_images/Screenshot_2023-08-16_at_10.48.26.png rename to docs/build/cadence/basics/_blocks_images/Screenshot_2023-08-16_at_10.48.26.png diff --git a/docs/build/basics/_blocks_images/Screenshot_2023-08-16_at_10.50.53.png b/docs/build/cadence/basics/_blocks_images/Screenshot_2023-08-16_at_10.50.53.png similarity index 100% rename from docs/build/basics/_blocks_images/Screenshot_2023-08-16_at_10.50.53.png rename to docs/build/cadence/basics/_blocks_images/Screenshot_2023-08-16_at_10.50.53.png diff --git a/docs/build/basics/_blocks_images/Screenshot_2023-08-16_at_15.16.38.png b/docs/build/cadence/basics/_blocks_images/Screenshot_2023-08-16_at_15.16.38.png similarity index 100% rename from docs/build/basics/_blocks_images/Screenshot_2023-08-16_at_15.16.38.png rename to docs/build/cadence/basics/_blocks_images/Screenshot_2023-08-16_at_15.16.38.png diff --git a/docs/build/cadence/basics/_category_.yml b/docs/build/cadence/basics/_category_.yml new file mode 100644 index 0000000000..e621e97072 --- /dev/null +++ b/docs/build/cadence/basics/_category_.yml @@ -0,0 +1,2 @@ +label: Basics +position: 3 diff --git a/docs/build/basics/_collection_images/Screenshot_2023-08-17_at_19.50.39.png b/docs/build/cadence/basics/_collection_images/Screenshot_2023-08-17_at_19.50.39.png similarity index 100% rename from docs/build/basics/_collection_images/Screenshot_2023-08-17_at_19.50.39.png rename to docs/build/cadence/basics/_collection_images/Screenshot_2023-08-17_at_19.50.39.png diff --git a/docs/build/basics/_events_images/Screenshot_2023-08-18_at_13.59.01.png b/docs/build/cadence/basics/_events_images/Screenshot_2023-08-18_at_13.59.01.png similarity index 100% rename from docs/build/basics/_events_images/Screenshot_2023-08-18_at_13.59.01.png rename to docs/build/cadence/basics/_events_images/Screenshot_2023-08-18_at_13.59.01.png diff --git a/docs/build/basics/_events_images/Screenshot_2023-08-18_at_14.09.33.png b/docs/build/cadence/basics/_events_images/Screenshot_2023-08-18_at_14.09.33.png similarity index 100% rename from docs/build/basics/_events_images/Screenshot_2023-08-18_at_14.09.33.png rename to docs/build/cadence/basics/_events_images/Screenshot_2023-08-18_at_14.09.33.png diff --git a/docs/build/basics/_events_images/Screenshot_2023-08-18_at_14.30.36.png b/docs/build/cadence/basics/_events_images/Screenshot_2023-08-18_at_14.30.36.png similarity index 100% rename from docs/build/basics/_events_images/Screenshot_2023-08-18_at_14.30.36.png rename to docs/build/cadence/basics/_events_images/Screenshot_2023-08-18_at_14.30.36.png diff --git a/docs/build/cadence/basics/_fees_images/Screenshot_2023-08-17_at_17.16.32.png b/docs/build/cadence/basics/_fees_images/Screenshot_2023-08-17_at_17.16.32.png new file mode 100644 index 0000000000..5bedf970dc Binary files /dev/null and b/docs/build/cadence/basics/_fees_images/Screenshot_2023-08-17_at_17.16.32.png differ diff --git a/docs/build/basics/_fees_images/Screenshot_2023-08-17_at_17.27.50.png b/docs/build/cadence/basics/_fees_images/Screenshot_2023-08-17_at_17.27.50.png similarity index 100% rename from docs/build/basics/_fees_images/Screenshot_2023-08-17_at_17.27.50.png rename to docs/build/cadence/basics/_fees_images/Screenshot_2023-08-17_at_17.27.50.png diff --git a/docs/build/basics/_fees_images/flowscan-fees.png b/docs/build/cadence/basics/_fees_images/flowscan-fees.png similarity index 100% rename from docs/build/basics/_fees_images/flowscan-fees.png rename to docs/build/cadence/basics/_fees_images/flowscan-fees.png diff --git a/docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_13.57.36.png b/docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_13.57.36.png similarity index 100% rename from docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_13.57.36.png rename to docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_13.57.36.png diff --git a/docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_14.52.51.png b/docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_14.52.51.png similarity index 100% rename from docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_14.52.51.png rename to docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_14.52.51.png diff --git a/docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_14.52.56.png b/docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_14.52.56.png similarity index 100% rename from docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_14.52.56.png rename to docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_14.52.56.png diff --git a/docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_15.10.33.png b/docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_15.10.33.png similarity index 100% rename from docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_15.10.33.png rename to docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_15.10.33.png diff --git a/docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_16.08.18.png b/docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_16.08.18.png similarity index 100% rename from docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_16.08.18.png rename to docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_16.08.18.png diff --git a/docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_16.29.30.png b/docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_16.29.30.png similarity index 100% rename from docs/build/basics/_transactions_images/Screenshot_2023-08-17_at_16.29.30.png rename to docs/build/cadence/basics/_transactions_images/Screenshot_2023-08-17_at_16.29.30.png diff --git a/docs/build/basics/_transactions_images/chain-comparison.png b/docs/build/cadence/basics/_transactions_images/chain-comparison.png similarity index 100% rename from docs/build/basics/_transactions_images/chain-comparison.png rename to docs/build/cadence/basics/_transactions_images/chain-comparison.png diff --git a/docs/build/basics/_transactions_images/finality.png b/docs/build/cadence/basics/_transactions_images/finality.png similarity index 100% rename from docs/build/basics/_transactions_images/finality.png rename to docs/build/cadence/basics/_transactions_images/finality.png diff --git a/docs/build/cadence/basics/accounts.md b/docs/build/cadence/basics/accounts.md new file mode 100644 index 0000000000..f35fd0e198 --- /dev/null +++ b/docs/build/cadence/basics/accounts.md @@ -0,0 +1,263 @@ +--- +sidebar_position: 2 +title: Accounts +description: Learn about Flow blockchain accounts, including their structure, key management, multi-sig capabilities, and creation process. Understand how accounts store contracts, manage storage, and handle transaction signing. +keywords: + - Flow accounts + - blockchain accounts + - account keys + - multi-sig + - public keys + - account storage + - account creation + - keyless accounts + - service accounts + - account address + - account balance + - signature algorithms + - hash algorithms + - account contracts +--- + +:::info + +Are you an EVM developer looking for information about EVM Accounts on Flow? If so, check out the EVM specific documentation [here](../../../build/evm/accounts.md) + +::: + +# Accounts + +An account on Flow is a record in the chain state that holds the following information: + +- Address: unique identifier for the account. +- Public Keys: public keys authorized on the account. +- Code: Cadence contracts deployed to the account. +- Storage: area of the account used to store resource assets. + +Accounts and their keys are needed to sign transactions that change the Flow blockchain state. To execute a transaction, a small amount of Flow, called a ["Fee"] must be paid by the account or subsidized by a wallet or service. Flow allocates a [fixed amount of storage] to each account to save data structures and Resources. An account may also contain contract code which transactions and scripts can interact with to query or mutate the state of the blockchain. + +A simple representation of an account: + +![Screenshot 2023-08-16 at 16.43.07.png](_accounts_images/Screenshot_2023-08-16_at_16.43.07.png) + +## Address + +A Flow address is represented as 16 hex-encoded characters (usually prefixed with `0x` to indicate hex encoding). Unlike Bitcoin and Ethereum, Flow addresses are not derived from cryptographic public keys. Instead, each Flow address is assigned by the Flow protocol via an onchain deterministic sequence. The sequence uses an error detection code to guarantee that all addresses differ with at least two hex characters. This makes typos that result in accidental loss of assets impossible. + +This decoupling is a unique advantage of Flow, as it allows for multiple public keys to be associated with one account, or for a single public key to be used across several accounts. + +## Balance + +Each Flow account created on Mainnet will by default [hold a Flow vault that holds a balance and is part of the FungibleToken standard]. This balance is used to pay for [transaction fees and storage fees]. + +:::warning + +The minimum amount of FLOW an account can have is **0.001**. + +::: + +This minimum storage fee is provided by the account creator and covers the cost of storage up to 100kB of data in perpetuity. This fee is applied only once and can be "topped up" to add additional storage to an account. The minimum account reservation ensures that most accounts won't run out of storage capacity if anyone deposits anything (like an NFT) to the account. + +### Maximum available balance + +Due to the storage restrictions, there is a maximum available balance that user can withdraw from the wallet. The core contract [`FlowStorageFees`] provides a function to retrieve that value: + +```cadence +import "FlowStorageFees" + +access(all) fun main(accountAddress: Address): UFix64 { + return FlowStorageFees.defaultTokenAvailableBalance(accountAddress) +} +``` + +Alternatively developers can use `availableBalance` property of the `Account` + +```cadence +access(all) fun main(address: Address): UFix64 { + let acc = getAccount(address) + let balance = acc.availableBalance + + return balance +} + +``` + +## Contracts + +An account can optionally store multiple [Cadence contracts]. The code is stored as a human-readable UTF-8 encoded string which makes it easy for anyone to inspect the contents. + +## Storage + +Each Flow account has an associated storage and capacity. The account's storage used is the byte size of all the data stored in the account's storage. An account's [storage capacity is directly tied to the balance of Flow tokens] an account has. An account can, without any additional cost, use any amount of storage up to its storage capacity. If a transaction puts an account over storage capacity or drops an account's balance below the minimum 0.001 Flow tokens, that transaction fails and reverts. + +## Account **keys** + +Flow accounts can be configured with multiple public keys that are used to control access. Owners of the associated private keys can sign transactions to mutate the account's state. + +During account creation, public keys can be provided which will be used when owners interact with the account. You can send a transaction to add, remove, or revoke account keys. This is radically different from blockchains like Ethereum where an account is tied to a single public/private key pair. + +Each account key has a weight that determines the signing power it holds. + +:::warning + +A transaction is not authorized to access an account unless it has a total signature weight greater than or equal to **1000**, the weight threshold. + +::: + +For example, an account might contain three keys, each with 500 weight: + +![Screenshot 2023-08-16 at 16.28.58.png](_accounts_images/Screenshot_2023-08-16_at_16.28.58.png) + +This represents a 2-of-3 multi-sig quorum, in which a transaction is authorized to access the account if it receives signatures from _at least_ two out of three keys. + +An account key contains the following attributes: + +- **ID** used to identify keys within an account. +- **Public Key** raw public key (encoded as bytes). +- **Signature algorithm** (see below). +- **Hash algorithm** (see below). +- **Weight** integer between 0-1000. +- **Revoked** whether the key has been revoked or it's active. +- **Sequence Number** is a number that increases with each submitted transaction signed by this key. + +### Signature and hash algorithms + +The signature and hashing algorithms are used during the transaction signing process and can be set to certain predefined values. + +There are two curves commonly used with the ECDSA algorithm, secp256r1 ([OID 1.2.840.10045.3.1.7], also called the "NIST P-256." this curve is common for mobile secure enclave support), and secp256k1 ([OID 1.3.132.0.10], the curve used by "Bitcoin"). Be sure to double-check which parameters you use before you register a key, because if you present a key that uses one of the curves under the code and format of the other, an error will occur. + +| Algorithm | Curve | ID | Code | +| --------- | --------- | --------------- | ---- | +| ECDSA | P-256 | ECDSA_P256 | 2 | +| ECDSA | secp256k1 | ECDSA_secp256k1 | 3 | + +_Note that the codes listed here are for the signature algorithms as used by the node API, and they are different from the ones [defined in Cadence]_ + +| Algorithm | Output Size | ID | Code | +| --------- | ----------- | -------- | ---- | +| SHA-2 | 256 | SHA2_256 | 1 | +| SHA-3 | 256 | SHA3_256 | 3 | + +Both hashing and signature algorithms are compatible with each other, so you can freely choose from the set. + +### **Locked / keyless accounts** + +An account on Flow doesn't require keys in order to exist, but this makes the account immutable since no transaction can be signed that can change the account. This can be useful if we want to freeze an account contract code and it elegantly solves the problem of when you have multiple account types (as that is the case for Ethereum). + +![Screenshot 2023-08-16 at 18.59.10.png](_accounts_images/Screenshot_2023-08-16_at_18.59.10.png) + +To achieve keyless accounts, you can remove a public key from an account signing with that same key and repeat that action until an account has no keys left. You can also create a new account that has no keys assigned. With account linking, you can also have a child account that has no keys, but that the parent controls. + +:::danger + +Be careful when you remove keys from an account, because after an account's total key weights sum to less than 1000, it can no longer be modified. + +::: + +### **Multi-sig accounts** + +To create a multi-signature account, you can manage the account keys and their corresponding weight. To repeat, in order to sign a transaction the keys used to sign it must have weights that sum up to at least 1000. With this information, we can easily see how we can achieve the following cases: + +#### 2-of-3 multi-sig quorum + +![Screenshot 2023-08-16 at 19.34.44.png](_accounts_images/Screenshot_2023-08-16_at_19.34.44.png) + +#### 3-of-3 multi-sig quorum + +![Screenshot 2023-08-16 at 19.34.55.png](_accounts_images/Screenshot_2023-08-16_at_19.34.55.png) + +#### 1-of-2 signature + +![Screenshot 2023-08-16 at 19.34.51.png](_accounts_images/Screenshot_2023-08-16_at_19.34.51.png) + +### Key format + +We support ECDSA with the curves `P-256` and `secp256k1`. For these curves, the public key is encoded into 64 bytes as `X||Y` where `||` is the concatenation operator. + +- `X` is 32 bytes and is the big endian byte encoding of the `x`-coordinate of the public key padded to 32, i.e. `X=x_31||x_30||...||x_0` or `X = x_31*256^31 + ... + x_i*256^i + ... + x_0`. +- `Y` is 32 bytes and is the big endian byte encoding of the `y`-coordinate of the public key padded to 32, i.e. `Y=y_31||y_30||...||y_0` or `Y = y_31*256^31 + ... + y_i*256^i + ... + y_0` + +## Account creation + +To create accounts on the Flow blockchain, we call a special [create account Cadence function]. After an account is created, we can associate a new key with that account. Of course, all that can be done within a single transaction. Keep in mind that there is an account creation fee that needs to be paid. Account creation fees are relatively low, and we expect that wallet providers and exchanges will cover the cost when a user converts fiat to crypto for the first time. + +For development purposes, [you can use Flow CLI to easily create emulator, testnet and mainnet accounts]. The account creation fee is paid by a funding wallet, so you don't need a pre-existing account to create it. + +### **Key generation** + +You should generate keys in a secure manner, and take different levels of caution for each key's purpose. + +:::warning + +Anyone who obtains access to a private key can modify the account the key is associated with (assuming it has enough weight). Be very careful how you store the keys. + +::: + +For secure production keys, we suggest that you use key management services such as [Google key management] or [Amazon KMS], which are also supported by our CLI and SDKs. Those services are mostly great when integrated into your application. However, for personal use, you can securely use any [existing wallets] as well as a [hardware Ledger wallet]. + +## Service accounts + +### Flow Service Account + +The Service Account is a special account in Flow that has special permissions to manage system contracts. It is able to mint tokens, set fees, and update network-level contracts. + +### Tokens and fees + +The Service Account has administrator access to the FLOW token smart contract, so it has authorization to mint and burn tokens. It also has access to the transaction fee smart contract and can adjust the fees charged for transactions execution on Flow. + +### Network management + +The Service Account administers other smart contracts that manage various aspects of the Flow network, such as epochs and (in the future) validator staking auctions. + +### Governance + +Besides its special permissions, the Service Account is an account like any other in Flow. The service account is currently controlled by a smart contract governed by the Flow community. No single entity has the ability to unilaterally execute a transaction from the service account because it requires four signatures from controlling keys. The Flow foundation only controls three of the keys and the others are controlled by trusted community members and organizations. + +## Accounts retrieval + +You can use the Flow Command Line Interface (CLI) to get account data. To do this, run the following command: + +```sh +flow accounts get 0xf919ee77447b7497 -n mainnet +``` + +Find [more about the command in the CLI docs]. + +Accounts can be obtained from the access node APIs, currently, there are two gRPC and REST APIs. You can find more information about them here: + +**gRPC API** [building-on-flow/nodes/access-api#accounts] + +**REST API** [http-api#tag/Accounts] + +There are multiple SDKs implementing the above APIs for different languages: + +**Javascript SDK** [tools/clients/fcl-js] + +**Go SDK** [tools/clients/flow-go-sdk] + +Find a list of all SDKs here: [tools/clients] + + + +["Fee"]: ./fees.md +[fixed amount of storage]: ./fees.md#storage +[hold a Flow vault that holds a balance and is part of the FungibleToken standard]: ./flow-token.md +[transaction fees and storage fees]: ./fees.md +[`FlowStorageFees`]: ../core-contracts/05-flow-fees.md#flowstoragefees +[Cadence contracts]: https://cadence-lang.org/docs/language/contracts +[storage capacity is directly tied to the balance of Flow tokens]: ./fees.md#storage +[OID 1.2.840.10045.3.1.7]: http://oid-info.com/get/1.2.840.10045.3.1.7 +[OID 1.3.132.0.10]: http://oid-info.com/get/1.3.132.0.10 +[defined in Cadence]: https://cadence-lang.org/docs/language/crypto#signing-algorithms +[create account Cadence function]: https://cadence-lang.org/docs/language/accounts#account-creation +[you can use Flow CLI to easily create emulator, testnet and mainnet accounts]: ../../../build/tools/flow-cli/accounts/create-accounts.md +[Google key management]: https://cloud.google.com/security-key-management +[Amazon KMS]: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.Keys.html +[existing wallets]: ../../../ecosystem/wallets.md +[hardware Ledger wallet]: ../../../ecosystem/wallets.md) +[more about the command in the CLI docs]: ../../../build/tools/flow-cli/accounts/get-accounts.md +[building-on-flow/nodes/access-api#accounts]: ../../../protocol/access-onchain-data/index.md#accounts +[http-api#tag/Accounts]: /http-api#tag/Accounts +[tools/clients/fcl-js]: ../../../build/tools/clients/fcl-js/index.md +[tools/clients/flow-go-sdk]: ../../../build/tools/clients/flow-go-sdk/index.md +[tools/clients]: ../../../build/tools/clients/index.md \ No newline at end of file diff --git a/docs/build/cadence/basics/blocks.md b/docs/build/cadence/basics/blocks.md new file mode 100644 index 0000000000..aa015b1b1a --- /dev/null +++ b/docs/build/cadence/basics/blocks.md @@ -0,0 +1,105 @@ +--- +sidebar_position: 1 +title: Blocks +description: Learn about Flow blockchain blocks, their structure, lifecycle, and how they maintain the blockchain's state. Understand block headers, payloads, and the finalization process. +keywords: + - blocks + - blockchain blocks + - block header + - block payload + - block seals + - block finalization + - block status + - consensus + - collection guarantees + - block retrieval + - block ID + - block height + - Flow blockchain + - blockchain state +--- + +# Blocks + +Blocks are entities that make up the Flow blockchain. Each block contains a list of [transactions] that were executed and as a result, changed the global blockchain state. Each block is identified by a unique ID which is a cryptographic hash of the block contents. Block also includes a link to the parent block ID, which creates a linked list of blocks called the Flow blockchain. + +The unique block ID serves as proof of the block contents which any oberver can independently validate. Interesting cryptographic properties of the hash that make up the block ID guarantee that if any change is made to the block data, it would produce a different hash. Because blocks are linked, a different hash would break the link as it would no longer be referenced in the next block. + +A very basic representation of blocks is: + +![Screenshot 2023-08-16 at 15.16.38.png](_blocks_images/Screenshot_2023-08-16_at_15.16.38.png) + +Blocks are ordered from the genesis block 0 up to the latest block. Each block contains an ordered list of transactions. This is how the Flow blockchain preserves the complete history of all the changes made to the state from the start to the current state. + +Each block contains more data which is divided into **block header** and **block payload**. There are many representations of block data within the Flow protocol. APIs, node types, and specific components within the node may view a block from different perspectives. For the purpose of this document, we will talk about block data we expose through APIs to the clients. + +![Screenshot 2023-08-16 at 10.50.53.png](_blocks_images/Screenshot_2023-08-16_at_10.50.53.png) + +### Block header + +The Block header contains the following fields: + +- **ID** represents the block's unique identifier, which is derived from the hashing block header, which includes the payload hash. The algorithm used on Flow to hash the content and get an identifier is SHA3 256. This ID is a commitment to all the values in the block staying the same. +- **Parent ID** is a link to the previous block ID in the list that makes up the blockchain. +- **Height** is the block sequence number, where block 0 was the first block produced, and each next block increments the value by one. +- **Timestamp** is the timestamp at which this block was proposed by the consensus node. Depending on your use case, this time might not be accurate enough, [read more about how to measure time on the Flow blockchain]. +- **Payload Hash** represents the payload hash that is included when producing the ID of the block. To calculate the payload hash take Merkle root hashes of collection guarantees, seals, execution receipts, and execution results and hash them together. For more information, see the block payload section below. + +### Block payload + +The block payload contains the following fields: + +- **Collection Guarantees** is a list of collection IDs with the signatures from the collection nodes that produced the collections. This acts as a guarantee by collection nodes that [transactions]data in the collection will be available on the collection node if requested by other nodes at a later time. Flow purposely skips including transaction data in a block, makes blocks as small as possible, and produces new blocks by consensus nodes fast, because consensus nodes have to sync the proposed block between nodes, and that data should be the smallest possible. The consensus nodes don't really care what will a transaction do as long as it's valid, they only need to define an order of those transactions in a block. +- **Block Seals** is the attestation by verification nodes that the transactions in a previously executed block have been verified. This seals a previous block referenced by the block ID. It also references the result ID and execution root hash. It contains signatures of the verification nodes that produced the seal. + +## Lifecycle and status + +Block status is not a value stored inside the block itself, but it represents the lifecycle of a block. We derive this value based on the block inclusion in the Flow blockchain and present it to the user as it acts as an important indicator of the finality of the changes the block contains. + +Here, we'll give an overview of the different phases a block goes through. [More details can be found in the whitepaper]. Also, a lot of the block states are not necessarily important to the developer but only important to the Flow blockchain's function. + +New blocks are constantly being proposed even if no new transactions are submitted to the network. Consensus nodes are in charge of blocks production. They use a consensus algorithm (an implementation of HotStuff) to agree on what the new block will be. A block contains the ordered list of collections and each collection contains an ordered list of transactions. This is an important fact to reiterate. A block serves as a list of transitions to the Flow state machine. It documents, as an ordered list, all the changes transactions will make to the state. + +A block that is [agreed upon by the consensus nodes via an implementation of HotStuff consensus algorithm] to be the next block is **finalized**. This means the block won't change anymore and it will next be executed by the execution node. Be careful because until a block is **sealed** the changes are not to be trusted. After verification nodes validate and agree on the correctness of execution results, a block is sealed and consensus nodes will include these seals in the new block. + +In summary, a block can be either **finalized** which guarantees transactions included in the block will stay the same and will be executed, and **sealed** which means the block execution was verified. + +![Screenshot 2023-08-16 at 10.48.26.png](_blocks_images/Screenshot_2023-08-16_at_10.48.26.png) + +## Block Retrieval + +You can use the Flow CLI to get the block data by running: + +```sh +flow blocks get latest -network mainnet +``` + +Find [more about the command in the CLI docs] + +Blocks can be obtained from the access node APIs, currently, there are two gRPC and REST APIs. You can find more information about them here: + +[**gRPC Block API**] + +[**REST Block API**] + +There are multiple SDKs that implement the above APIs for different languages: + +[**Javascript SDK**] + +[**Go SDK**] + +Find a list of all SDKs [here]. + + + +[read more about how to measure time on the Flow blockchain]: https://cadence-lang.org/docs/measuring-time#time-on-the-flow-blockchain +[read more about measuring time on the Flow blockchain]: https://cadence-lang.org/docs/measuring-time#time-on-the-flow-blockchain +[transactions]: ./transactions.md +[More details can be found in the whitepaper]: https://flow.com/technical-paper +[agreed upon by the consensus nodes via an implementation of HotStuff consensus algorithm]: https://arxiv.org/pdf/2002.07403.pdf +[more about the command in the CLI docs]: ../../../build/tools/flow-cli/get-flow-data/get-blocks.md +[**gRPC Block API**]: ../../../protocol/access-onchain-data/index.md#blocks +[**REST Block API**]: /http-api#tag/Blocks +[**Javascript SDK**]: ../../../build/tools/clients/fcl-js/index.md +[**Go SDK**]: ../../../build/tools/clients/flow-go-sdk/index.md +[here]: ../../../build/tools/clients/index.md \ No newline at end of file diff --git a/docs/build/cadence/basics/collections.md b/docs/build/cadence/basics/collections.md new file mode 100644 index 0000000000..b87ab6dd79 --- /dev/null +++ b/docs/build/cadence/basics/collections.md @@ -0,0 +1,60 @@ +--- +sidebar_position: 1 +title: Collections +description: Learn about Flow blockchain collections, how they optimize data transfer by linking blocks and transactions, and their role in the network architecture. Understand how collection nodes create and manage transaction collections. +keywords: + - collections + - blockchain collections + - transaction collections + - collection nodes + - HotStuff consensus + - transaction hashes + - network optimization + - collection clusters + - transaction payload + - Flow architecture + - consensus nodes + - collection retrieval + - blockchain scaling + - data optimization +--- + +# Collections + +Collections link blocks and transactions together. Collection node clusters make these collections (via the HotStuff consensus algorithm), made up of an ordered list of one or more hashes of [signed transactions]. In order to optimize data, blocks don't contain transactions (as they do on Ethereum). The benefits are transaction data does not get transferred to consensus nodes on the network which optimizes transfer speed, and this architecture allows you to add collection clusters, which scales ingestion speed. Consensus nodes need to only agree on the order of transactions to be executed, they don't need to know the transaction payload, which makes blocks and collections lightweight. Collection nodes hold transaction payloads for anyone who requests them (for example, execution nodes). + +![Screenshot 2023-08-17 at 19.50.39.png](_collection_images/Screenshot_2023-08-17_at_19.50.39.png) + +## Collection retrieval + +To use the Flow CLI to get the collection data, run the following command: + +```sh +flow collections get caff1a7f4a85534e69badcda59b73428a6824ef8103f09cb9eaeaa216c7d7d3f -n mainnet +``` + +Find [more about the command in the CLI docs]. + +Collections can be obtained from the access node APIs, currently, there are two gRPC and REST APIs. You can find more information about them here: + +[**gRPC Collection API**] + +[**REST Collection API**] + +There are multiple SDKs that implement the above APIs for different languages: + +[**Javascript SDK**] + +[**Go SDK**] + +Find a list of all SDKs [here]. + + + +[signed transactions]: ./transactions.md +[more about the command in the CLI docs]: ../../../build/tools/flow-cli/get-flow-data/get-blocks.md +[**gRPC Collection API**]: ../../../protocol/access-onchain-data/index.md#collections +[**REST Collection API**]: /http-api#tag/Collections +[**Javascript SDK**]: ../../../build/tools/clients/fcl-js/index.md +[**Go SDK**]: ../../../build/tools/clients/flow-go-sdk/index.md +[here]: ../../../build/tools/clients/index.md \ No newline at end of file diff --git a/docs/build/basics/events.md b/docs/build/cadence/basics/events.md similarity index 54% rename from docs/build/basics/events.md rename to docs/build/cadence/basics/events.md index f4c110474e..65e0b87841 100644 --- a/docs/build/basics/events.md +++ b/docs/build/cadence/basics/events.md @@ -24,9 +24,9 @@ keywords: Flow events are special values that are emitted on the network during the execution of a Cadence program and can be observed by off-chain observers. -Events are defined as Cadence code and you should [read Cadence documentation](https://cadence-lang.org/docs/language/events) to understand how to define them. +Events are defined as Cadence code and you should [read the Cadence documentation] to understand how to define them. -Since transactions don't have return values you can leverage events to broadcast certain changes the transaction caused. Clients listening on Flow networks (apps) can listen to these events being emitted and react. +Since transactions don't have return values you can leverage events to broadcast certain changes the transaction caused. Clients taht listen on Flow networks (apps) can listen to these events that are emitted and react. ![Screenshot 2023-08-18 at 14.09.33.png](_events_images/Screenshot_2023-08-18_at_14.09.33.png) @@ -39,29 +39,29 @@ Events consist of the **event name** and an optional **payload**. ![Screenshot 2023-08-18 at 13.59.01.png](_events_images/Screenshot_2023-08-18_at_13.59.01.png) -## Core Events +## Core events Core events are events emitted directly from the FVM (Flow Virtual Machine). The events have the same name on all networks and do not follow the same naming as user-defined events (they have no address). A list of events that are emitted by the Flow network is: -| Event Name | Description | -| ---------------------------- | ------------------------------------------------------------------------| -| flow.AccountCreated | Event that is emitted when a new account gets created. | -| flow.AccountKeyAdded | Event that is emitted when a key gets added to an account. | -| flow.AccountKeyRemoved | Event that is emitted when a key gets removed from an account. | -| flow.AccountContractAdded | Event that is emitted when a contract gets deployed to an account. | -| flow.AccountContractUpdated | Event that is emitted when a contract gets updated on an account. | -| flow.AccountContractRemoved | Event that is emitted when a contract gets removed from an account. | -| flow.InboxValuePublished | Event that is emitted when a Capability is published from an account. | -| flow.InboxValueUnpublished | Event that is emitted when a Capability is unpublished from an account. | -| flow.InboxValueClaimed1 | Event that is emitted when a Capability is claimed by an account. | +| Event Name | Description | +| --------------------------- | ----------------------------------------------------------------------- | +| flow.AccountCreated | Event that is emitted when a new account gets created. | +| flow.AccountKeyAdded | Event that is emitted when a key gets added to an account. | +| flow.AccountKeyRemoved | Event that is emitted when a key gets removed from an account. | +| flow.AccountContractAdded | Event that is emitted when a contract gets deployed to an account. | +| flow.AccountContractUpdated | Event that is emitted when a contract gets updated on an account. | +| flow.AccountContractRemoved | Event that is emitted when a contract gets removed from an account. | +| flow.InboxValuePublished | Event that is emitted when a Capability is published from an account. | +| flow.InboxValueUnpublished | Event that is emitted when a Capability is unpublished from an account. | +| flow.InboxValueClaimed1 | Event that is emitted when a Capability is claimed by an account. | -For more details [on the core events, you can read Cadence reference documentation](https://cadence-lang.org/docs/language/core-events). +For more details [on the core events, you can read Cadence reference documentation]. ## User-defined events -Events that are defined inside contracts and when emitted follow a common naming schema. The schema consists of 4 parts: +Events that are defined inside contracts and when emitted follow a common naming schema. The schema consists of four parts: ```cadence A.{contract address}.{contract name}.{event type} @@ -71,23 +71,20 @@ An example event would look like: ![Screenshot 2023-08-18 at 14.30.36.png](_events_images/Screenshot_2023-08-18_at_14.30.36.png) -The first `A` means the event is originating from a contract, which will always be the case for user-defined events. The contract address as the name implies is the location of a contract deployed on the Flow network. Next, is the name of the contracted event originates from, and last is the event type defined in the contract. +The first `A` means the event originates from a contract, which will always be the case for user-defined events. The contract address as the name implies is the location of a contract deployed on the Flow network. Next, is the name of the contracted event originates from, and last is the event type defined in the contract. -There is an unlimited amount of events that can be defined on Flow, but you should know about the most common ones. +There is an unlimited amount of events that can be defined on Flow, but you should know about the most common ones. -### Fungible Token Events +### Fungible token events -All fungible token contracts, including [The FLOW Token contract](../../build/core-contracts/03-flow-token.md), -use the [fungible token standard on Flow](../../build/core-contracts/02-fungible-token.md). -As with any contract, the standard emits events when interacted with. -When any fungible token is transferred, standard events are emitted. -You can find a lot of details on the events emitted in the [Fungible Token documentation](../../build/core-contracts/02-fungible-token.md). +All fungible token contracts, which includes [The FLOW Token contract], use the [fungible token standard on Flow]. As with any contract, the standard emits events when interacted with. When any fungible token is transferred, standard events are emitted. You can find a lot of details on the events emitted in the [Fungible Token documentation]. -The most common events are when tokens are transferred which is accomplished with two actions: withdrawing tokens from the payer and depositing tokens in the receiver. Each of those actions has a corresponding event: +The most common events are when tokens are transferred which is accomplished with two actions: withdraw tokens from the payer and deposit tokens in the receiver. Each of those actions has a corresponding event: -**Withdraw Tokens** +**Withdraw tokens** Event name: `FungibleToken.Withdrawn` + ```cadence event Withdrawn(type: String, amount: UFix64, @@ -101,7 +98,7 @@ Mainnet event: `A.f233dcee88fe0abe.FungibleToken.Withdrawn` Testnet event: `A.9a0766d93b6608b7.FungibleToken.Withdrawn` -**Deposit Tokens** +**Deposit tokens** ```cadence event Deposited(type: String, @@ -120,7 +117,7 @@ Testnet event: `A.9a0766d93b6608b7.FungibleToken.Deposited` ### **Fee Events** -Since fees are governed by a contract deployed on the Flow network, that contract also emits events when fees are deducted. +Since fees are governed by a contract deployed on the Flow network, that contract also emits events when fees are deducted. Charging fees consists of a couple of steps: @@ -128,33 +125,41 @@ Charging fees consists of a couple of steps: - Withdraw Flow tokens from the payer account - Deposit Flow tokens to the fees contract -These events are very common since they accommodate all transactions on Flow. Each fee deduction will result in three events: the withdrawal of Flow tokens, the deposit of Flow tokens, and the fee deduction. +These events are very common since they accommodate all transactions on Flow. Each fee deduction will result in three events: the withdrawal of Flow tokens, the deposit of Flow tokens, and the fee deduction. An example of fee events: ```yml Events: - Index: 0 - Type: A.f233dcee88fe0abe.FungibleToken.Withdrawn + Type: A.f233dcee88fe0abe.FungibleToken.Withdrawn Tx ID: 1ec90051e3bc74fc36cbd16fc83df08e463dda8f92e8e2193e061f9d41b2ad92 Values: - - type (String): "1654653399040a61.FlowToken.Vault" + - type (String): '1654653399040a61.FlowToken.Vault' - amount (UFix64): 0.00000100 - from (Address?): b30eb2755dca4572 - Index: 1 - Type: A.f233dcee88fe0abe.FungibleToken.Deposited + Type: A.f233dcee88fe0abe.FungibleToken.Deposited Tx ID: 1ec90051e3bc74fc36cbd16fc83df08e463dda8f92e8e2193e061f9d41b2ad92 Values: - - type (String): "1654653399040a61.FlowToken.Vault" + - type (String): '1654653399040a61.FlowToken.Vault' - amount (UFix64): 0.00000100 - to (Address?): f919ee77447b7497 - Index: 2 - Type: A.f919ee77447b7497.FlowFees.FeesDeducted + Type: A.f919ee77447b7497.FlowFees.FeesDeducted Tx ID: 1ec90051e3bc74fc36cbd16fc83df08e463dda8f92e8e2193e061f9d41b2ad92 Values: - amount (UFix64): 0.00000100 - inclusionEffort (UFix64): 1.00000000 - executionEffort (UFix64): 0.00000000 ``` + + + +[read the Cadence documentation]: https://cadence-lang.org/docs/language/events +[The FLOW Token contract]: ../core-contracts/03-flow-token.md +[fungible token standard on Flow]: ../core-contracts/02-fungible-token.md +[Fungible Token documentation]: ../core-contracts/02-fungible-token.md +[on the core events, you can read Cadence reference documentation]: https://cadence-lang.org/docs/language/core-events \ No newline at end of file diff --git a/docs/build/basics/fees.md b/docs/build/cadence/basics/fees.md similarity index 59% rename from docs/build/basics/fees.md rename to docs/build/cadence/basics/fees.md index df67b77127..f3ca6323b5 100644 --- a/docs/build/basics/fees.md +++ b/docs/build/cadence/basics/fees.md @@ -15,6 +15,7 @@ keywords: - network protection - blockchain fees - gas fees + - compute unit fees - Flow token - fee structure - cost estimation @@ -22,74 +23,81 @@ keywords: :::info -Are you an EVM developer looking for information about EVM Accounts on Flow? If so, check out the EVM specific documentation [here](../../evm/fees.md) +Are you an EVM developer who wants information about EVM Accounts on Flow? If so, check out the EVM specific documentation [here] ::: # Fees -## Transaction Fees +## Transaction fees -A transaction fee is a cost paid in Flow by the payer account and is required for a transaction to be included in the Flow blockchain. Fees are necessary for protecting the network against spam/infinite running transactions and to provide monetary incentives for participants that make up the Flow network. +A transaction fee is a cost paid in Flow by the payer account and is required for a transaction to be included in the Flow blockchain. Fees are necessary to protect the network against spam or infinite running transactions and to provide monetary incentives for participants that make up the Flow network. -A transaction fee is paid regardless of whether a transaction succeeds or fails. If the payer account doesn't have sufficient Flow balance to pay for the transaction fee, the transaction will fail. We can limit the transaction fee to some extent by providing the gas limit value when submitting the transaction. +On Flow, transaction fees are determined with `compute units (CU)`, a metric that captures the effort needed to include and execute a transaction. Compute units function similarly to gas in EVM systems but are derived differently. To calculate the final fee paid by the user, multiply the transaction’s total compute units by the current compute-unit price, with all fees payable in FLOW. -### Understanding the need for transaction fees +A transaction fee is paid regardless of whether a transaction succeeds or fails. If the payer account doesn't have sufficient Flow balance to pay for the transaction fee, the transaction will fail. We can provide the compute unit limit value when you submit the transaction, which helps limit the transaction fee. -Segmented transaction fees are essential to ensure fair pricing based on the impact on the network. For instance, more heavy operations will require more resources to process and propagate transactions. Common operations, however, will stay reasonably priced. +### Understand the need for transaction fees -Fees will improve the overall security of the network by making malicious actions (eg spam) on the network less viable. +One of the ways that a single computer that no one owns and anyone can use from being monopolized by any part is to charge a fee measured by the amount of computation needed to execute code. All blockchains implement a form of this system. + +Segmented transaction fees are essential to ensure fair pricing based on the impact on the network. For instance, heavier operations will require more resources to process and propagate transactions. Common operations, however, will stay reasonably priced. + +To improve the overall security of the network, fees makie malicious actions (such as spam) on the network less viable. They also prevent a computer crash if an infinite loop is started maliciously or accidentally. The unique Flow architecture is targeted at high throughput. It makes it easier to have slack in the system, so short spikes can be handled more gracefully. -### **Fee Structure** +### **Fee structure** Each transaction fee consists of three components: execution fee, inclusion fee, and network surge factor. ![Screenshot 2023-08-17 at 17.16.32.png](_fees_images/Screenshot_2023-08-17_at_17.16.32.png) -**Execution Fee** +**Execution fee** The execution effort for a transaction is determined by the code path the transaction takes and the actions it does. The actions that have an associated execution effort cost can be separated into four broad buckets: -- Normal lines of cadence, loops, or function calls -- Reading data from storage, charged per byte read -- Writing data to storage, charged per byte written -- Account creation +- Normal lines of cadence, loops, or function calls. +- Reading data from storage, charged per byte read. +- Writing data to storage, charged per byte written. +- Account creation. + +| | Computation Units | Flow | +|-----------------------------------|-------------------|-------------| +| FT transfer | 19 | 8.60E-04 | +| Mint a small NFT (size-dependent) | 25 | 1.10E-03 | +| Empty Transaction | 0 | 1.00E-04 | +| Create 1 Account | 45 | 1.90E-03 | +| Create 10 Accounts | 363 | 1.46E-02 | +| Deploy contract (~50kb) | 319 | 1.29E-02 | +| Add key to an account | 9 | 4.60E-04 | + -| Transaction Type | Estimated cost (FLOW) | -| -------------------------------------------------- | --------------------- | -| FT transfer | 0.00000185 | -| Mint a small NFT (heavily depends on the NFT size) | 0.0000019 | -| Empty Transaction | 0.000001 | -| Add key to an account | 0.000001 | -| Create 1 Account | 0.00000315 | -| Create 10 accounts | 0.00002261 | -| Deploying a contract that is ~50kb | 0.00002965 | +**Inclusion fee** -**Inclusion Fee** +The inclusion effort of a transaction represents the work needed to: -The inclusion effort of a transaction represents the work needed for: +- Include the transaction in a block +- Transport the transaction information from node to node +- Verify transaction signatures -- Including the transaction in a block -- Transporting the transaction information from node to node -- Verifying transaction signatures +Right now, the inclusion effort is always 1.0 and the inclusion effort cost is fixed to `0.0001`. -Right now, the inclusion effort is always 1.0 and the inclusion effort cost is fixed to `0.000001`. +Fees were last revised as per [FLIP 351](https://github.com/onflow/flips/blob/main/governance/20251119-transaction-fee-update.md) -**Surge Factor** +**Surge factor** -In the future, a network surge will be applied when the network is busy due to an increased influx of transactions required to be processed or a decrease in the ability to process transactions. Right now, the network surge is fixed to `1.0`. +A network surge factor is applied when the network is busy due to an increased influx of transactions required to be processed or a decrease in the ability to process transactions. -Currently, both the inclusion fee and surge factor don't represent any significant Flow fees. Keep in mind this can change in the future. +See [FLIP 336] for details on this calculation. -**Estimating transaction costs** +**Estimat transaction costs** -Cost estimation is a two-step process. First, you need to gather the execution effort with either the emulator, on testnet, or on mainnet. Second, you use the execution effort for a transaction to calculate the final fees using one of the JavaScript or Go FCL SDKs. +Cost estimation is a two-step process. First, you need to gather the execution effort with either the emulator, on testnet, or on mainnet. Second, you use the execution effort for a transaction to calculate the final fees with one of the JavaScript or Go FCL SDKs. ## Storage -Flow's approach to storage capacity is a bit similar to some banks' pricing models, where maintaining a minimum balance prevents monthly account fees. Here, the amount of data in your account determines your minimum balance. If you fall below the minimum balance, you cannot transact with your account, except for deposits or deleting data. The essence of storage fee model is that it ensures data availability without continuously charging fees for storage, while also preventing abuses that could burden the network's storage resources. This distinction between current state and blockchain history is crucial for understanding storage requirements and limitations. +Flow's approach to storage capacity is a bit similar to some banks' pricing models, where you maintain a minimum balance to prevent monthly account fees. Here, the amount of data in your account determines your minimum balance. If you fall below the minimum balance, you can't transact with your account, except for deposits or data deletion. The essence of storage fee model is that it ensures data availability but doesn't continuously charge fees for storage, and also prevents abuses that could burden the network's storage resources. This distinction between current state and blockchain history is crucial for you to understand storage requirements and limitations. Each Flow account has associated storage used. The account's storage used is the byte size of all the data stored in the account's storage. Accounts also have a storage capacity, which is directly tied to the amount of Flow tokens an account has. The account can, without any additional cost, use any amount of storage up to its storage capacity. @@ -99,7 +107,7 @@ If a transaction puts an account over storage capacity, that transaction fails a ::: -**Storage Capacity** +**Storage capacity** The storage capacity of an account is dictated by the amount of FLOW it has. @@ -111,21 +119,21 @@ The **minimum amount of FLOW an account can have is 0.001**. This minimum is pro The minimum account reservation ensures that most accounts won't run out of storage capacity if anyone deposits anything (like an NFT) to the account. -Currently, the amount required to store 100 MB in account storage is 1 Flow. +Currently, the amount required to store 100 MB in account storage is one Flow. ![Screenshot 2023-08-17 at 17.27.50.png](_fees_images/Screenshot_2023-08-17_at_17.27.50.png) -Please note that storing data in an account on Flow doesn't charge tokens from the account, it just makes sure you will keep the tokens as a reserve. Once the storage is freed up you can transfer the Flow tokens. +When you store data in an account on Flow, it doesn't charge tokens from the account. Rather, it just makes sure you will keep the tokens as a reserve. After the storage is freed up, you can transfer the Flow tokens. -### Storage Capacity of the Payer +### Storage capacity of the payer -The storage capacity of the Payer of a transaction is generally computed the same way as the capacity of any other account, however, the system needs to account for the transaction fees the payer will incur at the end of the transaction. The final transaction fee amount is not fully known at this step, only when accounts are checked for storage compliance. If their storage used is more than their storage capacity, the transaction will fail. +The storage capacity of the Payer of a transaction is generally computed the same way as the capacity of any other account. However, the system needs to account for the transaction fees the payer will incur at the end of the transaction. The final transaction fee amount is not fully known at this step, only when accounts are checked for storage compliance. If their storage used is more than their storage capacity, the transaction will fail. Because of this, the payer's balance is conservatively considered to be lower by the maximum possible transaction fees, when checking for storage compliance. The maximum transaction fee of a specific transaction is the transaction fee as if the transaction would have used up all of its execution effort limit. -### Storage Used +### Storage used -All data that is in an account's storage counts towards storage used. Even when an account is newly created it is not empty. There are already some items in its storage: +All data that is in an account's storage counts towards storage used. Even when an account is newly created, it is not empty. There are already some items in its storage: - Metadata that marks that the account exists. - An empty FLOW vault, and stored receiver capability. @@ -133,13 +141,13 @@ All data that is in an account's storage counts towards storage used. Even when - Smart contracts deployed on the account if the account was created with contracts. - The value of the account's storage used as an unsigned integer. -Adding additional keys, smart contracts, capabilities, resources, etc. to the account counts towards storage used. +When you add additional keys, smart contracts, capabilities, resources, and so on to the account, it counts towards storage used. Data stored on the Flow blockchain is stored in a key-value ledger. Each item's key contains the address that owns the item and the path to the item. An account can have many keys, therefore flow considers the account key items are stored with. This means that the storage used by each item is the byte length of the item plus the byte length of the item's key. ### Maximum available balance -Due to the storage restrictions, there is a maximum available balance that user can withdraw from the wallet. The core contract [`FlowStorageFees`](../core-contracts/05-flow-fees.md#flowstoragefees) provides a function to retrieve that value: +Due to the storage restrictions, there is a maximum available balance that user can withdraw from the wallet. The core contract [`FlowStorageFees`] provides a function to retrieve that value: ```cadence import "FlowStorageFees" @@ -161,11 +169,11 @@ access(all) fun main(address: Address): UFix64 { ``` -## Practical Understanding of Fees +## Practically understand fees -**Using Flow Emulator** +**Use the Flow emulator** -You can start the [emulator using the Flow CLI](../../tools/emulator/index.md#running-the-emulator-with-the-flow-cli). Run your transaction and take a look at the events emitted: +You can start the [emulator with the Flow CLI]. Run your transaction and take a look at the events emitted: ```shell 0|emulator | time="2022-04-06T17:13:22-07:00" level=info msg="⭐ Transaction executed" computationUsed=3 txID=a782c2210c0c1f2a6637b20604d37353346bd5389005e4bff6ec7bcf507fac06 @@ -175,11 +183,11 @@ You should see the `computationUsed` field. Take a note of the value, you will u **On testnet or mainnet** -Once a transaction is completed, you can use an explorer like [Flowscan](https://flowscan.io/) to review the transaction details and events emitted. For Flowscan, you can open the transaction in question and look for the event `FeesDeducted` from the [`FlowFees`](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowFees.cdc) contract: +When a transaction is completed, you can use an explorer like [Flowscan] to review the transaction details and events emitted. For Flowscan, you can open the transaction in question and look for the event `FeesDeducted` from the [`FlowFees`] contract: ![flowscan-fees](./_fees_images/flowscan-fees.png) -In the event data on the right side, you will see a set of fields representing [the fees for a specific transaction.](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowFees.cdc#L14): +In the event data on the right side, you will see a set of fields that represent [the fees for a specific transaction.]: - Total Fees Paid - Inclusion Effort @@ -187,9 +195,9 @@ In the event data on the right side, you will see a set of fields representing [ Take a note of the last value in the list - the `executionEffort` value. You will use it in the next step. -### Calculating final costs +### Calculate final costs -The cost for transactions can be calculated using the following FCL scripts on mainnet/testnet respectively. +The cost for transactions can be calculated with the following FCL scripts on mainnet/testnet respectively. **On mainnet** @@ -215,15 +223,19 @@ access(all) fun main( } ``` -## Configuring execution limits +## Configure execution limits FCL SDKs allow you to set the execution effort limit for each transaction. Based on the execution effort limit determined in the previous step, you should set a reasonable maximum to avoid unexpected behavior and protect your users. The final transaction fee is computed from the actual execution effort used up to this maximum. -> **Note**: Keep in mind that the limits are not for the final fees that the user will have to pay. The limits are for the execution efforts specifically. +:::info + +Keep in mind that the limits are not for the final fees that the user will have to pay. The limits are for the execution efforts specifically. -It is important to set a limit that isn't too high or too low. If it is set too high, the payer needs to have more funds in their account before sending the transaction. If it is too low, the execution could fail and all state changes are dropped. +::: -**Using FCL JS SDK** +It is important to set a limit that isn't too high or too low. If it is set too high, the payer needs to have more funds in their account before they send the transaction. If it is too low, the execution could fail and all state changes are dropped. + +**Use FCL JS SDK** You need to set the `limit` parameter for the `mutate` function, for example: @@ -247,7 +259,7 @@ const transaction = await fcl.tx(transactionId).onceExecuted(); console.log(transaction;) ``` -**Using FCL Go SDK** +**Use FCL Go SDK** You need to call the `SetComputeLimit` method to set the fee limit, for example: @@ -272,11 +284,11 @@ tx := flow.NewTransaction(). ### Maximum transaction fees of a transaction -The maximum possible fee imposed on the payer for a transaction can be calculated as the **inclusion cost plus the execution cost**. The execution cost is the fee calculated for running the transaction based on the [execution effort limit maximum specified](#configuring-execution-limits). +The maximum possible fee imposed on the payer for a transaction can be calculated as the **inclusion cost plus the execution cost**. The execution cost is the fee calculated to run the transaction based on the [execution effort limit maximum specified]. The payer will never pay more than this amount for the transaction. -## Optimizing Cadence code to reduce effort +## Optimize Cadence code to reduce effort Several optimizations can lead to reduced execution time of transactions. Below is a list of some practices. This list is not exhaustive but rather exemplary. @@ -344,7 +356,7 @@ access(all) fun add(_ a: Int, _ b: Int): Int { **Avoid excessive load and save operations** -Avoid costly loading and storage operations and [borrow references](https://cadence-lang.org/docs/design-patterns#avoid-excessive-load-and-save-storage-operations-prefer-in-place-mutations) where possible, for example: +Avoid costly loading and storage operations and [borrow references] where possible, for example: ```cadence transaction { @@ -367,25 +379,25 @@ transaction { **Limit accounts created per transaction** -Creating accounts and adding keys are associated with costs. Try to only create accounts and keys when necessary. +Try to only create accounts and add keys when necessary, because there are costs associated with these actions. -**Check user's balance before executing transactions** +**Check user's balance before you execute transactions** You should ensure that the user's balance has enough balance to cover the highest possible fees. For FT transfers, you need to cover the amount to transfer in addition to the highest possible fees. -## Educating users +## Educate users -Wallets will handle the presentation of the final transaction costs but you can still facilitate the user experience by educating them within your application. +Wallets will handle the presentation of the final transaction costs, but you can still facilitate the user experience when you educate them within your application. -If your user is using self-custody wallets, they may have to pay the transaction and want to understand the fees. Here are some suggestions. +If your user has self-custody wallets, they may have to pay the transaction and want to understand the fees. Here are some suggestions. **Explain that costs can vary depending on the network usage** Suggested message: "Fees improve the security of the network. They are flexible to ensure fair pricing based on the impact on the network." -**Explain that waiting for the network surge to pass is an option** +**Explain that they can wait for the network surge to pass** -Inevitably, network surges will cause higher fees. Users who might want to submit a transaction while the network usage is surging should consider sending the transaction at a later time to reduce costs. +Inevitably, network surges will cause higher fees. Users who might want to submit a transaction while the network usage surges may want to send the transaction at a later time to reduce costs. **Explain that the wallet might not allow the transaction due to a lack of funds** @@ -395,21 +407,25 @@ If dynamic fees increase to the highest possible level, the user's fund might no There are several places to learn more about transaction fees: -- [FLIP-660](https://github.com/onflow/flow/pull/660) -- [FLIP-753](https://github.com/onflow/flow/pull/753) -- [Flow Fees Contract](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowFees.cdc) +- [FLIP-660] +- [FLIP-753] +- [Flow Fees Contract] + +:::info + +If you have thoughts on the implementation of transaction fees on Flow, you can [leave feedback on this forum post]. -> **Note**: If you have thoughts on the implementation of transaction fees on Flow, you can [leave feedback on this forum post](https://forum.flow.com/t/variable-transaction-fees-are-coming-to-flow/2941). +::: ## FAQs **When will the fee update go into effect?** -The updates were rolled out with the [Spork on April 6, 2022](../../networks/node-ops/node-operation/past-upgrades#mainnet-17), and were enabled on [June 1st](https://forum.flow.com/t/permissionless-contract-deployment-progress/2981) during the [weekly epoch transition](https://github.com/onflow/service-account/tree/main/transactions/set-execution-effort-weights/2022/jun-1). +The updates were rolled out with the [Spork on April 6, 2022], and were turned on [June 1st] during the [weekly epoch transition]. **Why are fees collected even when transactions fail?** -Broadcasting and verifying a transaction requires execution, so costs are deducted appropriately. +Costs are deducted appropriately when you or your users broadcast and verify a transaction. **What execution costs are considered above average?** @@ -421,11 +437,14 @@ Yes. **What is the lowest execution cost?** -The lowest execution cost is 1. This means your transaction included one function call or loop that didn't read or write any date. +The lowest execution cost is one. This means your transaction included one function call or loop that didn't read or write any date. **Can I determine how much a transaction will cost on mainnet without actually paying?** -You can estimate the costs in a two-way process: 1) determine execution costs for transactions (emulator or testnet) and 2) use an FCL SDK method to calculate the final transaction fees. +You can estimate the costs in a two-way process: + +1. Determine execution costs for transactions (emulator or testnet). +2. Use an FCL SDK method to calculate the final transaction fees. **How accurate will testnet fees be to mainnet fees?** @@ -433,7 +452,7 @@ Final fees are determined by the surge factor on the network. The surge factor f **I use Blocto and I haven't paid any fees yet. Why is that?** -That is because Blocto is acting as the payer for transactions. Self-custody wallets may have the user pay the transaction. Additionally, apps can sponsor the transaction if they choose. +That is because Blocto acts as the payer for transactions. Self-custody wallets may have the user pay the transaction. Additionally, apps can sponsor the transaction if they choose. **Why would the same transaction have different fees when executed for different accounts?** @@ -441,8 +460,28 @@ Execution costs, among other things, include the cost to read data from account Additional Details: -- The most expensive operations in Cadence are reading and writing to storage. This isn't punitive! Every read needs to be sent to all Verification nodes for verification (with Merkel proofs), and every write requires a path of Merkel hashes to be updated. Reading and writing to storage is inherently expensive on any blockchain. +- The most expensive operations in Cadence are reading and writing to storage. This isn't punitive! Every read needs to be sent to all Verification nodes for verification (with Merkel proofs), and every write requires a path of Merkel hashes to be updated. It's inherently expensive to read and write on any blockchain. - The way data is stored in accounts is as a tree (the hint is in the name "atree" :wink:). So, the more elements in the account, the more levels of the tree, and therefore the more nodes of that tree that need to be read and updated. So, looking at the byte size of an account is a decent proxy for figuring out how much it's going to cost. - Because it's a tree, the cost of reads and writes grows with log(n), but does scale. -- atree has an update queued up for [Crescendo](https://flow.com/upgrade/crescendo) that will improve this. The previous version erred on the side of adding new levels to the tree (to keep the code simple), while the new version tries to pack more data at each level. This should result in fewer levels for the same byte size. Additionally, it includes a more compact encoding leading to a reduction in the byte size of most accounts. -- Even with these improvements, this relationship is likely to remain indefinitely. The bigger the account, the more bookkeeping the nodes have to do, which will result in somewhat larger tx fees. +- atree has an update queued up for [Crescendo] that will improve this. The previous version erred on the side of adding new levels to the tree (to keep the code simple), while the new version tries to pack more data at each level. This will result in fewer levels for the same byte size. Additionally, it includes a more compact encoding leading to a reduction in the byte size of most accounts. +- Even with these improvements, this relationship is likely to remain indefinitely. The bigger the account, the more maintenance the nodes have to do, which will result in somewhat larger tx fees. + + + +[here]: ../../../build/evm/fees.md +[FLIP 336]: https://github.com/onflow/flips/blob/main/governance/20250727-dynamic-transaction-fees.md +[`FlowStorageFees`]: ../core-contracts/05-flow-fees.md#flowstoragefees +[emulator with the Flow CLI]: ../../../build/tools/emulator/index.md#running-the-emulator-with-the-flow-cli +[Flowscan]: https://flowscan.io/ +[`FlowFees`]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowFees.cdc: +[the fees for a specific transaction.]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowFees.cdc#L14 +[execution effort limit maximum specified]: #configuring-execution-limits +[borrow references]: https://cadence-lang.org/docs/design-patterns#avoid-excessive-load-and-save-storage-operations-prefer-in-place-mutations +[FLIP-660]: https://github.com/onflow/flow/pull/660 +[FLIP-753]: https://github.com/onflow/flow/pull/753 +[Flow Fees Contract]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowFees.cdc +[leave feedback on this forum post]: https://forum.flow.com/t/variable-transaction-fees-are-coming-to-flow/2941 +[Spork on April 6, 2022]: ../../../protocol/node-ops/node-operation/past-upgrades#mainnet-17 +[June 1st]: https://forum.flow.com/t/permissionless-contract-deployment-progress/2981 +[weekly epoch transition]: https://github.com/onflow/service-account/tree/main/transactions/set-execution-effort-weights/2022/jun-1 +[Crescendo]: https://flow.com/upgrade/crescendo \ No newline at end of file diff --git a/docs/build/cadence/basics/flow-token.md b/docs/build/cadence/basics/flow-token.md new file mode 100644 index 0000000000..e425b73ce8 --- /dev/null +++ b/docs/build/cadence/basics/flow-token.md @@ -0,0 +1,117 @@ +--- +title: FLOW Coin +sidebar_position: 10 +description: Learn about the FLOW coin, its role as the native token of the Flow blockchain, and how to acquire, use, and build with it. Understand staking, delegation, and transaction fee mechanisms. +keywords: + - FLOW coin + - FLOW token + - native token + - fungible token + - staking + - delegation + - transaction fees + - Flow protocol + - Flow rewards + - token utility + - Flow wallet + - token custody + - Flow transactions + - Flow governance + - Flow ecosystem +--- + +# FLOW Coin + +This section contains information about the FLOW Coin for individual backers, wallet providers, custodians and node operators. + +### FLOW as a Native Coin + +FLOW is the default coin for the Flow protocol, meaning it is used for all protocol-level fee payments, rewards and staking transactions. FLOW implements the standard [Flow Fungible Token interface], which all other onchain fungible tokens also conform to. This interface is defined in Cadence, Flow's native smart-contract programming language, which makes it easy to write applications that interact with FLOW. + +## How to Get FLOW + +There are two ways to acquire FLOW Coins as yield: + +1. [Earn FLOW as a Validator or Delegator]: Receive newly-minted FLOW as a reward when you run a node. +1. [Earn FLOW as a Community Contributor]: Flow offers grants for selected proposals as well as RFPs for teams to submit proposals for funded development + +## How to use FLOW + +With FLOW, you can: + +- Spend +- Stake +- Delegate +- Hold +- Vote +- Send and share +- Create, develop, and grow your dapp + +### Spend FLOW + +All you need to spend FLOW is an account and a tool to sign transactions (a wallet, custodian, or other signing service). The FCL (Flow Client Library) makes it super duper easy to go to any dapp, login with your account, have a great time, and then sign with the wallet of your choice only once you decide to make a purchase. + +### Stake FLOW + +[You can use FLOW to operate a staked node.] Node operators receive newly-minted FLOW as a reward for helping to secure the network. + +### Delegate FLOW + +[You can use FLOW for stake delegation.] Delegators receive newly-minted FLOW as a reward for helping to secure the network. + +### Hold FLOW + +If you have already purchased FLOW and wish to hold it, you have a couple of options: + +- For relatively small, short term holdings - most people use a wallet. + Wallets are used to help you sign transactions (verify your actions) when you use your FLOW tokens. + +- For larger, long term holdings - you may want to use a custody provider to keep your funds safe. + +You can find wallets and custodians that support Flow in the [Flow Port] + +### Vote with FLOW + +Participation in the Flow community means more than just run a node or build a dapp. It's also about engaging in discussion, debate, and decision making about the protocol, the content on it, and the people that it impacts. You can use your Flow account to submit votes to community polls and other governance related activities. + +### Send and share FLOW + +If you simply want to share the love and bring your friends to Flow, it's easier than an edible arrangement. + +It is possible to use the Flow blockchain and not hold any FLOW coins yourself. Free to play games, trials, community polls, and other community activities can all take place with only an account (which may be created on a person's behalf) and a small fixed fee which may be paid by a user agent. + +The protocol requires some FLOW coins to process these transactions, but (and this is the cool part!) a product can support users who do not themselves hold FLOW and still provide that user with all the underlying security guarantees the Flow protocol provides. + +It's easy to transfer FLOW, create accounts, and update keys on [Flow Port] + +### Submit transactions and update users + +Transactions are submitted with a Flow SDK via the Access API. + +On Flow, a transaction is identified by its hash - the hash that exists as soon as that transaction is signed and submitted to an Access or Collection node. Results of transactions can be queried by transaction hash through the Access API. A user can check the status of a transaction at any time via the [Flow Block Explorer]. + +To expose these results natively in your app, you can use a Flow SDK to [fetch transaction results]. + +With a Flow SDK, you can also [fetch account state by address] from a Flow Access API. + +After the transaction is sealed, an event is emitted and you will be able to read transaction events and update the user. + +The Flow SDKs also allow [polling for events] with the Flow Access API. + +## How to build with FLOW + +To get started with Flow, see the [Flow App Quickstart] + + + +[Flow Fungible Token interface]: https://github.com/onflow/flow-ft +[Earn FLOW as a Validator or Delegator]: ../../../protocol/staking/06-technical-overview.md +[Earn FLOW as a Community Contributor]: https://github.com/onflow/developer-grants +[You can use FLOW to operate a staked node.]: ../../../protocol/staking/06-technical-overview.md +[You can use FLOW for stake delegation.]: ../../../protocol/staking/06-technical-overview.md +[Flow Port]: https://port.flow.com/ +[Flow Block Explorer]: https://flowscan.io/ +[fetch transaction results]: https://github.com/onflow/flow-go-sdk#querying-transaction-results +[fetch account state by address]: https://github.com/onflow/flow-go-sdk#querying-accounts +[polling for events]: https://github.com/onflow/flow-go-sdk#querying-events) +[Flow App Quickstart]: ../../../blockchain-development-tutorials/cadence/getting-started/building-a-frontend-app.md \ No newline at end of file diff --git a/docs/build/cadence/basics/mev-resistance.md b/docs/build/cadence/basics/mev-resistance.md new file mode 100644 index 0000000000..970ed64b3a --- /dev/null +++ b/docs/build/cadence/basics/mev-resistance.md @@ -0,0 +1,92 @@ +--- +title: MEV Resistance +description: How Flow’s unique architecture minimizes Maximal Extractable Value (MEV) to ensure fair and equitable access. +sidebar_position: 5 +keywords: + - MEV + - Maximal Extractable Value + - Flow Blockchain + - Equitable Access + - Transaction Ordering + - Blockchain Security +--- + +# How Flow Suppresses MEV to Ensure Equitable Access + +
+ +
+ +## The hidden cost of MEV in decentralized systems + +One of the most under-discussed benefits of decentralization is **equitable access**. Ideally, the value and quality-of-service you receive from a decentralized platform should not depend on your identity, computing power, or personal connections. However, **Maximal Extractable Value (MEV)** poses a significant threat to this principle. + +MEV allows block producers to manipulate transaction ordering for profit—often at the direct expense of users. The ability to front-run, back-run, or sandwich transactions can extract value from ordinary users, which reinforces inequalities instead of eliminating them. In most blockchain networks, MEV is not just an unfortunate side effect; it is structurally embedded in how transactions are processed. + +## Why MEV persists on most blockchains + +MEV is difficult to prevent on most blockchains because **each block has a single builder**. This builder must have: + +- A full copy of the blockchain state. +- The ability to simulate transactions before they are finalized. +- Absolute control over transaction selection and ordering. + +In practice, this means that **the entity who adds your transaction to the blockchain can first simulate it to identify profit opportunities**. They can test hundreds or thousands of ways to rearrange transactions, and insert their own to extract MEV—often at **your** expense. + +For example, if a block builder can sandwich your transaction and earn $10, it means **you** likely lose $10 in value. This is functionally theft, and the worst part? If your transaction is airtight and offers no MEV opportunities, the block builder has no obligation to include it at all. Pay the toll, or get locked out. + +## How Flow accomplishes MEV resilience + +Unlike many blockchains, **Flow was designed from the ground up to minimize MEV** through a unique multi-role architecture. Flow introduces key design choices that break the typical MEV-enabling structure: + +### 1. **Separate transaction selection from execution** + +On Flow, **Collection Nodes** select transactions, but they do not have access to the execution state or computing power to simulate them. Meanwhile, **Execution Nodes** run transactions but cannot choose or reorder them. + +This separation significantly reduces the ability of block builders to test transactions before execution. Even if an attacker controls both a Collection Node and an Execution Node, they cannot easily extract MEV. + +### 2. **Separate transaction ordering from execution** + +Flow further decentralizes control by introducing **Consensus Nodes** that determine transaction order. These nodes are separate from both Collection Nodes and Execution Nodes. + +For an attacker to perform MEV, they would need to: + +- Control a **Collection Node** to insert a transaction. +- Control a **Consensus Node** to place it in the desired order. +- Have execution state access to predict its effects. + +This makes it vastly more difficult to extract MEV compared to traditional blockchains, where a single entity often controls all three functions. + +### 3. **Strict transaction execution rules** + +Execution Nodes on Flow have a **simple, enforceable rule**: They **must** execute transactions exactly as ordered by Consensus Nodes, or they get slashed. + +Unlike traditional blockchains, where the same party both orders and executes transactions, Flow ensures that Execution Nodes cannot manipulate transaction order for profit. + +### 4. **Parallel processing for extra MEV resistance** + +Flow’s unique **pipelined execution model** adds another layer of complexity for potential attackers. + +While one block is executed, the next block undergoes consensus, and a third block continues to collect transactions. This means that **to front-run or sandwich attack on Flow, an attacker must successfully predict the outcome of at least two unexecuted blocks—one of which hasn’t even been built yet**. + +Even with significant resources, this makes profitable MEV attacks incredibly difficult. + +## The end result: a fairer blockchain + +Flow’s architecture ensures that: + +- The nodes that select transactions **don’t know** their order. +- The nodes that order transactions **don’t know** the blockchain state. +- The nodes that execute transactions **can’t** modify the order. + +By **intentionally separating powers**, Flow eliminates MEV at its root rather than merely mitigate its effects. + +This level of protection against MEV is not an afterthought—it has been a fundamental design goal of Flow since day one. If equitable access matters, **why settle for anything less?** diff --git a/docs/build/basics/network-architecture.md b/docs/build/cadence/basics/network-architecture.md similarity index 81% rename from docs/build/basics/network-architecture.md rename to docs/build/cadence/basics/network-architecture.md index a46184494d..436142f5e6 100644 --- a/docs/build/basics/network-architecture.md +++ b/docs/build/cadence/basics/network-architecture.md @@ -5,4 +5,4 @@ title: Network Architecture ↗️ -; +; diff --git a/docs/build/cadence/basics/scripts.md b/docs/build/cadence/basics/scripts.md new file mode 100644 index 0000000000..7954c637fc --- /dev/null +++ b/docs/build/cadence/basics/scripts.md @@ -0,0 +1,145 @@ +--- +sidebar_position: 4 +title: Scripts +description: Learn about Flow scripts - read-only Cadence code that can query blockchain state without fees. Understand how to write, execute, and optimize scripts for accessing Flow network data. +keywords: + - scripts + - Cadence scripts + - blockchain queries + - read operations + - Flow scripts + - script execution + - state queries + - Flow API + - script limitations + - best practices + - historic data + - script arguments + - script returns + - Flow CLI + - computation limits +--- + +# Scripts + +A script provides a light-weight method to query chain data. + +It is executable Cadence code that can query for Flow execution state data but cannot modify it in any way. + +Unlike a Flow transaction, a script is not signed and requires no transaction fees. Also unlike a transaction, a script can return a value back to the caller. You can think of script execution as a read-only operation, very similar to the `eth_call` RPC method on Ethereum. + +Scripts are currently executed on either the Access Nodes or the Execution Nodes based on the Access node configuration. + +Scripts are defined by the following the Cadence code: + +```cadence +// The 'main' function is the entry point function and every script needs to have one. +access(all) fun main() { + // Cadence statements to be executed go here +} +``` + +Scripts can return a typed value: + +```cadence +access(all) fun main(): Int { + return 1 + 2 +} +``` + +Scripts can also accept arguments: + +```cadence +access(all) fun main(arg: String): String { + return "Hello ".concat(arg) +} +``` + +Scripts can call contract functions and query the state of a contract. To call a function on another contract, import it from its address and invoke the function: + +```cadence +import World from 0x01 + +access(all) fun main(): String { + return World.hello() +} +``` + +Scripts can also be run against previous blocks, which allows you to query historic data from the Flow network. This is particularly useful to retrieve historical states of contracts or track changes over time. + +## When to use a script? + +Scripts can be used for the following: + +1. Validate a transaction before you submit it (for example, confirm that if the payer has sufficient balance, the receiver account is setup correctly to receive a token or NFT). +2. Collect chain data over time. +3. Continuously verify accounts through a background job, such as a Discord bot that verifies users by their Flow account. +4. Query core contracts. For an example, see how to [query staking and epoch related information]. Also, see the scripts directory under each of the [core contract transactions] for other core contracts related scripts. + +## Execute Scripts + +### Access API + +To execute a script, submit it to the Access API provided by access nodes. Currently, there are three API endpoints that allow a user to execute scripts at the latest sealed block, a previous block height, or a previous block ID. + +[**gRPC Script API**] + +[**REST Script API**] + +There are multiple SDKs implementing the above APIs for different languages: + +[**Javascript SDK**] + +[**Go SDK**] + +Find a list of all SDKs [here] + +### Flow CLI + +You can also execute a script with the [Flow CLI]: + +```sh +flow scripts execute ./helloWorld.cdc +``` + +A user can define their own scripts or can use already defined scripts by the contract authors that can be found with the [FLIX] service. + +## Best Practices + +The following are some recommendations for how to write efficient scripts: + +1. **Simpler and shorter scripts**: Scripts, like transactions, are subject to computation limits (see [limitations]).We recommend that you run shorter and simpler scripts which have low time complexity for a faster response. If you have a script with several nested loops, long iteration, or that queries many onchain fields, we recommend that you simplify the script logic. + +2. **Fewer state reads**: A script reads execution state and to get a faster response, it is best to limit the amount of state that is read by the script. + +3. **Smaller length of array or dictionary type arguments**: If your script requires an array or a dictionary as an argument where each element causes a state lookup, instead of a single script call that passes in a long list, make multiple calls with a smaller subset of the array or dictionary. + +4. **NFTCatalog**: If your script uses the [NFTCatalog] functions, ensure that you use the [latest functions] and do not use any of the deprecated functions such as `getCatalog()`. + +## Limitations + +1. **Rate limit** - Script execution is subjected to API rate-limits imposed by the Access nodes and the Execution nodes. The rate limits for the Public Access nodes hosted by QuickNode are outlined [outlined here]. + +2. **Computation limit** - Similar to a transaction, each script is also subjected to a computation limit. The specific value can be configured by individual Access and Execution node operators. Currently, the default compute unit (gas) limit for a script is 100,000. + +3. **Historic block data limit** + 1. Script execution on execution nodes is restricted to approximately the last 100 blocks. Any request for script execution on an execution node on a past block (specified by block ID or block height) will fail if that block is more than 100 blocks in the past. + 2. Script execution on an access node can go much beyond the last 100 blocks but is restricted to the height when the [last] network upgrade ([HCU] or spork) occurred. + + + +[query staking and epoch related information]: ../../../protocol/staking/07-staking-scripts-events.md +[core contract transactions]: https://github.com/onflow/flow-core-contracts/tree/master/transactions +[**gRPC Script API**]: ../../../protocol/access-onchain-data/index.md#scripts +[**REST Script API**]: /http-api#tag/Scripts +[**Javascript SDK**]: ../../../build/tools/clients/fcl-js/index.md +[**Go SDK**]: ../../../build/tools/clients/flow-go-sdk/index.md +[here]: ../../../build/tools/clients/index.md +[Flow CLI]: ../../../build/tools/flow-cli/scripts/execute-scripts +[FLIX]: ../../../build/tools/flow-cli/flix +[limitations]: #limitations +[NFTCatalog]: https://github.com/onflow/nft-catalog +[latest functions]: https://github.com/onflow/nft-catalog?tab=readme-ov-file#using-the-catalog-for-marketplaces-and-other-nft-applications +[outlined here]: https://www.quicknode.com/docs/flow#endpoint-rate-limits +[last]: https://developers.flow.com/protocol/node-ops/node-operation/past-upgrades +[HCU]: https://developers.flow.com/protocol/node-ops/node-operation/hcu \ No newline at end of file diff --git a/docs/build/basics/smart-contracts.md b/docs/build/cadence/basics/smart-contracts.md similarity index 64% rename from docs/build/basics/smart-contracts.md rename to docs/build/cadence/basics/smart-contracts.md index 7203fb02e9..f31d77c73f 100644 --- a/docs/build/basics/smart-contracts.md +++ b/docs/build/cadence/basics/smart-contracts.md @@ -1,6 +1,6 @@ --- -slug: /build/basics/smart-contracts -redirect: /build/smart-contracts/overview +slug: /build/cadence/basics/smart-contracts +redirect: /build/cadence/smart-contracts/overview title: Smart Contracts ↙ description: Redirect page to comprehensive Flow smart contracts documentation and overview. keywords: @@ -16,8 +16,8 @@ keywords: # Smart Contracts -Go to [Smart Contracts](../../build/smart-contracts/overview.md) +Go to [Smart Contracts](../smart-contracts/overview.md) import {Redirect} from '@docusaurus/router'; -; +; diff --git a/docs/build/basics/transactions.md b/docs/build/cadence/basics/transactions.md similarity index 65% rename from docs/build/basics/transactions.md rename to docs/build/cadence/basics/transactions.md index fa1c814378..09495a3473 100644 --- a/docs/build/basics/transactions.md +++ b/docs/build/cadence/basics/transactions.md @@ -23,30 +23,32 @@ keywords: # Transactions -Transactions are cryptographically signed data messages that contain a set of instructions that update the Flow state. They are a basic unit of computation that gets executed by execution nodes. In order for a transaction to be included in the Flow blockchain a fee is required from the payer. +Transactions are cryptographically signed data messages that contain a set of instructions that update the Flow state. They are a basic unit of computation that gets executed by execution nodes. In order for a transaction to be included in the Flow blockchain a fee is required from the payer. ![Screenshot 2023-08-17 at 13.57.36.png](_transactions_images/Screenshot_2023-08-17_at_13.57.36.png) :::tip -Transactions on Flow are fundamentally different from those on Ethereum. The main purpose of a transaction is not to send funds but to contain code that gets executed. This makes transactions very flexible and powerful. In addition to being able to access the authorizing accounts private assets, transactions can also read and call functions in public contracts, and access public domains in other users' accounts Transactions on Flow also feature different roles, such as defining third-party payer accounts, proposer accounts, and authorizers, which we will talk about in detail soon. +Transactions on Flow are fundamentally different from those on Ethereum. The main purpose of a transaction is not to send funds, but to contain code that gets executed. This makes transactions very flexible and powerful. In addition to being able to access the authorizing accounts private assets, transactions can also read and call functions in public contracts, and access public domains in other users' accounts. + + Transactions on Flow also feature different roles, such as define third-party payer accounts, proposer accounts, and authorizers, which we will talk about in detail soon. ::: -In order for a transaction to be valid and executed it must contain signatures from accounts involved as well as some other information, let's take a look at all the required fields. +In order for a transaction to be valid and executed, it must contain signatures from accounts involved as well as some other information, let's take a look at all the required fields. ![Screenshot 2023-08-17 at 14.52.56.png](_transactions_images/Screenshot_2023-08-17_at_14.52.56.png) ### Script -The script section contains instructions for transaction execution. This is a Cadence program in source code form (human-readable), and encoded as UTF-8. The transaction program must contain a `transaction` declaration. +The script section contains instructions for transaction execution. This is a Cadence program in source code form (human-readable), and encoded as UTF-8. The transaction program must contain a `transaction` declaration. -A transaction includes multiple optional phases `prepare`, `pre`, `execute`, and `post` phase. You can read more about it in the [Cadence reference document on transactions](https://cadence-lang.org/docs/language/transactions). Each phase has a purpose, the two most important phases are `prepare` and `execute`. +A transaction includes multiple optional phases `prepare`, `pre`, `execute`, and `post` phase. You can read more about it in the Cadence [documentation on transactions]. Each phase has a purpose, the two most important phases are `prepare` and `execute`. -In the `prepare` phase, we have access to `&Account` objects, which gives us the power to interact with those accounts. The accounts are called authorizers of transactions, so each account we want to interact with in the `prepare` phase must sign the transaction as an authorizer. -The `execute` phase does exactly what it says, it executes the main logic of the transaction. This phase is optional, but it is a best practice to add your main transaction logic in the section, so it is explicit. +In the `prepare` phase, we have access to `&Account` objects, which gives us the power to interact with those accounts. The accounts are called authorizers of transactions, so each account we want to interact with in the `prepare` phase must sign the transaction as an authorizer. +The `execute` phase does exactly what it says, it executes the main logic of the transaction. This phase is optional, but it is a best practice to add your main transaction logic in the section, so it is explicit. -Again make sure to read Cadence [documentation on transactions](https://cadence-lang.org/docs/language/transactions) +Again, make sure to read Cadence [documentation on transactions] This is an example of a transaction script: @@ -60,25 +62,27 @@ transaction(greeting: String) { ### Arguments -Transactions may declare parameters it needs during execution, these must be provided as input arguments when sending a transaction. You can think of them as function arguments. Currently, we provide [arguments in the JSON-Cadence Data Interchange Format](https://cadencelang.dev/docs/1.0/json-cadence-spec). Which is a human-readable JSON format. The sample script from above accepts a single `String` argument. +Transactions may declare parameters it needs during execution, these must be provided as input arguments when you send a transaction. You can think of them as function arguments. Currently, we provide [arguments in the JSON-Cadence Data Interchange Format]. Which is a human-readable JSON format. The sample script from above accepts a single `String` argument. -### Reference Block +### Reference block -A reference to a recent block used for expiry. A transaction is considered expired if it is submitted to Flow after reference block height + N, where N is a constant defined by the network. On mainnet current setting for N is 600 which amounts to approximately 10 minutes for expiry (please note this is subject to change). +A reference to a recent block used for expiry. A transaction is considered expired if it is submitted to Flow after reference block height + N, where N is a constant defined by the network. On mainnet current setting for N is 600 which amounts to approximately 10 minutes for expiry (this is subject to change). :::caution -It is recommended to use the latest finalized block as the reference block, as it is the most recent block guaranteed to be included by the network. Using the latest sealed block is not recommended, as sealing occurs after finalization and could cause the transaction to fall outside of the expiration window. + +We recommend that you use the latest finalized block as the reference block, as it is the most recent block guaranteed to be included by the network. We don't recommend that you use the latest sealed block, as sealing occurs after finalization and could cause the transaction to fall outside of the expiration window. + ::: -### Gas Limit +### Gas limit -When a transaction is executed each operation consumes a predefined amount of computational units (we define more about that in the Fees documentation). This defines the maximum amount of computation that is allowed to be done during this transaction. If a transaction completes execution using fewer computational units than the limit, it remains unaffected. However, if it hits this limit during execution, the transaction will fail, its changes will be reverted, but fees will still be applied. The maximum computational limit for Flow mainnet is currently at 9999, but this might change. The maximum network limit is defined to protect the network from transactions that would run forever. +When a transaction is executed each operation consumes a predefined amount of computational units (we define more about that in the Fees documentation). This defines the maximum amount of computation that is allowed to be done during this transaction. If a transaction completes execution with fewer computational units than the limit, it remains unaffected. However, if it hits this limit during execution, the transaction will fail, its changes will be reverted, but fees will still be applied. The maximum computational limit for Flow mainnet is currently at 9999, but this might change. The maximum network limit is defined to protect the network from transactions that would run forever. -### Proposal Key +### Proposal key -Each transaction must declare a proposal key, which can be an account key from any Flow account (App, User or Wallet). The account that owns the proposal key is referred to as the *proposer*. +Each transaction must declare a proposal key, which can be an account key from any Flow account (App, User or Wallet). The account that owns the proposal key is referred to as the _proposer_. -Proposer is a role in a transaction that defines who is proposing the transaction, the effect of the transaction being submitted on the proposer is that it will increment the sequence number for the provided proposer key. This is done to ensure transactions are not resubmitted (replay attack) and thus sequencing actions. +Proposer is a role in a transaction that defines who proposes the transaction, the effect of the transaction being submitted on the proposer is that it will increment the sequence number for the provided proposer key. This is done to ensure transactions are not resubmitted (replay attack) and thus sequence actions. A proposal key definition declares the address, key ID, and up-to-date sequence number for the account key. A single proposer can have many transactions executed in parallel only limited by the key they use to propose the transaction. @@ -86,11 +90,11 @@ A proposal key definition declares the address, key ID, and up-to-date sequence - Address identifies the account that will act as a proposer of this transaction. - Key ID is an index number (starting at 0) that identifies the key on the account provided in the address. -- Sequence Number is a number on each key that increments by 1 with each transaction. This ensures that each transaction executes at most once and prevents many unwanted situations, such as [transaction replay attacks](https://en.wikipedia.org/wiki/Replay_attack). Each key in an account has a dedicated sequence number associated with it. Unlike Ethereum, there is no sequence number for the entire account. +- Sequence Number is a number on each key that increments by one with each transaction. This ensures that each transaction executes at most once and prevents many unwanted situations, such as [transaction replay attacks]. Each key in an account has a dedicated sequence number associated with it. Unlike Ethereum, there is no sequence number for the entire account. ### Authorizers -Authorizers are accounts that authorize a transaction to read and mutate their state. A transaction can specify zero or more authorizers, depending on how many accounts the transaction needs to access. +Authorizers are accounts that authorize a transaction to read and mutate their state. A transaction can specify zero or more authorizers, and this depends on how many accounts the transaction needs to access. The number of authorizers on the transaction must match the number of &Account parameters declared in the prepare statement of the Cadence script. @@ -102,31 +106,23 @@ transaction { } ``` -Each account defined as an authorizer must sign the transaction with its own key, -and by doing so it acknowledges the transaction it signed -will have access to that account and may modify it. -How it will modify it is understood from the list of account entitlements -that are granted in the `prepare` argument list and by reading the transaction script. -In an transaction, developers should only give the minimum set of account entitlements -that are required for the transaction to execute properly. -This ensures that users who are signing transactions can understand -what parts of their account a transaction can access. +Each account defined as an authorizer must sign the transaction with its own key, and when it does so, it acknowledges the transaction it signed will have access to that account and may modify it. How it will modify it is understood from the list of account entitlements that are granted in the `prepare` argument list and when it reads the transaction script. In an transaction, developers should only give the minimum set of account entitlements that are required for the transaction to execute properly. This ensures that users who sign transactions can understand what parts of their account a transaction can access. ### Payer -A payer is the account that pays the fees for the transaction. A transaction must specify exactly one payer. The payer is only responsible for paying the network and gas fees; the transaction is not authorized to access resources or code stored in the payer account. +A payer is the account that pays the fees for the transaction. A transaction must specify exactly one payer. The payer only has to pay the network and compute unit fees; the transaction is not authorized to access resources or code stored in the payer account. -By explicitly specifying a payer a transaction can be paid by third-party services such as wallet providers. +When you explicitly specify a payer, third-party services such as wallet providers can pay a transaction. -## Transaction Lifecycle +## Transaction lifecycle -Once a transaction has been submitted to the Flow network using the Access node APIs, it will begin its lifecycle and eventually reach a finality. Each submitted transaction can be identified with an ID. +After a transaction has been submitted to the Flow network with the Access node APIs, it will begin its lifecycle and eventually reach a finality. Each submitted transaction can be identified with an ID. **Transaction ID** A transaction ID is a hash of the encoded transaction payload and can be calculated at any time. We don't submit transaction ID as part of the transaction payload as it can be derived from the data and thus would mean duplication of data. -### Transaction Status +### Transaction status The transaction status represents the state of a transaction on the Flow blockchain. Some statuses are mutable and some are immutable, they usually follow a timeline like so: @@ -135,7 +131,7 @@ The transaction status represents the state of a transaction on the Flow blockch - Unknown - The transaction has not yet been seen by the section of the network you communicate with. - Pending - The transaction has been received by a collection node but has not yet been finalized in a block. - Finalized - The consensus nodes have included the transaction in a block, but it has not been executed by execution nodes. -- Executed - Execution nodes have produced a result for the transaction. +- Executed - Execution nodes have produced a result for the transaction. - Sealed - The verification nodes have verified and agreed on the result of the transaction and the consensus node has included the seal in the latest block. - Expired - The transaction was submitted past its expiration block height. @@ -145,9 +141,9 @@ It is **important to differentiate the transaction status and transaction result ::: -### Transaction Result +### Transaction result -Once a transaction is executed, its result will be available, providing details on its success or any errors encountered during execution. It also includes events the transaction may have emitted. +After a transaction is executed, its result will be available, which provides details on its success or any errors encountered during execution. It also includes events the transaction may have emitted. ![Screenshot 2023-08-17 at 16.29.30.png](_transactions_images/Screenshot_2023-08-17_at_16.29.30.png) @@ -160,20 +156,20 @@ From a developer perspective, a transaction is only successful if: ::: -## Transaction Time +## Transaction time -Understanding how transaction times work across different blockchains is crucial for developers and users to optimize their operations and expectations. Flow's multi-node architecture allows for some of the fastest transaction times and finality times across chains. Read on for more detail on how it works and what it means for developers and users. +It's crucial that developers and users understand how transaction times work across different blockchains to optimize their operations and expectations. Flow's multi-node architecture allows for some of the fastest transaction times and finality times across chains. Read on for more detail on how it works and what it means for developers and users. -### Two Key Transaction Questions +### Two key transaction questions Whenever a transaction is processed, two primary questions come to mind: 1. **Inclusion**: Will this transaction be included in the final chain? 2. **Result**: What is the outcome of the transaction? -Different blockchains tackle these questions in varied sequences. For instance, Bitcoin and Ethereum provide answers simultaneously. Layer 2 solutions (L2s) can sometimes address the outcome before confirming inclusion. But there's a catch: you can have an answer to those questions that might be wrong. Flow, on the other hand, prioritizes the inclusion question. +Different blockchains tackle these questions in varied sequences. For instance, Bitcoin and Ethereum provide answers simultaneously. Layer 2 solutions (L2s) can sometimes address the outcome before it confirms inclusion. But, there's a catch: you can have an answer to those questions that might be wrong. Flow, on the other hand, prioritizes the inclusion question. -### Transaction Finality +### Transaction finality Drawing a parallel to traditional finance, a vendor might instantly know if Visa approves a transaction, but the possibility of chargebacks lingers for weeks. This uncertainty introduces the concept of "finality" in blockchain transactions. @@ -181,26 +177,25 @@ In the dominant Proof-of-Stake (PoS) environment, which includes most chains exc - **Preliminary result**: It's an initial answer to the aforementioned questions. The preliminary result doesn't ensure correctness, and there are no economic penalties (like "slashing") if the informant provides false information. - **Soft economic finality**: This stage provides an answer backed by cryptographic proof. If the informant is deceptive, they face economic repercussions or "slashing." -- **Hard economic finality**: The provided answer either holds true, or the entire blockchain requires a restart. The latter case sees at least one-third of the nodes facing economic penalties. +- **Hard economic finality**: The provided answer either holds true, or the entire blockchain requires a restart. The latter case sees at least one-third of the nodes face economic penalties. ![finality.png](./_transactions_images/finality.png) -### Chain Comparisons +### Chain comparisons -Chain | Preliminary | Soft finality | Hard finality ----------|-------------|---------------|--------------- -Solana | 100ms | n/a | ~30s -Ethereum | 15s | n/a | ~15m -Flow | bypass | 4s | ~10s +| Chain | Preliminary | Soft finality | Hard finality | +| -------- | ----------- | ------------- | ------------- | +| Solana | 100ms | n/a | ~13s | +| Ethereum | 15s | n/a | ~13m | +| Flow | bypass | 4s | ~10s | #### Flow -Flow bypasses preliminary results entirely. It reaches soft finality ("Executed") in about 4 seconds and hard finality ("Sealed") in around 10 seconds. If an Access Node on Flow states a transaction has occurred, it's either correct or cryptographic proof exists that can lead to the node's slashing. +Flow bypasses preliminary results entirely. It reaches soft finality ("Executed") in about four seconds and hard finality ("Sealed") in around 10 seconds. If an Access Node on Flow states a transaction has occurred, it's either correct or cryptographic proof exists that can lead to the node's slashing. ![transaction-time.png](_transactions_images/chain-comparison.png) - -## Signing a Transaction +## Sign a transaction Due to the existence of **weighted keys** and **split signing roles**, Flow transactions sometimes need to be signed multiple times by one or more parties. That is, multiple unique signatures may be needed to authorize a single transaction. @@ -209,9 +204,10 @@ A transaction can contain two types of signatures: **payload signatures** and ** ![Screenshot 2023-08-17 at 14.52.51.png](_transactions_images/Screenshot_2023-08-17_at_14.52.51.png) ### Signer Roles + - **Proposer**: the account that specifies a proposal key. -- **Payer**: the account paying for the transaction fees. -- **Authorizers**: zero or more accounts authorizing the transaction to mutate their state. +- **Payer**: the account that pays for the transaction fees. +- **Authorizers**: zero or more accounts that authorize the transaction to mutate their state. ### Payload @@ -223,7 +219,7 @@ The transaction payload is the innermost portion of a transaction and contains t ::: -### Authorization Envelope +### Authorization envelope The transaction authorization envelope contains both the transaction payload and the payload signatures. @@ -235,7 +231,7 @@ Special case: if an account is both the payer and either a proposer or authorize ::: -### Payment Envelope +### Payment envelope The outermost portion of the transaction, which contains the payload and envelope signatures, is referred to as the payment envelope. @@ -245,7 +241,7 @@ Special case: if an account is both the payer and either a proposer or authorize ::: -### Payer Signs Last +### Payer signs last The payer must sign the portion of the transaction that contains the payload signatures, which means that the payer must always sign last. This ensures the payer that they are signing a valid transaction with all of the required payload signatures. @@ -255,19 +251,19 @@ Special case: if an account is both the payer and either a proposer or authorize ::: -### Signature Structure +### Signature structure -A transaction signature is a composite structure containing three fields: +A transaction signature is a composite structure that contains three fields: - Address - Key ID - Signature Data -The *address* and *key ID* fields declare the account key that generated the signature, which is required in order to verify the signature against the correct public key. +The _address_ and _key ID_ fields declare the account key that generated the signature, which is required in order to verify the signature against the correct public key. -### Sequence Numbers +### Sequence numbers -Flow uses sequence numbers to ensure that each transaction executes at most once. This prevents many unwanted situations such as [transaction replay attacks](https://en.wikipedia.org/wiki/Replay_attack). +Flow uses sequence numbers to ensure that each transaction executes at most once. This prevents many unwanted situations such as [transaction replay attacks]. Sequence numbers work similarly to transaction nonces in Ethereum, but with several key differences: @@ -280,11 +276,11 @@ The transaction proposer is only required to specify a sequence number for a sin ::: -Each time an account key is used as a proposal key, its sequence number is incremented by 1. The sequence number is updated after execution, even if the transaction fails (reverts) during execution. +Each time an account key is used as a proposal key, its sequence number is incremented by one. The sequence number is updated after execution, even if the transaction fails (reverts) during execution. -A transaction is failed if its proposal key does not specify a sequence number equal to the sequence number stored on the account *at execution time.* +A transaction is failed if its proposal key does not specify a sequence number equal to the sequence number stored on the account _at execution time._ -## Common Signing Scenarios +## Common signing scenarios Below are several scenarios in which different signature combinations are required to authorize a transaction. @@ -299,7 +295,7 @@ This scenario is only possible if the signature is generated by a key with full | 0x01 | 1 | 1000 | ```json -{ +{ "payload": { "proposalKey": { "address": "0x01", @@ -307,7 +303,7 @@ This scenario is only possible if the signature is generated by a key with full "sequenceNumber": 42 }, "payer": "0x01", - "authorizers": [ "0x01" ] + "authorizers": ["0x01"] }, "payloadSignatures": [], // 0x01 is the payer, so only needs to sign envelope "envelopeSignatures": [ @@ -330,7 +326,7 @@ A transaction that declares a single account as the proposer, payer and authoriz | 0x01 | 2 | 500 | ```json -{ +{ "payload": { "proposalKey": { "address": "0x01", @@ -338,7 +334,7 @@ A transaction that declares a single account as the proposer, payer and authoriz "sequenceNumber": 42 }, "payer": "0x01", - "authorizers": [ "0x01" ] + "authorizers": ["0x01"] }, "payloadSignatures": [], // 0x01 is the payer, so only needs to sign envelope "envelopeSignatures": [ @@ -361,12 +357,12 @@ A transaction that declares a single account as the proposer, payer and authoriz A transaction that declares different accounts for each signing role will require at least one signature from each account. | Account | Key ID | Weight | -| --- | --- | --- | -| 0x01 | 1 | 1000 | -| 0x02 | 1 | 1000 | +| ------- | ------ | ------ | +| 0x01 | 1 | 1000 | +| 0x02 | 1 | 1000 | ```json -{ +{ "payload": { "proposalKey": { "address": "0x01", @@ -374,7 +370,7 @@ A transaction that declares different accounts for each signing role will requir "sequenceNumber": 42 }, "payer": "0x02", - "authorizers": [ "0x01" ] + "authorizers": ["0x01"] }, "payloadSignatures": [ { @@ -388,7 +384,7 @@ A transaction that declares different accounts for each signing role will requir "address": "0x02", "keyId": 1, "sig": "0xdef456" - }, + } ] } ``` @@ -398,14 +394,14 @@ A transaction that declares different accounts for each signing role will requir A transaction that declares different accounts for each signing role may require more than one signature per account if those accounts use weighted keys to achieve multi-sig functionality. | Account | Key ID | Weight | -| --- | --- | --- | -| 0x01 | 1 | 500 | -| 0x01 | 2 | 500 | -| 0x02 | 1 | 500 | -| 0x02 | 2 | 500 | +| ------- | ------ | ------ | +| 0x01 | 1 | 500 | +| 0x01 | 2 | 500 | +| 0x02 | 1 | 500 | +| 0x02 | 2 | 500 | ```json -{ +{ "payload": { "proposalKey": { "address": "0x01", @@ -413,7 +409,7 @@ A transaction that declares different accounts for each signing role may require "sequenceNumber": 42 }, "payer": "0x02", - "authorizers": [ "0x01" ] + "authorizers": ["0x01"] }, "payloadSignatures": [ { @@ -421,7 +417,7 @@ A transaction that declares different accounts for each signing role may require "keyId": 1, "sig": "0xabc123" }, - { + { "address": "0x01", // 0x01 is not payer, so only signs payload "keyId": 2, "sig": "0x123abc" @@ -437,33 +433,45 @@ A transaction that declares different accounts for each signing role may require "address": "0x02", "keyId": 2, "sig": "0x456def" - }, + } ] } ``` -## Transaction Submission and Retrieval +## Transaction submission and retrieval -You can use the Flow CLI to get an existing transaction by ID: +You can use the Flow CLI to get a current transaction by ID: ```sh flow transactions get 1ec90051e3bc74fc36cbd16fc83df08e463dda8f92e8e2193e061f9d41b2ad92 -n mainnet ``` -Find [more about the command in the CLI docs](../../tools/flow-cli/get-flow-data/get-blocks.md). +Find [more about the command in the CLI docs]. -A user can define their own transactions or it can use already defined transactions by the contract authors that can be found by using the FLIX service. +A user can define their own transactions or it can use already defined transactions by the contract authors that can be found by with the FLIX service. Transactions can be submitted and obtained from the access node APIs, currently, there are two gRPC and REST APIs. You can find more information about them here: -[**gRPC Transaction API**](../../networks/access-onchain-data/index.md#transactions) +[**gRPC Transaction API**] + +[**REST Transaction API**] + +There are multiple SDKs that the above APIs for different languages: -[**REST Transaction API**](/http-api#tag/Transactions) +[**Javascript SDK**] -There are multiple SDKs implementing the above APIs for different languages: +[**Go SDK**] -[**Javascript SDK**](../../tools/clients/fcl-js/index.md) +Find a list of all SDKs [here] -[**Go SDK**](../../tools/clients/flow-go-sdk/index.md) + -Find a list of all SDKs [here](../../tools/clients/index.md) +[documentation on transactions]: https://cadence-lang.org/docs/language/transactions +[arguments in the JSON-Cadence Data Interchange Format]: https://cadencelang.dev/docs/1.0/json-cadence-spec +[transaction replay attacks]: https://en.wikipedia.org/wiki/Replay_attack +[more about the command in the CLI docs]: ../../../build/tools/flow-cli/get-flow-data/get-blocks.md +[**gRPC Transaction API**]: ../../../protocol/access-onchain-data/index.md#transactions +[**REST Transaction API**]: /http-api#tag/Transactions +[**Javascript SDK**]: ../../../build/tools/clients/fcl-js/index.md +[**Go SDK**]: ../../../build/tools/clients/flow-go-sdk/index.md +[here]: ../../../build/tools/clients/index.md \ No newline at end of file diff --git a/docs/build/core-contracts/02-fungible-token.md b/docs/build/cadence/core-contracts/02-fungible-token.md similarity index 74% rename from docs/build/core-contracts/02-fungible-token.md rename to docs/build/cadence/core-contracts/02-fungible-token.md index 806e361e42..2eb4464fa3 100644 --- a/docs/build/core-contracts/02-fungible-token.md +++ b/docs/build/cadence/core-contracts/02-fungible-token.md @@ -21,14 +21,15 @@ keywords: - token specification --- +# Fungible Token Contract + The `FungibleToken` contract implements the Fungible Token Standard. It is the second contract ever deployed on Flow. -- [Basic Fungible Token Tutorial](https://cadence-lang.org/docs/tutorial/fungible-tokens) -- [Fungible Token Guide](../guides/fungible-token.md) -- [Fungible Token Standard Repo](https://github.com/onflow/flow-ft) +- [Basic Fungible Token Tutorial] +- [Fungible Token Guide] +- [Fungible Token Standard Repo] -The `FungibleTokenMetadataViews` and `FungibleTokenSwitchboard` contracts -are also deployed to the same account as `FungibleToken`. +The `FungibleTokenMetadataViews` and `FungibleTokenSwitchboard` contracts are also deployed to the same account as `FungibleToken`. Source: [FungibleToken.cdc](https://github.com/onflow/flow-ft/blob/master/contracts/FungibleToken.cdc) @@ -41,10 +42,7 @@ Source: [FungibleToken.cdc](https://github.com/onflow/flow-ft/blob/master/contra # Transactions -All `FungibleToken` projects are encouraged to use -the generic token transactions and scripts in the `flow-ft` [repo](https://github.com/onflow/flow-ft/tree/master/transactions). -They can be used for any token that implements the fungible token standard properly -without changing any code besides import addresses on different networks. +All `FungibleToken` projects are encouraged to use the generic token transactions and scripts in the `flow-ft` [repo]. They can be used for any token that implements the fungible token standard properly without any code change besides import addresses on different networks. # Events @@ -56,18 +54,15 @@ A.{contract address}.{contract name}.{event name} The components of the format are: -- `contract address` - the address of the account the contract has been deployed to -- `contract name` - the name of the contract in the source code -- `event name` - the name of the event as declared in the source code +- `contract address` - the address of the account the contract has been deployed to. +- `contract name` - the name of the contract in the source code. +- `event name` - the name of the event as declared in the source code. -## FungibleToken Events +## FungibleToken events -Contracts that implement the Fungible Token standard get access -to standard events that are emitted every time a relevant action occurs, -like depositing and withdrawing tokens. +Contracts that implement the Fungible Token standard get access to standard events that are emitted every time a relevant action occurs, like deposit and withdraw tokens. -This means that projects do not have to implement their own custom events -unless the standard events do not satisfy requirements they have for events. +This means that projects do not have to implement their own custom events unless the standard events do not satisfy requirements they have for events. The `FungibleToken` events will have the following format: @@ -76,8 +71,7 @@ A.{contract address}.FungibleToken.Deposited A.{contract address}.FungibleToken.Withdrawn ``` -Where the `contract address` is the `FungibleToken` address on the network being queried. -The addresses on the various networks are shown above. +Where the `contract address` is the `FungibleToken` address on the network being queried. The addresses on the various networks are shown above. ### FungibleToken.Deposited @@ -92,9 +86,7 @@ access(all) event Deposited ( ) ``` -Whenever `deposit()` is called on a resource type that implements -`FungibleToken.Vault`, the `FungibleToken.Deposited` event is emitted -with the following arguments: +Whenever `deposit()` is called on a resource type that implements `FungibleToken.Vault`, the `FungibleToken.Deposited` event is emitted with the following arguments: - `type: String`: The type identifier of the token being deposited. - Example: `A.4445e7ad11568276.FlowToken.Vault` @@ -123,9 +115,7 @@ access(all) event Withdrawn ( ) ``` -Whenever `withdraw()` is called on a resource type that implements -`FungibleToken.Vault`, the `FungibleToken.Withdrawn` event is emitted -with the following arguments: +Whenever `withdraw()` is called on a resource type that implements `FungibleToken.Vault`, the `FungibleToken.Withdrawn` event is emitted with the following arguments: - `type: String`: The type identifier of the token being withdrawn. - Example: `A.4445e7ad11568276.FlowToken.Vault` @@ -152,8 +142,7 @@ access(all) event Burned ( ) ``` -Whenever a fungible token that implements `FungibleToken.Vault` is burned -via the `Burner.burn()` method, this event is emitted with the following arguments: +Whenever a fungible token that implements `FungibleToken.Vault` is burned via the `Burner.burn()` method, this event is emitted with the following arguments: - `type: String`: The type identifier of the token that was burnt. - Example: `A.4445e7ad11568276.FlowToken.Vault` @@ -161,3 +150,10 @@ via the `Burner.burn()` method, this event is emitted with the following argumen - Example: `0.00017485` - `fromUUID: UInt64`: The UUID of the Vault that was burnt. - Example: `177021372071991` + + + +[Basic Fungible Token Tutorial]: https://cadence-lang.org/docs/tutorial/fungible-tokens +[Fungible Token Guide]: ../../../blockchain-development-tutorials/tokens/fungible-token-cadence.md +[Fungible Token Standard Repo]: https://github.com/onflow/flow-ft +[repo]: https://github.com/onflow/flow-ft/tree/master/transactions diff --git a/docs/build/core-contracts/03-flow-token.md b/docs/build/cadence/core-contracts/03-flow-token.md similarity index 81% rename from docs/build/core-contracts/03-flow-token.md rename to docs/build/cadence/core-contracts/03-flow-token.md index ff9725ea69..48c9b11230 100644 --- a/docs/build/core-contracts/03-flow-token.md +++ b/docs/build/cadence/core-contracts/03-flow-token.md @@ -21,9 +21,11 @@ keywords: - Flow testnet --- +# Flow Token Contract + The `FlowToken` contract defines the FLOW network token. -Source: [FlowToken.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowToken.cdc) +Source: [FlowToken.cdc] | Network | Contract Address | | ------------------------- | -------------------- | @@ -32,18 +34,16 @@ Source: [FlowToken.cdc](https://github.com/onflow/flow-core-contracts/blob/maste | Testnet | `0x7e60df042a9c0868` | | Mainnet | `0x1654653399040a61` | -# Transactions +## Transactions -Transactions and scripts for `FlowToken` are in the `flow-core-contracts` [repo](https://github.com/onflow/flow-core-contracts/tree/master/transactions/flowToken). +Transactions and scripts for `FlowToken` are in the `flow-core-contracts` [repo]. As mentioned in the `FungibleToken` page, developers are encouraged to use -the generic token transactions in the `flow-ft` [repo](https://github.com/onflow/flow-ft/tree/master/transactions) instead. +the generic token transactions in the [`flow-ft` repo] instead. -# Events +## Events -Flow relies on a set of core contracts that define key portions of the Flow protocol. Those contracts are core contracts -and are made to emit the events documented below. You can read about the [core contracts here](./index.md) -and view their source code and event definitions. +Flow relies on a set of core contracts that define key portions of the Flow protocol. Those contracts are core contracts and are made to emit the events documented below. You can read about the [core contracts here] and view their source code and event definitions. Events emitted from core contracts follow a standard format: @@ -53,18 +53,17 @@ A.{contract address}.{contract name}.{event name} The components of the format are: -- `contract address` - the address of the account the contract has been deployed to -- `contract name` - the name of the contract in the source code -- `event name` - the name of the event as declared in the source code +- `contract address` - the address of the account the contract has been deployed to. +- `contract name` - the name of the contract in the source code. +- `event name` - the name of the event as declared in the source code. -### Flow Token Contract +### Flow token contract Description of events emitted from the [FLOW Token contract](./03-flow-token.md). -The contract defines the fungible FLOW token. Please note that events for the fungible token contracts are the same -if deployed to a different account but the `contract address` is -changed to the address of the account the contract has been deployed to. -### Tokens Initialized +The contract defines the fungible FLOW token. Please note that events for the fungible token contracts are the same if deployed to a different account but the `contract address` is changed to the address of the account the contract has been deployed to. + +### Tokens initialized Event that is emitted when the contract gets created. @@ -80,7 +79,7 @@ access(all) event TokensInitialized(initialSupply: UFix64) | ------------- | ------ | -------------------------------- | | initialSupply | UFix64 | The initial supply of the tokens | -### Tokens Withdrawn +### Tokens withdrawn Event that is emitted when tokens get withdrawn from a Vault. @@ -97,7 +96,7 @@ access(all) event TokensWithdrawn(amount: UFix64, from: Address?) | amount | UFix64 | The amount of tokens withdrawn | | from | Address? | Optional address of the account that owns the vault where tokens were withdrawn from. `nil` if the vault is not in an account's storage | -### Tokens Deposited +### Tokens deposited Event that is emitted when tokens get deposited to a Vault. @@ -114,7 +113,7 @@ access(all) event TokensDeposited(amount: UFix64, to: Address?) | amount | UFix64 | The amount of tokens withdrawn | | to | Address? | Optional address of the account that owns the vault where tokens were deposited to. `nil` if the vault is not in an account's storage | -### Tokens Minted +### Tokens minted Event that is emitted when new tokens gets minted. @@ -130,7 +129,7 @@ access(all) event TokensMinted(amount: UFix64) | ------ | ------ | ---------------------------- | | amount | UFix64 | The amount of tokens to mint | -### Tokens Burned +### Tokens burned Event that is emitted when tokens get destroyed. @@ -146,7 +145,7 @@ access(all) event TokensBurned(amount: UFix64) | ------ | ------ | ---------------------------- | | amount | UFix64 | The amount of tokens to burn | -### Minter Created +### Minter created Event that is emitted when a new minter resource gets created. @@ -174,6 +173,14 @@ Event that is emitted when a new burner Resource gets created. access(all) event BurnerCreated() ``` -### Staking Events +### Staking events + +To learn more about staking events, read [staking/events/] + + -To learn more about staking events, read [staking/events/](../../networks/staking/07-staking-scripts-events.md) +[FlowToken.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowToken.cdc +[repo]: https://github.com/onflow/flow-core-contracts/tree/master/transactions/flowToken +[`flow-ft` repo]: https://github.com/onflow/flow-ft/tree/master/transactions +[core contracts here]: ./index.md +[staking/events/]: ../../../protocol/staking/07-staking-scripts-events.md diff --git a/docs/build/core-contracts/04-service-account.md b/docs/build/cadence/core-contracts/04-service-account.md similarity index 74% rename from docs/build/core-contracts/04-service-account.md rename to docs/build/cadence/core-contracts/04-service-account.md index ac71f708ce..5deddce8fa 100644 --- a/docs/build/core-contracts/04-service-account.md +++ b/docs/build/cadence/core-contracts/04-service-account.md @@ -20,6 +20,8 @@ keywords: - network configuration --- +# Service Account Contracts + The service account is the account that manages the core protocol requirements of Flow. | Network | Contract Address | @@ -31,14 +33,13 @@ The service account is the account that manages the core protocol requirements o Here are three important contracts deployed to the service account: -# FlowServiceAccount +## FlowServiceAccount -`FlowServiceAccount` tracks transaction fees, deployment permissions, and provides -some convenience methods for Flow Token operations. +`FlowServiceAccount` tracks transaction fees, deployment permissions, and provides some convenience methods for Flow Token operations. -Source: [FlowServiceAccount.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowServiceAccount.cdc) +Source: [FlowServiceAccount.cdc] -## Events +### Events Important events from `FlowServiceAccount` are: @@ -47,16 +48,13 @@ access(all) event TransactionFeeUpdated(newFee: UFix64) access(all) event AccountCreationFeeUpdated(newFee: UFix64) ``` -# RandomBeaconHistory +## RandomBeaconHistory -- `RandomBeaconHistory` stores the history of random sources generated by - the Flow network. The defined Heartbeat resource is - updated by the Flow Service Account at the end of every block - with that block's source of randomness. +- `RandomBeaconHistory` stores the history of random sources generated by the Flow network. The defined Heartbeat resource is updated by the Flow Service Account at the end of every block with that block's source of randomness. -Source: [RandomBeaconHistory.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/RandomBeaconHistory.cdc) +Source: [RandomBeaconHistory.cdc] -## Events +### Events Important events from `RandomBeaconHistory` are: @@ -75,15 +73,13 @@ access(all) event RandomHistoryMissing(blockHeight: UInt64, gapStartHeight: UInt access(all) event RandomHistoryBackfilled(blockHeight: UInt64, gapStartHeight: UInt64, count: UInt64) ``` -# NodeVersionBeacon +## NodeVersionBeacon -- `NodeVersionBeacon` holds the past - and future protocol versions that should be used - to execute/handle blocks at a given block height. +- `NodeVersionBeacon` holds the past and future protocol versions that should be used to execute or handle blocks at a given block height. -Source: [NodeVersionBeacon.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/NodeVersionBeacon.cdc) +Source: [NodeVersionBeacon.cdc] -## Events +### Events Important events from `NodeVersionBeacon` are: @@ -102,3 +98,9 @@ access(all) event VersionBeacon( /// freeze period is measured in blocks (from the current block). access(all) event NodeVersionBoundaryFreezePeriodChanged(freezePeriod: UInt64) ``` + + + +[FlowServiceAccount.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowServiceAccount.cdc +[RandomBeaconHistory.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/RandomBeaconHistory.cdc +[NodeVersionBeacon.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/NodeVersionBeacon.cdc \ No newline at end of file diff --git a/docs/build/core-contracts/05-flow-fees.md b/docs/build/cadence/core-contracts/05-flow-fees.md similarity index 88% rename from docs/build/core-contracts/05-flow-fees.md rename to docs/build/cadence/core-contracts/05-flow-fees.md index 7bcf6893c1..ddb096ce71 100644 --- a/docs/build/core-contracts/05-flow-fees.md +++ b/docs/build/cadence/core-contracts/05-flow-fees.md @@ -21,11 +21,11 @@ keywords: - blockchain fees --- -## FlowFees +# Flow Fees Contract The `FlowFees` contract is where all the collected flow fees are gathered. -Source: [FlowFees.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowFees.cdc) +Source: [FlowFees.cdc] | Network | Contract Address | | ------------------------- | -------------------- | @@ -56,7 +56,7 @@ access(all) event FeeParametersChanged(surgeFactor: UFix64, inclusionEffortCost: The `FlowStorageFees` contract defines the parameters and utility methods for storage fees. -Source: [FlowStorageFees.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowStorageFees.cdc) +Source: [FlowStorageFees.cdc] | Network | Contract Address | | ------------------------- | -------------------- | @@ -76,3 +76,8 @@ access(all) event StorageMegaBytesPerReservedFLOWChanged(_ storageMegaBytesPerRe // Emitted when the minimum amount of Flow tokens that an account needs to have reserved for storage capacity changes. access(all) event MinimumStorageReservationChanged(_ minimumStorageReservation: UFix64) ``` + + + +[FlowFees.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowFees.cdc +[FlowStorageFees.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowStorageFees.cdc diff --git a/docs/build/core-contracts/06-staking-contract-reference.md b/docs/build/cadence/core-contracts/06-staking-contract-reference.md similarity index 59% rename from docs/build/core-contracts/06-staking-contract-reference.md rename to docs/build/cadence/core-contracts/06-staking-contract-reference.md index 534edae87d..3a8223823a 100644 --- a/docs/build/core-contracts/06-staking-contract-reference.md +++ b/docs/build/cadence/core-contracts/06-staking-contract-reference.md @@ -21,11 +21,11 @@ keywords: - staking requirements --- -## Contract +# Flow Staking Contract Reference The `FlowIDTableStaking` contract is the central table that manages staked nodes, delegation and rewards. -Source: [FlowIDTableStaking.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowIDTableStaking.cdc) +Source: [FlowIDTableStaking.cdc] | Network | Contract Address | | ------------------------- | -------------------- | @@ -34,39 +34,37 @@ Source: [FlowIDTableStaking.cdc](https://github.com/onflow/flow-core-contracts/b | Testnet | `0x9eca2b38b18b5dfe` | | Mainnet | `0x8624b52f9ddcd04a` | -## Transactions and Scripts +## Transactions and scripts -Transactions for the staking contract are in the `flow-core-contracts` repo. -Developers and users are advised to use [the staking collection transactions](../../networks/staking/14-staking-collection.md) -to stake tokens instead of the basic transactions that are used for tests. +Transactions for the staking contract are in the `flow-core-contracts` repo. Developers and users are advised to use [the staking collection transactions] to stake tokens instead of the basic transactions that are used for tests. -### Getting Staking Info with Scripts +### Getting staking info with scripts These scripts are read-only and get info about the current state of the staking contract. | ID | Name | Source | | ----------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`SC.01`** | Get Delegation Cut Percentage | [idTableStaking/get_cut_percentage.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_cut_percentage.cdc) | -| **`SC.02`** | Get Minimum Stake Requirements | [idTableStaking/get_stake_requirements.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_stake_requirements.cdc) | -| **`SC.03`** | Get Total Weekly Reward Payout | [idTableStaking/get_weekly_payout.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_weekly_payout.cdc) | -| **`SC.04`** | Get Current Staked Node Table | [idTableStaking/get_current_table.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_current_table.cdc) | -| **`SC.05`** | Get Proposed Staked Node Table | [idTableStaking/get_proposed_table.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_proposed_table.cdc) | -| **`SC.06`** | Get Total Flow Staked | [idTableStaking/get_total_staked.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_total_staked.cdc) | -| **`SC.07`** | Get Total Flow Staked by Node Type | [idTableStaking/get_total_staked_by_type.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_total_staked_by_type.cdc) | -| **`SC.08`** | Get All Info about a single NodeID | [idTableStaking/get_node_info.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_node_info.cdc) | -| **`SC.09`** | Get a node's total Commitment (delegators) | [idTableStaking/get_node_total_commitment.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_node_total_commitment.cdc) | -| **`SC.10`** | Get All Info about a single Delegator | [idTableStaking/delegation/get_delegator_info.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/delegation/get_delegator_info.cdc) | -| **`SC.11`** | Get a node's total Commitment | [idTableStaking/get_node_total_commitment_without_delegators.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_node_total_commitment_without_delegators.cdc) | - -### Delegator Transactions - -Documentation for delegating with tokens is described in the staking documentation -for [the staking collection](../../networks/staking/14-staking-collection.md) +| **`SC.01`** | Get Delegation Cut Percentage | [idTableStaking/get_cut_percentage.cdc] | +| **`SC.02`** | Get Minimum Stake Requirements | [idTableStaking/get_stake_requirements.cdc] | +| **`SC.03`** | Get Total Weekly Reward Payout | [idTableStaking/get_weekly_payout.cdc] | +| **`SC.04`** | Get Current Staked Node Table | [idTableStaking/get_current_table.cdc] | +| **`SC.05`** | Get Proposed Staked Node Table | [idTableStaking/get_proposed_table.cdc] | +| **`SC.06`** | Get Total Flow Staked | [idTableStaking/get_total_staked.cdc] | +| **`SC.07`** | Get Total Flow Staked by Node Type | [idTableStaking/get_total_staked_by_type.cdc] | +| **`SC.08`** | Get All Info about a single NodeID | [idTableStaking/get_node_info.cdc] | +| **`SC.09`** | Get a node's total Commitment (delegators) | [idTableStaking/get_node_total_commitment.cdc] | +| **`SC.10`** | Get All Info about a single Delegator | [idTableStaking/delegation/get_delegator_info.cdc] | +| **`SC.11`** | Get a node's total Commitment | [idTableStaking/get_node_total_commitment_without_delegators.cdc] | + +### Delegator transactions + +Documentation for token delegation is described in the staking documentation +for [the staking collection]. ## Events The `FlowIDTableStaking` contract emits an event whenever an important action occurs. -See the [staking events Documentation](../../networks/staking/07-staking-scripts-events.md) for more information about each event. +See the [staking events Documentation]for more information about each event. ```cadence /// Epoch @@ -114,3 +112,21 @@ See the [staking events Documentation](../../networks/staking/07-staking-scripts access(all) event NewStakingMinimums(newMinimums: {UInt8: UFix64}) access(all) event NewDelegatorStakingMinimum(newMinimum: UFix64) ``` + + + +[FlowIDTableStaking.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowIDTableStaking.cdc +[the staking collection transactions]: ../../../protocol/staking/14-staking-collection.md +[idTableStaking/get_cut_percentage.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_cut_percentage.cdc +[idTableStaking/get_stake_requirements.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_stake_requirements.cdc +[idTableStaking/get_weekly_payout.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_weekly_payout.cdc +[idTableStaking/get_current_table.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_current_table.cdc +[idTableStaking/get_proposed_table.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_proposed_table.cdc +[idTableStaking/get_total_staked.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_total_staked.cdc +[idTableStaking/get_total_staked_by_type.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_total_staked_by_type.cdc +[idTableStaking/get_node_info.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_node_info.cdc +[idTableStaking/get_node_total_commitment.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_node_total_commitment.cdc +[idTableStaking/delegation/get_delegator_info.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/delegation/get_delegator_info.cdc +[idTableStaking/get_node_total_commitment_without_delegators.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/idTableStaking/scripts/get_node_total_commitment_without_delegators.cdc +[the staking collection]: ../../../protocol/staking/14-staking-collection.md +[staking events Documentation]: ../../../protocol/staking/07-staking-scripts-events.md \ No newline at end of file diff --git a/docs/build/cadence/core-contracts/07-epoch-contract-reference.md b/docs/build/cadence/core-contracts/07-epoch-contract-reference.md new file mode 100644 index 0000000000..a614134f86 --- /dev/null +++ b/docs/build/cadence/core-contracts/07-epoch-contract-reference.md @@ -0,0 +1,107 @@ +--- +title: Flow Epoch Contracts Reference +sidebar_position: 7 +sidebar_label: Epoch Contracts +description: Learn about Flow's epoch-related contracts that manage network phases, quorum certificates, and distributed key generation. Understand how FlowEpoch, FlowClusterQC, and FlowDKG contracts work together. +keywords: + - epoch contracts + - FlowEpoch + - FlowClusterQC + - FlowDKG + - epoch phases + - quorum certificates + - distributed key generation + - epoch metadata + - epoch counter + - epoch scripts + - QC voting + - DKG participants + - network phases + - Flow protocol + - epoch management +--- + +# Contract + +The `FlowEpoch` contract is the state machine that manages Epoch phases and emits service events. The `FlowClusterQC` and `FlowDKG` contracts manage the processes that happen during the Epoch Setup phase. + +These contracts are all deployed to the same account as the `FlowIDTableStaking` contract. + +Sources: + +- [FlowEpoch.cdc] +- [FlowClusterQC.cdc] +- [FlowDKG.cdc] + +| Network | Contract Address | +| ------------------------- | -------------------- | +| Emulator | `0xf8d6e0586b0a20c7` | +| Cadence Testing Framework | `0x0000000000000001` | +| Testnet | `0x9eca2b38b18b5dfe` | +| Mainnet | `0x8624b52f9ddcd04a` | + +## Transactions + +### Get epoch info + +These scripts are read-only and get info about the current state of the epoch contract. + +| ID | Name | Source | +| ----------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| **`EP.01`** | Get Epoch Metadata | [epoch/get_epoch_metadata.cdc] | +| **`EP.02`** | Get Configurable Metadata | [epoch/get_config_metadata.cdc] | +| **`EP.03`** | Get Epoch Counter | [epoch/get_epoch_counter.cdc] | +| **`EP.04`** | Get Epoch Phase | [epoch/get_epoch_phase.cdc] | + +## Quorum certificate transactions and scripts + +| ID | Name | Source | +| ----------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **`QC.01`** | Create QC Voter | [quorumCertificate/get_epoch_metadata.cdc] | +| **`QC.02`** | Submit QC Vote | [quorumCertificate/get_config_metadata.cdc] | +| **`QC.03`** | Get Collector Cluster | [quorumCertificate/scripts/get_cluster.cdc] | +| **`QC.04`** | Get QC Enabled | [quorumCertificate/scripts/get_qc_enabled.cdc] | +| **`QC.05`** | Get Node Has Voted | [quorumCertificate/scripts/get_node_has_voted.cdc] | +| **`QC.06`** | Get QC Voting Complete | [quorumCertificate/scripts/get_voting_completed.cdc] | + +## DKG transactions and scripts + +| ID | Name | Source | +| ------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **`DKG.01`** | Create DKG Participant | [dkg/create_participant.cdc] | +| **`DKG.02`** | Get Configurable Metadata | [dkg/send_whiteboard_message.cdc] | +| **`DKG.03`** | Send Final Submission | [dkg/send_final_submission.cdc] | +| **`DKG.04`** | Get DKG Enabled | [dkg/scripts/get_dkg_enabled.cdc] | +| **`DKG.05`** | Get DKG Completed | [dkg/scripts/get_dkg_completed.cdc] | +| **`DKG.06`** | Get Whiteboard Messages | [dkg/scripts/get_whiteboard_messages.cdc] | +| **`DKG.07`** | Get Final Submissions | [dkg/scripts/get_final_submissions.cdc] | +| **`DKG.08`** | Get Node Has Submitted | [dkg/scripts/get_node_has_submitted.cdc] | + +# Events + +See the [epoch documentation] for a list and documentation for important `FlowEpoch` events. + + + +[FlowEpoch.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/epochs/FlowEpoch.cdc +[FlowClusterQC.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/epochs/FlowClusterQC.cdc +[FlowDKG.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/epochs/FlowDKG.cdc +[epoch documentation]: ../../../protocol/staking/05-epoch-scripts-events.md +[epoch/get_epoch_metadata.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/epoch/scripts/get_epoch_metadata.cdc) +[epoch/get_config_metadata.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/epoch/scripts/get_config_metadata.cdc +[epoch/get_epoch_counter.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/epoch/scripts/get_epoch_counter.cdc +[epoch/get_epoch_phase.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/epoch/scripts/get_epoch_phase.cdc) +[quorumCertificate/get_epoch_metadata.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/create_voter.cdc) +[quorumCertificate/get_config_metadata.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/submit_vote.cdc +[quorumCertificate/scripts/get_cluster.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/scripts/get_cluster.cdc +[quorumCertificate/scripts/get_qc_enabled.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/scripts/get_qc_enabled.cdc +[quorumCertificate/scripts/get_node_has_voted.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/scripts/get_node_has_voted.cdc +[quorumCertificate/scripts/get_voting_completed.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/scripts/get_voting_completed.cdc +[dkg/create_participant.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/create_participant.cdc +[dkg/send_whiteboard_message.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/send_whiteboard_message.cdc +[dkg/send_final_submission.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/send_final_submission.cdc +[dkg/scripts/get_dkg_enabled.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/scripts/get_dkg_enabled.cdc +[dkg/scripts/get_dkg_completed.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/scripts/get_dkg_completed.cdc +[dkg/scripts/get_whiteboard_messages.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/scripts/get_whiteboard_messages.cdc +[dkg/scripts/get_final_submissions.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/scripts/get_final_submissions.cdc +[dkg/scripts/get_node_has_submitted.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/scripts/get_node_has_submitted.cdc \ No newline at end of file diff --git a/docs/build/core-contracts/08-non-fungible-token.md b/docs/build/cadence/core-contracts/08-non-fungible-token.md similarity index 60% rename from docs/build/core-contracts/08-non-fungible-token.md rename to docs/build/cadence/core-contracts/08-non-fungible-token.md index 0b8e0de64f..0aaccaec0b 100644 --- a/docs/build/core-contracts/08-non-fungible-token.md +++ b/docs/build/cadence/core-contracts/08-non-fungible-token.md @@ -21,14 +21,15 @@ keywords: - digital assets --- -The `NonFungibleToken` contract interface implements the Fungible Token Standard. -All NFT contracts are encouraged to import and implement this standard. +# Non-Fungible Token Contract -- [Basic Non-Fungible Token Tutorial](https://cadence-lang.org/docs/tutorial/non-fungible-tokens-1) -- [Non Fungible Token Guide](../guides/nft.md) -- [Non Fungible Token Standard Repo](https://github.com/onflow/flow-nft) +The `NonFungibleToken` contract interface implements the Fungible Token Standard. All NFT contracts are encouraged to import and implement this standard. -Source: [NonFungibleToken.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc) +- [Basic Non-Fungible Token Tutorial] +- [Non Fungible Token Guide] +- [Non Fungible Token Standard Repo] + +Source: [NonFungibleToken.cdc] | Network | Contract Address | | ------------------------- | -------------------- | @@ -37,14 +38,11 @@ Source: [NonFungibleToken.cdc](https://github.com/onflow/flow-nft/blob/master/co | Testnet | `0x631e88ae7f1d7c20` | | Mainnet | `0x1d7e57aa55817448` | -# Transactions +## Transactions -All `NonFungibleToken` projects are encouraged to use -the generic token transactions and scripts in the `flow-nft` [repo](https://github.com/onflow/flow-nft/tree/master/transactions). -They can be used for any token that implements the non-fungible token standard properly -without changing any code besides import addresses on different networks. +All `NonFungibleToken` projects are encouraged to use the generic token transactions and scripts in the `flow-nft` [repo]. You can use them for any token that implements the non-fungible token standard properly, and you won't have to change any code besides import addresses on different networks. -# Events +## Events Events emitted from all contracts follow a standard format: @@ -54,18 +52,15 @@ A.{contract address}.{contract name}.{event name} The components of the format are: -- `contract address` - the address of the account the contract has been deployed to -- `contract name` - the name of the contract in the source code -- `event name` - the name of the event as declared in the source code +- `contract address` - the address of the account the contract has been deployed to. +- `contract name` - the name of the contract in the source code. +- `event name` - the name of the event as declared in the source code. -## NonFungibleToken Events +## NonFungibleToken events -Contracts that implement the Non-Fungible Token standard get access -to standard events that are emitted every time a relevant action occurs, -like depositing and withdrawing tokens. +Contracts that implement the Non-Fungible Token standard get access to standard events that are emitted every time a relevant action occurs, like token deposits and withdrawls. -This means that projects do not have to implement their own custom events -unless the standard events do not satisfy requirements they have for events. +This means that projects do not have to implement their own custom events unless the standard events do not satisfy requirements they have for events. The `NonFungibleToken` events will have the following format: @@ -74,8 +69,7 @@ A.{contract address}.NonFungibleToken.Deposited A.{contract address}.NonFungibleToken.Withdrawn ``` -Where the `contract address` is the `NonFungibleToken` address on the network being queried. -The addresses on the various networks are shown above. +Where the `contract address` is the `NonFungibleToken` address on the network being queried. The addresses on the various networks are shown above. ### NonFungibleToken.Deposited @@ -89,9 +83,7 @@ access(all) event Deposited ( ) ``` -Whenever `deposit()` is called on a resource type that implements -`NonFungibleToken.Collection`, the `NonFungibleToken.Deposited` event is emitted -with the following arguments: +Whenever `deposit()` is called on a resource type that implements `NonFungibleToken.Collection`, the `NonFungibleToken.Deposited` event is emitted with the following arguments: - `type: String`: The type identifier of the token being deposited. - Example: `A.4445e7ad11568276.TopShot.NFT` @@ -99,8 +91,7 @@ with the following arguments: - Example: `173838` - `uuid: UInt64`: The UUID of the token that was deposited. - Example: `177021372071991` -- `to: Address?`: The address of the account that owns the Collection that received - the token. If the collection is not stored in an account, `to` will be `nil`. +- `to: Address?`: The address of the account that owns the Collection that received the token. If the collection is not stored in an account, `to` will be `nil`. - Example: `0x4445e7ad11568276` - `collectionUUID: UInt64`: The UUID of the Collection that received the token. - Example: `177021372071991` @@ -117,9 +108,7 @@ access(all) event Withdrawn ( ) ``` -Whenever `withdraw()` is called on a resource type that implements -`NonFungibleToken.Collection`, the `NonFungibleToken.Withdrawn` event is emitted -with the following arguments: +Whenever `withdraw()` is called on a resource type that implements `NonFungibleToken.Collection`, the `NonFungibleToken.Withdrawn` event is emitted with the following arguments: - `type: String`: The type identifier of the token being withdrawn. - Example: `A.4445e7ad11568276.TopShot.NFT` @@ -127,8 +116,7 @@ with the following arguments: - Example: `113838` - `uuid: UInt64`: The UUID of the token that was withdrawn. - Example: `177021372071991` -- `from: Address?`: The address of the account that owns the Collection that - the token was withdrawn from. If the collection is not stored in an account, `to` will be `nil`. +- `from: Address?`: The address of the account that owns the Collection that the token was withdrawn from. If the collection is not stored in an account, `to` will be `nil`. - Example: `0x4445e7ad11568276` - `providerUUID: UInt64`: The UUID of the Collection that the token was withdrawn from. - Example: `177021372071991` @@ -144,17 +132,21 @@ access(all) event Updated( ) ``` -Whenever a non-fungible token is updated for whatever reason, -projects should call the `NonFungibleToken.emitNFTUpdated()` function -to emit this event. It indicates to event listeners that they should query -the NFT to update any stored information they have about the NFT in their database. +Whenever a non-fungible token is updated for whatever reason, projects should call the `NonFungibleToken.emitNFTUpdated()` function to emit this event. It indicates to event listeners that they should query the NFT to update any stored information they have about the NFT in their database. - `type: String`: The type identifier of the token that was updated. - Example: `A.4445e7ad11568276.TopShot.NFT` -- `id: UInt64`: The ID of the token that was updated. Note: This may or may not be the UUID. +- `id: UInt64`: The ID of the token that was updated. This may or may not be the UUID. - Example: `173838` - `uuid: UInt64`: The UUID of the token that was updated. - Example: `177021372071991` -- `owner: Address?`: The address of the account that owns the Collection that owns - the token. If the collection is not stored in an account, `to` will be `nil`. +- `owner: Address?`: The address of the account that owns the Collection that owns the token. If the collection is not stored in an account, `to` will be `nil`. - Example: `0x4445e7ad11568276` + + + +[repo]: https://github.com/onflow/flow-nft/tree/master/transactions +[Basic Non-Fungible Token Tutorial]: https://cadence-lang.org/docs/tutorial/non-fungible-tokens-1) +[Non Fungible Token Guide]: ../../../blockchain-development-tutorials/tokens/nft-cadence.md) +[Non Fungible Token Standard Repo]: https://github.com/onflow/flow-nft) +[NonFungibleToken.cdc]: https://github.com/onflow/flow-nft/blob/master/contracts/NonFungibleToken.cdc) \ No newline at end of file diff --git a/docs/build/core-contracts/09-nft-metadata.md b/docs/build/cadence/core-contracts/09-nft-metadata.md similarity index 52% rename from docs/build/core-contracts/09-nft-metadata.md rename to docs/build/cadence/core-contracts/09-nft-metadata.md index d957df6f6f..7d0c7a750e 100644 --- a/docs/build/core-contracts/09-nft-metadata.md +++ b/docs/build/cadence/core-contracts/09-nft-metadata.md @@ -2,14 +2,14 @@ title: NFT Metadata Contract sidebar_position: 9 sidebar_label: NFT Metadata -description: Learn about Flow's NFT metadata standards implemented through ViewResolver and MetadataViews contracts. Understand how to attach and manage on-chain metadata for NFTs and integrate with the Flow NFT Catalog. +description: Learn about Flow's NFT metadata standards implemented through ViewResolver and MetadataViews contracts. Understand how to attach and manage onchain metadata for NFTs and integrate with the Flow NFT Catalog. keywords: - NFT metadata - ViewResolver - MetadataViews - metadata standard - NFT catalog - - on-chain metadata + - onchain metadata - NFT interoperability - metadata views - FLIP-0636 @@ -21,14 +21,15 @@ keywords: - NFT optimization --- -The `ViewResolver` and `MetadataViews` contracts implement a standard to attach on-chain metadata -to NFTs. This standard was originally proposed in [FLIP-0636](https://github.com/onflow/flips/blob/main/application/20210916-nft-metadata.md). +# NFT Metadata Contract + +The `ViewResolver` and `MetadataViews` contracts implement a standard to attach onchain metadata to NFTs. This standard was originally proposed in [FLIP-0636]. It is deployed at the same address as the `NonFungibleToken` contract interface. -Source: [ViewResolver.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/ViewResolver.cdc) +Source: [ViewResolver.cdc] -Source: [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc) +Source: [MetadataViews.cdc] | Network | Contract Address | | ------------------------- | -------------------- | @@ -37,10 +38,19 @@ Source: [MetadataViews.cdc](https://github.com/onflow/flow-nft/blob/master/contr | Testnet | `0x631e88ae7f1d7c20` | | Mainnet | `0x1d7e57aa55817448` | -There exists a tool, [Flow NFT Catalog](https://flow-nft-catalog.com), which enables dapp developers the ability to unlock interoperability of your NFT collection across the Flow ecosystem. This will help make your NFT collection's metadata more discoverable and interoperable. +There exists a tool, [Flow NFT Catalog], which allows dapp developers to unlock interoperability of your NFT collection across the Flow ecosystem. This will help make your NFT collection's metadata more discoverable and interoperable. To optimize your NFT collections for this catalog, you'll need to: -1. Update your NFT contract to support `ViewResolver` and `MetadataViews` with implementation of the [core NFT views](../advanced-concepts/metadata-views.md). +1. Update your NFT contract to support `ViewResolver` and `MetadataViews` with implementation of the [core NFT views]. 2. Deploy the updated contract to both testnet and mainnet. -3. Afterwards, onboard your NFT to the Flow NFT catalog at [https://flow-nft-catalog.com](https://flow-nft-catalog.com). +3. Afterwards, onboard your NFT to the Flow NFT catalog at [https://flow-nft-catalog.com]. + + + +[FLIP-0636]: https://github.com/onflow/flips/blob/main/application/20210916-nft-metadata.md +[ViewResolver.cdc]: https://github.com/onflow/flow-nft/blob/master/contracts/ViewResolver.cdc +[MetadataViews.cdc]: https://github.com/onflow/flow-nft/blob/master/contracts/MetadataViews.cdc +[Flow NFT Catalog]: https://flow-nft-catalog.com +[core NFT views]: ../advanced-concepts/metadata-views.md +[https://flow-nft-catalog.com]: https://flow-nft-catalog.com \ No newline at end of file diff --git a/docs/build/core-contracts/10-nft-storefront.md b/docs/build/cadence/core-contracts/10-nft-storefront.md similarity index 56% rename from docs/build/core-contracts/10-nft-storefront.md rename to docs/build/cadence/core-contracts/10-nft-storefront.md index 553dc5fd9e..2d8d1711ec 100644 --- a/docs/build/core-contracts/10-nft-storefront.md +++ b/docs/build/cadence/core-contracts/10-nft-storefront.md @@ -21,19 +21,18 @@ keywords: - Flow marketplace --- -The NFT Storefront contracts implement a standard way to list NFTs for sale -and buy them from listings. `NFTStorefrontV2` is the more powerful and full-featured -version, so developers and users are encouraged to use it instead of `NFTStorefront` -or their own implementation. +# NFT Storefront Smart Contract + +The NFT Storefront contracts implement a standard way to list NFTs for sale and buy them from listings. `NFTStorefrontV2` is the more powerful and full-featured version, so developers and users are encouraged to use it instead of `NFTStorefront` or their own implementation. Source: [NFTStorefrontV2.cdc] -| Network | Contract Address | -| ------- | -------------------- | -| Emulator | `0xf8d6e0586b0a20c7` | +| Network | Contract Address | +| ------------------------- | -------------------- | +| Emulator | `0xf8d6e0586b0a20c7` | | Cadence Testing Framework | `0x0000000000000001` | -| Testnet | `0x2d55b98eb200daef` | -| Mainnet | `0x4eb8a10cb9f87357` | +| Testnet | `0x2d55b98eb200daef` | +| Mainnet | `0x4eb8a10cb9f87357` | Source: [NFTStorefront.cdc] @@ -46,106 +45,117 @@ Source: [NFTStorefront.cdc] The `NFTStorefrontV2` contract lets you create a _non-custodial Resource (NFT) marketplace_ on the FLOW blockchain. -`NFTStorefrontV2` makes it simple for Sellers to list NFTs in dApp specific marketplaces. DApp developers leverage the APIs provided by the contract to manage listings being offered for sale and to transact NFT trades. +`NFTStorefrontV2` makes it simple for Sellers to list NFTs in dApp specific marketplaces. dApp developers leverage the APIs provided by the contract to manage listings for sale and to transact NFT trades. ![dapps_1](https://user-images.githubusercontent.com/14581509/191749748-714f9d8f-cb41-4be4-a3d2-ec84cb8b5ffb.png) -Developers should use the `NFTStorefrontV2` to create their marketplace and to enable p2p purchases. The diagram below shows how dApps can facilitate the creation of NFT listings for different marketplaces and how marketplaces can filter their listings. +Developers should use the `NFTStorefrontV2` to create their marketplace and to alloq p2p purchases. The diagram below shows how dApps can facilitate the creation of NFT listings for different marketplaces and how marketplaces can filter their listings. -Listings made through a specific dApp storefront can be simultaneously listed on 3rd party marketplaces beyond that dApp. Well known 3rd party marketplaces listen for compatible NFT listing events enabling the automation of listings into their marketplace dashboards. +Listings made through a specific dApp storefront can be simultaneously listed on 3rd party marketplaces beyond that dApp. Well known 3rd party marketplaces listen for compatible NFT listing events, which allows the automation of listings into their marketplace dashboards. ![dapps_2](https://user-images.githubusercontent.com/14581509/191753605-e1c48a57-0c3c-4509-808b-8fee4e7d32e8.png) -Using the `NFTStorefrontV2`, marketplaces can instantly and easily tap into the vibrant FLOW NFT ecosystem and allow NFT holders to list their NFTs and enables creator royalties. +With the `NFTStorefrontV2`, marketplaces can instantly and easily tap into the vibrant FLOW NFT ecosystem and allow NFT holders to list their NFTs and allows creator royalties. -Marketplaces then process an NFT trade by interacting directly with seller storefronts. Flow's account based model ensures that NFTs listed for sale always reside in the Seller account until traded, regardless of how many listings are posted across any number of marketplaces, for the same NFT. +Marketplaces then interact with seller storefronts directly to process an NFT trade. Flow's account based model ensures that NFTs listed for sale always reside in the Seller account until traded, regardless of how many Listings are posted across any number of marketplaces, for the same NFT. ![marketplace_1](https://user-images.githubusercontent.com/14581509/191755699-fe0570cb-80a3-408c-8eef-4051e3209481.png) -## Functional Overview +## Functional overview -A general purpose sale support contract for NFTs implementing the Flow [`NonFungibleToken`] standard. -Each account that wants to list NFTs for sale creates a `Storefront` resource to store in their account and lists individual sales within that Storefront as Listings. There is usually one Storefront per account held at the `/storage/NFTStorefrontV2`. +A general purpose sale support contract for NFTs that implement the Flow [`NonFungibleToken`] standard. Each account that wants to list NFTs for sale creates a `Storefront` resource to store in their account and lists individual sales within that Storefront as listings. There is usually one Storefront per account held at the `/storage/NFTStorefrontV2`. -Each listing can define one or more sale cuts taken out of the sale price to go to one or more addresses. Listing fees, royalties, or other considerations can be paid using sale cuts. Also, the listing can include a commission as one of these sale cuts is paid to whoever facilitates the purchase. +Each listing can define one or more sale cuts taken out of the sale price to go to one or more addresses. Listing fees, royalties, or other considerations can be paid with sale cuts. Also, the listing can include a commission as one of these sale cuts is paid to whoever facilitates the purchase. -Listings can have an optional list of marketplace [receiver capabilities] used to receive the commission for fulfilling the listing. An NFT may be listed in one or more Listings, and the validity of each listing can easily be checked. +Listings can have an optional list of marketplace [receiver capabilities] used to receive the commission after the seller fulfills the listing. An NFT may be listed in one or more listings, and the validity of each listing can easily be checked. -Interested parties can globally track Listing events on-chain and filter by NFT types, IDs and other characteristics to determine which to make available for purchase within their own marketplace UIs." +Interested parties can globally track listing events onchain and filter by NFT types, IDs and other characteristics to determine which to make available for purchase within their own marketplace UIs." -## Selling NFTs +## Sell NFTs `NFTStorefrontV2` offers a generic process for creating the listing for an NFT. It provides all the essential APIs to manage those listings independently. -Many marketplaces create a single storefront resource to manage different individual listings. We recommend creating the listing under the user-owned storefront resource to make it trustless and platform-independent. Users should possess the `Storefront` resource under their account to create the listing using the storefront contract. +Many marketplaces create a single storefront resource to manage different individual listings. We recommend that you create the listing under the user-owned storefront resource to make it trustless and platform-independent. Users should possess the `Storefront` resource under their account to create the listing using the storefront contract. -## Creating a successful listing using the NFTStorefrontV2 contract. +## Create a successful listing with the NFTStorefrontV2 contract. -As recommended above, the first step is to create and store the [Storefront resource] in the user account using the [setup_account] transaction. +As recommended above, the first step is to create and store the [Storefront resource] in the user account with the [setup_account] transaction. -The next step is to create a listing under the newly created storefront resource. If the user (repetitive) already holds the storefront resource, then use the existing resource. The seller can come with multiple requirements for listing their NFTs, and We try our best to cover most of them below. +The next step is to create a listing under the newly-created storefront resource. If the user (repetitive) already holds the storefront resource, then use the current resource. The seller can come with multiple requirements to list their NFTs, and we try our best to cover most of them below. -### **Scenario 1:** Selling NFTs corresponds to more than one cryptocurrency, i.e. FLOW, USDC etc. +### **Scenario 1:** Sell NFTs that correspond to more than one cryptocurrency, such as FLOW, USDC etc. -The `NFTStorefrontV2` contract doesn't support selling an NFT for multiple different currencies with a single listing. However, this can be achieved by creating multiple listings for the same NFT for each different currency. +The `NFTStorefrontV2` contract doesn't support an NFT sale for multiple different currencies with a single listing. However, to achieve this, you can create multiple listings for the same NFT for each different currency. -**Example -** Alice wants to sell a kitty and is open to receiving FLOW and USDC +**Example -** Alice wants to sell a kitty and is open to receive FLOW and USDC ![scenario_1](./scenario_1.png) -Putting an NFT on sell called listing, seller can create a listing using [sell_item] transaction by providing some required details to list an NFT, i.e. Receiving currency type, [Capability] from where NFT will be deducted etc. If interested look [`createListing`] for more details. +A seller puts an NFT on sale, a process called listing. To create a listing with the [sell_item] transaction, the seller provides some required details to list an NFT, such as the receiving currency type, and the [Capability] from where the network deducts the NFT. For more information, see [`createListing`]. -To receive a different currency seller has to provide a different **Receiver currency type** , i.e. `salePaymentVaultType` As depicted in the above diagram, There are two listing formations with almost the same inputs. The only differentiator is the `salePaymentVaultType` parameter that needs to be different when creating duplicate NFT listings with different sale currency types. +To receive a different currency, the seller must provide a different **Receiver currency type** , such as `salePaymentVaultType`. As depicted in the above diagram, there are two listing formations with almost the same inputs. The only differentiator is the `salePaymentVaultType` parameter that needs to be different when the seller creates duplicate NFT listings with different sale currency types. -### **Scenario 2:** Peer-to-Peer (p2p) listing of NFT: A listing anyone can fulfil. +### **Scenario 2:** Peer-to-Peer (p2p) listing of NFT: A listing anyone can fulfill. -Dapps can leverage the **NFTStorefrontV2** to facilitate the creation of a listing for the seller independent of any marketplace. Dapps or marketplaces can list those listings on their platforms, or seller can settle it p2p. +dApps can leverage the **NFTStorefrontV2** to facilitate a listing's creation for the seller independent of any marketplace. dApps or marketplaces can list those listings on their platforms, or seller can settle it p2p. -The seller can use [sell_item] transaction to create a p2p listing, providing the `marketplacesAddress` with an empty array. The seller has a choice of providing [commission] to the facilitator of sale, which can also act as a discount if the facilitator and the purchaser are the same. +The seller can use [sell_item] transaction to create a p2p listing. To do this, they provide the `marketplacesAddress` with an empty array. The seller can provide [commission] to the facilitator of sale, which can also act as a discount if the facilitator and the purchaser are the same. ### **Scenario 3:** The seller wants to list its NFT in different marketplaces. -`NFTStorefrontV2` offers two different ways of doing it. +`NFTStorefrontV2` offers two different ways to do it. -- The seller can create a listing and provide the `marketplacesAddress` that it wants to have a listing on using [sell_item] transaction. +- The seller can create a listing and provide the `marketplacesAddress` that it wants to have a listing on with the [sell_item] transaction. Marketplaces can listen to `ListingAvailable` events and check whether their address is included in the `commissionReceivers` list; If yes, the marketplace would be rewarded during the successful fulfilment of the listing. - Example - Bob wants to list on marketplace 0xA, 0xB & 0xC and is willing to offer 10% commission on the sale price of the listing to the marketplaces. + Example - Bob wants to list on marketplace 0xA, 0xB & 0xC and will offer 10% commission on the sale price of the listing to the marketplaces. ![scenario_3](https://user-images.githubusercontent.com/14581509/190966834-8eda4ec4-e9bf-49ef-9dec-3c47a236d281.png) -- Another way to accomplish this is to create separate listings for each marketplace on which a user wants their listing using [sell_item_with_marketplace_cut] transaction. In this case, the marketplace would be incentivized by earning one of the parts of the [`saleCut`] by appending marketplace saleCut in `saleCuts` array during the creation of the listing. +- Another way to accomplish this is to create separate listings for each marketplace on which a user wants their listing with the [sell_item_with_marketplace_cut] transaction. In this case, the marketplace would earn one part of the [`saleCut`] as an incentive. It appends the marketplace saleCut in the `saleCuts` array when it creates the listing. ### Considerations 1. **Ghost listings -** _Ghost listings are listings which don't have an underlying NFT in the seller's account. However, the listing is still available for buyers to attempt to purchase_. StorefrontV2 is not immune to ghost listings. Usually, ghost listings will cause a purchaser's transaction to fail, which is annoying but isn't a significant problem. Ghost listings become a problem for the seller when the listed NFT comes back to the seller's account after its original sale. The ghost listing will no longer be invalid when it comes back, and anyone can purchase it even if the seller doesn't want to sell it at that price anymore. - **Note -** _We recommend that marketplaces and p2p dApps create an off-chain notification service that tells their users (i.e., sellers) to remove the listings if they don't hold the NFT anymore in the same account._ +:::info + +_We recommend that marketplaces and p2p dApps create an off-chain notification service that tells their users (sellers) to remove the listings if they don't hold the NFT anymore in the same account._ + +::: 2. **Expired listings -** `NFTStorefrontV2` introduces a safety measure to specify that a listing will expire after a certain period that can be set during the creation so no one can purchase the listing anymore. It is not a fool-proof safety measure, but it does give some safe ground to the sellers for the ghost listings & stale listings. - **Note -** _We recommended for marketplaces and p2p dApps not to show the expired listings on their dashboards._ +:::info + + _We recommended for marketplaces and p2p dApps not to show the expired listings on their dashboards._ + + ::: -## Purchasing NFTs +## Purchase NFTs -Purchasing NFTs through the `NFTStorefrontV2` is simple. The buyer has to provide the payment vault and the `commissionRecipient` , if applicable, during the purchase. p2p dApps don't need any intermediaries to facilitate the purchase of listings. [`purchase`] API offered by the `Listing` resource gets used to facilitate the purchase of NFT. +To purchase NFTs through the `NFTStorefrontV2` is simple. The buyer has to provide the payment vault and the `commissionRecipient` , if applicable, during the purchase. p2p dApps don't need any intermediaries to facilitate the purchase of listings. [`purchase`] API offered by the `Listing` resource gets used to facilitate the purchase of NFT. -During the listing purchase all saleCuts are paid automatically. This also includes distributing royalties for that NFT, if applicable. If the vault provided by the buyer lacks sufficient funds then the transaction will fail. +During the listing purchase, all saleCuts are paid automatically. This also includes royalty distribution for that NFT, if applicable. If the vault provided by the buyer lacks sufficient funds, then the transaction will fail. ### Considerations -1. **Auto cleanup -** `NFTStorefrontV2` offers a unique ability to do auto cleanup of duplicate listings during a purchase. It comes with a drawback if one NFT has thousands of duplicate listings. It will become the bottleneck during purchasing one of the listings as it will likely trigger an out-of-gas error. +1. **Auto cleanup -** `NFTStorefrontV2` offers a unique ability to do auto cleanup of duplicate listings during a purchase. It comes with a drawback if one NFT has thousands of duplicate listings. It will become the bottleneck during purchases one of the listings as it will likely trigger an out-of-compute error. + +:::info - **Note -** _We recommended NOT to have more than 50 (TBD) duplicate listings of any given NFT._ + _We recommended NOT to have more than 50 duplicate listings of any given NFT._ -2. **Unsupported receiver capability** - A common pitfall during the purchase of an NFT that some saleCut receivers don't have a supported receiver capability because that entitled sale cut would transfer to first valid sale cut receiver. However, it can be partially solved by providing the generic receiver using the [`FungibleTokenSwitchboard`] contract and adding all the currency capabilities the beneficiary wants to receive. More on the `FungibleTokenSwitchboard` can be read in [Fungible Token Switchboard] +::: -## Enabling creator royalties for NFTs +2. **Unsupported receiver capability** - A common pitfall during the purchase of an NFT that some saleCut receivers don't have a supported receiver capability because that entitled sale cut would transfer to first valid sale cut receiver. However, it can be partially solved if you provide the generic receiver with the [`FungibleTokenSwitchboard`] contract and add all the currency capabilities the beneficiary wants to receive. For more information about the `FungibleTokenSwitchboard`, see [Fungible Token Switchboard] -The `NFTStorefrontV2` contract optionally supports paying royalties to the minter account for secondary resales of that NFT after the original sale. Marketplaces decide for themselves whether to support creator royalties when validating listings for sale eligibility. We encourage all marketplaces to support creator royalties and support community creators in the **FLOW** ecosystem. +## Allow creator royalties for NFTs -Providing that a seller's NFT supports the [Royalty Metadata View] standard, then marketplaces can honor royalties payments at time of purchase. `NFTStorefrontV2` dynamically calculates the royalties owed at the time of listing creation and applies it as a saleCut of the listing at the time of purchase. +The `NFTStorefrontV2` contract optionally supports royalty payments to the minter account for secondary resales of that NFT after the original sale. Marketplaces decide for themselves whether to support creator royalties when they validate listings for sale eligibility. We encourage all marketplaces to support creator royalties and support community creators in the **FLOW** ecosystem. + +If a seller's NFT supports the [Royalty Metadata View] standard, then marketplaces can honor royalties payments at time of purchase. `NFTStorefrontV2` dynamically calculates the royalties owed at the time of listing creation and applies it as a saleCut of the listing at the time of purchase. ```cadence // Check whether the NFT implements the MetadataResolver or not. @@ -166,19 +176,19 @@ if nft.getViews().contains(Type()) { } ``` -Complete transaction can be viewed in [sell_item]. +You can view a complete transaction in [sell_item]. -saleCut only supports a single token receiver type and therefore beneficiaries of a `saleCut` can also only receive the token type used for the purchase. To support different token types for saleCuts we recommend using the [`FungibleTokenSwitchboard`] contract. The contract defines a generic receiver for fungible tokens which itself handles routing of tokens to the respective vault for that token type. Learn more about this in [Fungible Token Switchboard]. +saleCut only supports a single token receiver type and therefore beneficiaries of a `saleCut` can also only receive the token type used for the purchase. To support different token types for saleCuts, we recommend that you use the [`FungibleTokenSwitchboard`] contract. The contract defines a generic receiver for fungible tokens which itself handles routing of tokens to the respective vault for that token type. You can learn more about this in [Fungible Token Switchboard]. -## Enabling marketplace commissions for NFT sales +## Allow marketplace commissions for NFT sales -`NFTStorefrontV2` enables optional commissions on trades for marketplaces which require it as a condition to list a NFT for sale. Commission & commission receivers are set by the seller during initial listing creation. At time of purchase the commission amount is paid once only to the commission receiver matching the marketplace receiver address which facilitated the sale. +`NFTStorefrontV2` allows optional commissions on trades for marketplaces which require it as a condition to list a NFT for sale. The seller sets commission and commission receivers during initial listing creation. At time of purchase, the commission amount is paid once only to the commission receiver that matches the marketplace receiver address which facilitated the sale. -For NFT listings in marketplaces which don't require commission, commission receivers can be set as nil. Setting the buyer of the NFT and `commissionRecipient` to the same has the effect of applying a discount for the buyer. +For NFT listings in marketplaces which don't require commission, you can set commission receivers as `nil`. If you set the buyer of the NFT and `commissionRecipient` to `nil`, it applies a discount for the buyer. ![scenario_2](https://user-images.githubusercontent.com/14581509/190966499-c176203f-b6a6-4422-860f-1bf6f2bcdbb6.png). -## APIs & Events offered by NFTStorefrontV2 +## APIs and events offered by NFTStorefrontV2 ## Resource Interface `ListingPublic` @@ -194,7 +204,7 @@ resource interface ListingPublic { } ``` -An interface providing a useful public interface to a Listing. +An interface that provides a useful public interface to a Listing. ### Functions @@ -204,8 +214,7 @@ An interface providing a useful public interface to a Listing. fun borrowNFT(): &NonFungibleToken.NFT? ``` -This will assert in the same way as the NFT standard borrowNFT() -if the NFT is absent, for example if it has been sold via another listing. +This will assert in the same way as the NFT standard borrowNFT() if the NFT is absent, for example if it has been sold via another listing. --- @@ -215,9 +224,7 @@ if the NFT is absent, for example if it has been sold via another listing. fun purchase(payment FungibleToken.Vault, commissionRecipient Capability<&{FungibleToken.Receiver}>?): NonFungibleToken.NFT ``` -Facilitates the purchase of the listing by providing the payment vault -and the commission recipient capability if there is a non-zero commission for the given listing. -Respective saleCuts are transferred to beneficiaries and funtion return underlying or listed NFT. +Facilitates the purchase of the listing by providing the payment vault and the commission recipient capability if there is a non-zero commission for the given listing. Respective saleCuts are transferred to beneficiaries and funtion return underlying or listed NFT. --- @@ -227,7 +234,7 @@ Respective saleCuts are transferred to beneficiaries and funtion return underlyi fun getDetails(): ListingDetails ``` -Fetches the details of the listings +Fetches the details of the listings. --- @@ -237,8 +244,7 @@ Fetches the details of the listings fun getAllowedCommissionReceivers(): [Capability<&{FungibleToken.Receiver}>]? ``` -Fetches the allowed marketplaces capabilities or commission receivers for the underlying listing. -If it returns `nil` then commission is up to grab by anyone. +Fetches the allowed marketplaces capabilities or commission receivers for the underlying listing. If it returns `nil`, then commission is up for grabs by anyone. --- @@ -265,8 +271,7 @@ resource Storefront { } ``` -A resource that allows its owner to manage a list of Listings, and anyone to interact with them -in order to query their details and purchase the NFTs that they represent. +A resource that allows its owner to manage a set of listings, and anyone to interact with them in order to query their details and purchase the NFTs that they represent. Implemented Interfaces: @@ -288,7 +293,7 @@ fun createListing(nftProviderCapability Capability<&{NonFungibleToken.Provider, ``` insert -Create and publish a Listing for an NFT. +Create and publish a listing for an NFT. --- @@ -299,7 +304,7 @@ fun removeListing(listingResourceID UInt64) ``` removeListing -Remove a Listing that has not yet been purchased from the collection and destroy it. +Remove a listing that has not yet been purchased from the collection and destroy it. --- @@ -310,7 +315,7 @@ fun getListingIDs(): [UInt64] ``` getListingIDs -Returns an array of the Listing resource IDs that are in the collection +Returns an array of the listing resource IDs that are in the collection. --- @@ -332,7 +337,7 @@ fun cleanupExpiredListings(fromIndex UInt64, toIndex UInt64) ``` cleanupExpiredListings -Cleanup the expired listing by iterating over the provided range of indexes. +Iterate over the provided range of indexes to clean up the expired listings. --- @@ -361,8 +366,7 @@ resource interface StorefrontPublic { ``` StorefrontPublic -An interface to allow listing and borrowing Listings, and purchasing items via Listings -in a Storefront. +An interface to allow listing and borrowing listings, and purchase items via listings in a Storefront. ### Functions @@ -372,7 +376,8 @@ in a Storefront. fun getListingIDs(): [UInt64] ``` -getListingIDs Returns an array of the Listing resource IDs that are in the collection +getListingIDs +Returns an array of the listing resource IDs that are in the collection --- @@ -382,7 +387,8 @@ getListingIDs Returns an array of the Listing resource IDs that are in the colle fun getDuplicateListingIDs(nftType Type, nftID UInt64, listingID UInt64): [UInt64] ``` -getDuplicateListingIDs Returns an array of listing IDs that are duplicates of the given nftType and nftID. +getDuplicateListingIDs +Returns an array of listing IDs that are duplicates of the given nftType and nftID. --- @@ -392,7 +398,8 @@ getDuplicateListingIDs Returns an array of listing IDs that are duplicates of th fun borrowListing(listingResourceID UInt64): &Listing{ListingPublic}? ``` -borrowListing Returns a read-only view of the listing for the given listingID if it is contained by this collection. +borrowListing +Returns a read-only view of the listing for the given listingID if it is contained by this collection. --- @@ -402,7 +409,8 @@ borrowListing Returns a read-only view of the listing for the given listingID if fun cleanupExpiredListings(fromIndex UInt64, toIndex UInt64) ``` -cleanupExpiredListings Cleanup the expired listing by iterating over the provided range of indexes. +cleanupExpiredListings + Iterates over the provided range of indexes to clean up the expired listing. --- @@ -436,9 +444,7 @@ Returns an array of listing IDs of the given `nftType` and `nftID`. event StorefrontInitialized(storefrontResourceID: UInt64) ``` -A Storefront resource has been created. Consumers can now expect events from this Storefront. Note that we do not specify an address: we cannot and should not. Created resources do not have an owner address, and may be moved -after creation in ways we cannot check. `ListingAvailable` events can be used to determine the address -of the owner of the Storefront at the time of the listing but only at that precise moment in that precise transaction. If the seller moves the Storefront while the listing is valid, that is on them. +A Storefront resource was created. Consumers can now expect events from this Storefront. We do not specify an address: we cannot and should not. Created resources do not have an owner address, and may be moved after creation in ways we cannot check. `ListingAvailable` events can be used to determine the address of the owner of the Storefront at the time of the listing but only at that precise moment in that precise transaction. If the seller moves the Storefront while the listing is valid, that is on them. --- @@ -448,8 +454,7 @@ of the owner of the Storefront at the time of the listing but only at that preci event StorefrontDestroyed(storefrontResourceID: UInt64) ``` -A Storefront has been destroyed. Event consumers can now stop processing events from this Storefront. -Note - we do not specify an address. +A Storefront has been destroyed. Event consumers can now stop processing events from this Storefront. We do not specify an address. --- @@ -459,8 +464,7 @@ Note - we do not specify an address. event ListingAvailable(storefrontAddress: Address, listingResourceID: UInt64, nftType: Type, nftUUID: UInt64, nftID: UInt64, salePaymentVaultType: Type, salePrice: UFix64, customID: String?, commissionAmount: UFix64, commissionReceivers: [Address]?, expiry: UInt64) ``` -Above event gets emitted when a listing has been created and added to a Storefront resource. The Address values here are valid when the event is emitted, but the state of the accounts they refer to may change outside of the -`NFTStorefrontV2` workflow, so be careful to check when using them. +Above event gets emitted when a listing is created and added to a Storefront resource. The Address values here are valid when the event is emitted, but the state of the accounts they refer to may change outside of the `NFTStorefrontV2` workflow, so be careful to check when you use them. --- @@ -470,7 +474,7 @@ Above event gets emitted when a listing has been created and added to a Storefro event ListingCompleted(listingResourceID: UInt64, storefrontResourceID: UInt64, purchased: Bool, nftType: Type, nftUUID: UInt64, nftID: UInt64, salePaymentVaultType: Type, salePrice: UFix64, customID: String?, commissionAmount: UFix64, commissionReceiver: Address?, expiry: UInt64) ``` -The listing has been resolved. It has either been purchased, removed or destroyed. +The listing was resolved. It was either purchased, removed or destroyed. --- @@ -480,7 +484,7 @@ The listing has been resolved. It has either been purchased, removed or destroye event UnpaidReceiver(receiver: Address, entitledSaleCut: UFix64) ``` -A entitled receiver has not been paid during the sale of the NFT. +A entitled receiver wasn't paid during the sale of the NFT. --- @@ -505,4 +509,4 @@ A entitled receiver has not been paid during the sale of the NFT. [`saleCut`]: https://github.com/onflow/nft-storefront/blob/160e97aa802405ad26a3164bcaff0fde7ee52ad2/contracts/NFTStorefrontV2.cdc#L104 [`purchase`]: #fun-purchase [`FungibleTokenSwitchboard`]: https://github.com/onflow/flow-ft/blob/master/contracts/FungibleTokenSwitchboard.cdc -[Royalty Metadata View]: https://github.com/onflow/flow-nft/blob/21c254438910c8a4b5843beda3df20e4e2559625/contracts/MetadataViews.cdc#L335 \ No newline at end of file +[Royalty Metadata View]: https://github.com/onflow/flow-nft/blob/21c254438910c8a4b5843beda3df20e4e2559625/contracts/MetadataViews.cdc#L335 diff --git a/docs/build/cadence/core-contracts/11-staking-collection.md b/docs/build/cadence/core-contracts/11-staking-collection.md new file mode 100644 index 0000000000..f149c5a5af --- /dev/null +++ b/docs/build/cadence/core-contracts/11-staking-collection.md @@ -0,0 +1,132 @@ +--- +title: Flow Staking Collection Contract Reference +sidebar_position: 11 +sidebar_label: Staking Collection +description: Learn about Flow's Staking Collection contract that manages user stake and delegation resources. Understand how to interact with nodes, delegators, and locked tokens through the collection interface. +keywords: + - staking collection + - Flow staking + - node management + - delegation + - locked tokens + - machine accounts + - staking operations + - node registration + - delegator registration + - stake management + - token delegation + - staking interface + - Flow protocol + - staking transactions + - collection events +--- + +# Flow Staking Collection Contract Reference + +The `FlowStakingCollection` contract is a contract that manages a resource which contain a user's stake and delegation objects. + +The `FlowStakingCollection` allows a user to manage multiple active nodes or delegators and interact with node or delegator objects stored in either their optional locked account or in the StakingCollection itself (stored in the main account). If a user has locked tokens, StakingCollection allows a user to interact with their locked tokens to perform staking actions for any of their nodes or delegators. + +The staking collection also manages a node's machine accounts creation process if they have any collector or consensus nodes. It also allows them to deposit and withdraw tokens from any of their machine accounts through the staking collection. + +See the [Staking Collection Docs] for more information on the design of the staking collection contract. + +Source: [FlowStakingCollection.cdc] + +| Network | Contract Address | +| ------------------------- | -------------------- | +| Emulator | `0xf8d6e0586b0a20c7` | +| Cadence Testing Framework | `0x0000000000000001` | +| Testnet | `0x95e019a17d0e23d7` | +| Mainnet | `0x8d0e87b65159ae63` | + +## Transactions + +Use the following transactions to interact with the StakingCollection. + +:::info + +The StakingCollection differentiates between stake and delegation requests through passing an optional DelegatorID argument. For example, if you wish to Stake New Tokens for an active node, pass `nil` as the optional DelegatorID argument to the Stake New Tokens transaction. The same applies for all the other staking operation transactions. + +::: + +| ID | Name | Source | +| ------------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **`SCO.01`** | Setup Staking Collection | [stakingCollection/setup_staking_collection.cdc] | +| **`SCO.02`** | Register Delegator | [stakingCollection/register_delegator.cdc] | +| **`SCO.03`** | Register Node | [stakingCollection/register_node.cdc] | +| **`SCO.04`** | Create Machine Account | [stakingCollection/create_machine_account.cdc] | +| **`SCO.05`** | Request Unstaking | [stakingCollection/request_unstaking.cdc] | +| **`SCO.06`** | Stake New Tokens | [stakingCollection/stake_new_tokens.cdc] | +| **`SCO.07`** | Stake Rewarded Tokens | [stakingCollection/stake_rewarded_tokens.cdc] | +| **`SCO.08`** | Stake Unstaked Tokens | [stakingCollection/stake_unstaked_tokens.cdc] | +| **`SCO.09`** | Unstake All | [stakingCollection/unstake_all.cdc] | +| **`SCO.10`** | Withdraw Rewarded Tokens | [stakingCollection/withdraw_rewarded_tokens.cdc] | +| **`SCO.11`** | Withdraw Unstaked Tokens | [stakingCollection/withdraw_unstaked_tokens.cdc] | +| **`SCO.12`** | Close Stake | [stakingCollection/close_stake.cdc] | +| **`SCO.13`** | Transfer Node | [stakingCollection/transfer_node.cdc] | +| **`SCO.14`** | Transfer Delegator | [stakingCollection/transfer_delegator.cdc] | +| **`SCO.15`** | Withdraw From Machine Account | [stakingCollection/withdraw_from_machine_account.cdc] | +| **`SCO.22`** | Update Networking Address | [stakingCollection/update_networking_address.cdc] | + +## Scripts + +| ID | Name | Source | +| ------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **`SCO.16`** | Get All Delegator Info | [stakingCollection/scripts/get_all_delegator_info.cdc] | +| **`SCO.15`** | Get All Node Info | [stakingCollection/scripts/get_all_node_info.cdc] | +| **`SCO.22`** | Get Delegator Ids | [stakingCollection/scripts/get_delegator_ids.cdc] | +| **`SCO.17`** | Get Node Ids | [stakingCollection/scripts/get_node_ids.cdc] | +| **`SCO.18`** | Get Does Stake Exist | [stakingCollection/scripts/get_does_stake_exist.cdc] | +| **`SCO.19`** | Get Locked Tokens Used | [stakingCollection/scripts/get_locked_tokens_used.cdc] | +| **`SCO.20`** | Get Unlocked Tokens Used | [stakingCollection/scripts/get_unlocked_tokens_used.cdc] | +| **`SCO.21`** | Get Machine Accounts | [stakingCollection/scripts/get_machine_accounts.cdc] | + +## Setup Transaction + +To setup the Staking Collection for an account, use the `SC.01` transaction. + +The setup process finds any node or delegator records already stored in the main account's storage, as well as any in the associated locked account if an associated locked account exists. It connects these node and delegator records with the new Staking Collection, and you ue the Staking Collection API to interact with them. + +## Events + +The `StakingCollection` contract emits an event whenever an important action occurs. + +```cadence + access(all) event NodeAddedToStakingCollection(nodeID: String, role: UInt8, amountCommitted: UFix64, address: Address?) + access(all) event DelegatorAddedToStakingCollection(nodeID: String, delegatorID: UInt32, amountCommitted: UFix64, address: Address?) + + access(all) event NodeRemovedFromStakingCollection(nodeID: String, role: UInt8, address: Address?) + access(all) event DelegatorRemovedFromStakingCollection(nodeID: String, delegatorID: UInt32, address: Address?) + + access(all) event MachineAccountCreated(nodeID: String, role: UInt8, address: Address) +``` + + + +[Staking Collection Docs]: ../../../protocol/staking/14-staking-collection.md +[FlowStakingCollection.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowStakingCollection.cdc +[stakingCollection/setup_staking_collection.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/setup_staking_collection.cdc +[stakingCollection/register_delegator.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/register_delegator.cdc +[stakingCollection/register_node.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/register_node.cdc +[stakingCollection/request_unstaking.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/request_unstaking.cdc +[stakingCollection/stake_new_tokens.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/stake_new_tokens.cdc +[stakingCollection/stake_rewarded_tokens.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/stake_rewarded_tokens.cdc +[stakingCollection/stake_unstaked_tokens.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/stake_unstaked_tokens.cdc +[stakingCollection/unstake_all.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/unstake_all.cdc +[stakingCollection/withdraw_rewarded_tokens.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/withdraw_rewarded_tokens.cdc +[stakingCollection/withdraw_unstaked_tokens.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/withdraw_unstaked_tokens.cdc +[stakingCollection/close_stake.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/close_stake.cdc +[stakingCollection/transfer_node.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/transfer_node.cdc +[stakingCollection/transfer_delegator.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/transfer_delegator.cdc +[stakingCollection/withdraw_from_machine_account.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/withdraw_from_machine_account.cdc +[stakingCollection/update_networking_address.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/update_networking_address.cdc +[stakingCollection/scripts/get_all_delegator_info.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_all_delegator_info.cdc +[stakingCollection/scripts/get_all_node_info.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_all_node_info.cdc +[stakingCollection/scripts/get_delegator_ids.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_delegator_ids.cdc +[stakingCollection/scripts/get_node_ids.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_node_ids.cdc +[stakingCollection/scripts/get_does_stake_exist.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_does_stake_exist.cdc +[stakingCollection/scripts/get_locked_tokens_used.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_locked_tokens_used.cdc +[stakingCollection/scripts/get_unlocked_tokens_used.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_unlocked_tokens_used.cdc +[stakingCollection/scripts/get_machine_accounts.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_machine_accounts.cdc +[stakingCollection/create_machine_account.cdc]: https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/create_machine_account.cdc \ No newline at end of file diff --git a/docs/build/core-contracts/12-hybrid-custody.md b/docs/build/cadence/core-contracts/12-hybrid-custody.md similarity index 70% rename from docs/build/core-contracts/12-hybrid-custody.md rename to docs/build/cadence/core-contracts/12-hybrid-custody.md index bbafe362ab..49ae7fca38 100644 --- a/docs/build/core-contracts/12-hybrid-custody.md +++ b/docs/build/cadence/core-contracts/12-hybrid-custody.md @@ -21,13 +21,19 @@ keywords: - custody model --- -# Contract +# Flow Account Linking Contract Address The Account Linking contracts manage ChildAccounts to permit hybrid custody in scenarios where apps only want to share a subset of resources on their accounts with various parents. In many cases, this will be a user's primary wallet outside of the application a child account came from. -You can see the docs for account linking [here](https://developers.flow.com/build/advanced-concepts/account-linking) +You can see the docs for account linking [here] | Network | Contract Address | | ------- | ------------------------------------------------------------------------------ | -| Testnet | [`0x294e44e1ec6993c6`](https://contractbrowser.com/account/0x294e44e1ec6993c6) | -| Mainnet | [`0xd8a7e05a7ac670c0`](https://contractbrowser.com/account/0xd8a7e05a7ac670c0) | +| Testnet | [`0x294e44e1ec6993c6`] | +| Mainnet | [`0xd8a7e05a7ac670c0`] | + + + +[here]: https://developers.flow.com/build/cadence/advanced-concepts/account-linking +[`0x294e44e1ec6993c6`]: https://contractbrowser.com/account/0x294e44e1ec6993c6 +[`0xd8a7e05a7ac670c0`]: https://contractbrowser.com/account/0xd8a7e05a7ac670c0 \ No newline at end of file diff --git a/docs/build/core-contracts/13-evm.md b/docs/build/cadence/core-contracts/13-evm.md similarity index 55% rename from docs/build/core-contracts/13-evm.md rename to docs/build/cadence/core-contracts/13-evm.md index da008707d0..d6465fabde 100644 --- a/docs/build/core-contracts/13-evm.md +++ b/docs/build/cadence/core-contracts/13-evm.md @@ -21,21 +21,25 @@ keywords: - FLIP 223 --- -# Contract +# Flow EVM -The `EVM` contract is the entrypoint from Cadence to Flow EVM. While many developers may choose to interact with EVM -via [EVM-equivalent tooling paths](../../evm/using.mdx), all access to Flow EVM ultimately interfaces via Cadence at -some level. +The `EVM` contract is the entrypoint from Cadence to Flow EVM. While many developers may choose to interact with EVM via [EVM-equivalent tooling paths], all access to Flow EVM ultimately interfaces via Cadence at some level. -If you would like to interact with EVM directly from Cadence, you can use the `EVM` contract and it's constructs. Read -more about the EVM contract and its role in Flow's EVM equivalence in [FLIP -#223](https://github.com/onflow/flips/blob/main/protocol/20231116-evm-support.md). +If you would like to interact with EVM directly from Cadence, you can use the `EVM` contract and it's constructs. Read more about the EVM contract and its role in Flow's EVM equivalence in [FLIP #223]. -Mainnet/Testnet Source: [`EVM.cdc`](https://github.com/onflow/flow-go/blob/master/fvm/evm/stdlib/contract.cdc) +Mainnet/Testnet Source: [`EVM.cdc`] | Network | Contract Address | | ------------------------- | -------------------------------------------------------------------------- | | Emulator | `0xf8d6e0586b0a20c7` | | Cadence Testing Framework | `0x0000000000000001` | -| Testnet | [`0x8c5303eaa26202d6`](https://contractbrowser.com/A.8c5303eaa26202d6.EVM) | -| Mainnet | [`0xe467b9dd11fa00df`](https://contractbrowser.com/A.e467b9dd11fa00df.EVM) | +| Testnet | [`0x8c5303eaa26202d6`] | +| Mainnet | [`0xe467b9dd11fa00df`] | + + + +[EVM-equivalent tooling paths]: ../../../build/evm/using.mdx +[FLIP #223]: https://github.com/onflow/flips/blob/main/protocol/20231116-evm-support.md +[`EVM.cdc`]: https://github.com/onflow/flow-go/blob/master/fvm/evm/stdlib/contract.cdc +[`0x8c5303eaa26202d6`]: https://contractbrowser.com/A.8c5303eaa26202d6.EVM +[`0xe467b9dd11fa00df`]: https://contractbrowser.com/A.e467b9dd11fa00df.EVM \ No newline at end of file diff --git a/docs/build/core-contracts/14-burner.md b/docs/build/cadence/core-contracts/14-burner.md similarity index 55% rename from docs/build/core-contracts/14-burner.md rename to docs/build/cadence/core-contracts/14-burner.md index 585fe57f2f..0936727e24 100644 --- a/docs/build/core-contracts/14-burner.md +++ b/docs/build/cadence/core-contracts/14-burner.md @@ -21,20 +21,21 @@ keywords: - burn operations --- -# Contract +# Flow Burner Contract Address -The [Burner](https://github.com/onflow/flow-ft/blob/master/contracts/utility/Burner.cdc) contract provides a way for resources to define -custom logic that is executed when the resource is destroyed. -Resources that want to utilize this functionality should implement -the `Burner.Burnable` interface which requires that they include -a `burnCallback()` function that includes the custom logic. +The [Burner](https://github.com/onflow/flow-ft/blob/master/contracts/utility/Burner.cdc) contract provides a way for resources to define custom logic that is executed when the resource is destroyed. Resources that want to use this functionality should implement the `Burner.Burnable` interface which requires that they include a `burnCallback()` function that includes the custom logic. -It is recommended that regardless of the resource, all users and developers -should use `Burner.burn()` when destroying a resource instead of `destroy`. +We recommend that, regardless of the resource, all users and developers should use `Burner.burn()` when they destroy a resource instead of `destroy`. | Network | Contract Address | | ------- | ------------------------------------------------------------------------------ | | Cadence Testing Framework | `0x0000000000000001` | | Emulator | `0xee82856bf20e2aa6` | -| Testnet | [`0x294e44e1ec6993c6`](https://contractbrowser.com/account/0x294e44e1ec6993c6) | -| Mainnet | [`0xd8a7e05a7ac670c0`](https://contractbrowser.com/account/0xd8a7e05a7ac670c0) | \ No newline at end of file +| Testnet | [`0x294e44e1ec6993c6`] | +| Mainnet | [`0xd8a7e05a7ac670c0`] | + + + +[Burner]: https://github.com/onflow/flow-ft/blob/master/contracts/utility/Burner.cdc +[`0x294e44e1ec6993c6`]: https://contractbrowser.com/account/0x294e44e1ec6993c6 +[`0xd8a7e05a7ac670c0`]: https://contractbrowser.com/account/0xd8a7e05a7ac670c0 \ No newline at end of file diff --git a/docs/build/cadence/core-contracts/15-bridge.md b/docs/build/cadence/core-contracts/15-bridge.md new file mode 100644 index 0000000000..482f6a7932 --- /dev/null +++ b/docs/build/cadence/core-contracts/15-bridge.md @@ -0,0 +1,95 @@ +--- +title: VM Bridge Contracts +sidebar_position: 15 +sidebar_label: VM Bridge +description: Learn about Flow's bridge contracts that manage bridging tokens between the Cadence and EVM environments. +keywords: + - core contracts + - transaction fees + - EVM + - bridge + - fungible tokens + - non fungible tokens + - nft +--- + +# VM Bridge Contracts + +The Flow VM bridge is the account and series of smart contracts that manage how assets are safely bridged between the Cadence and EVM Flow Environments. + +| Network | Contract Address | +| ------------------------- | -------------------- | +| Emulator | `0xf8d6e0586b0a20c7` | +| Cadence Testing Framework | `0x0000000000000001` | +| Testnet | `0xdfc20aee650fcbdf` | +| Mainnet | `0x1e4aa0b87d10b141` | + +# Contracts + +There are many important contracts deployed to the bridge account. You should refer to [the bridge repo] and [the bridge guides] for more detailed information about the bridge and tutorials for how to use the bridge properly. + +Here is a list of each Cadence contract used for the bridge: + +| Contract | Purpose | +| ------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| `CrossVMNFT` | Contract that defines cross-VM NFT-related interfaces. | +| `CrossVMToken` | Contract that defines cross-VM Fungible Token Vault interfaces. | +| `FlowEVMBridgeHandlerInterfaces` | Defines interface for custom bridged token handlers. | +| `IBridgePermissions` | Defines an interface to prevent bridging for a specific token. | +| `ICrossVM` | Defines an interface to get EVM contract addresses. | +| `ICrossVMAsset` | Defines an interface to represent a Cadence bridged version of an EVM asset. | +| `IEVMBridgeNFTMinter` | Defines an interface that allows the bridge to mint NFTs. | +| `IEVMBridgeTokenMinter` | Defines an interface that allows the bridge to mint FTs. | +| `IFlowEVMNFTBridge` | Defines core methods for bridging NFTs. | +| `IFlowEVMTokenBridge` | Defines core methods for bridging FTs. | +| `FlowEVMBridge` | The main entrypoint for briding tokens across Flow VMs. | +| `FlowEVMBridgeAccessor` | Defines methods to route bridge requests from the EVM contract to the Flow-EVM bridge contract. | +| `FlowEVMBridgeConfig` | Used to store configuration options for the VM Bridge. | +| `FlowEVMBridgeCustomAssociations` | Stores configuration information about custom bridged asset configurations. | +| `FlowEVMBridgeCustomAssociationTypes` | Defines interfaces used to specify custom bridged asset associations. | +| `FlowEVMBridgeHandlers` | Defines mechanisms to handle assets with custom associations (Deprecated). | +| `FlowEVMBridgeNFTEscrow` | Handles locking of NFTs that are bridged from Flow to EVM and back. | +| `FlowEVMBridgeResolver` | Defines methods to resolve Metadata Views for bridged assets. | +| `FlowEVMBridgeTemplates` | Serves Cadence code from chunked templates for bridge-deployed assets. | +| `FlowEVMBridgeTokenEscrow` | Handles locking of FTs that are bridged from Flow to EVM and back. | +| `FlowEVMBridgeUtils` | Defines many different utility methods that are used by bridge contracts. | +| `ArrayUtils` | Provides useful utility functions for array manipulation. | +| `ScopedFTProviders` | Provides utilities to create provider capabilities for tokens that are restricted to a specific amount. | +| `Serialize` | Provides utilities to serialize common types to JSON compatible strings. | +| `SerializeMetadata` | Provides methods to serialize NFT metadata as a JSON compatible string. | +| `StringUtils` | Provides useful utility functions for string manipulation. | + +# EVM bridge Solidity contracts + +There are also Solidity contracts that are deployed in Flow EVM that are needed for the bridge. +Here are their addresses: + +| Contracts | Testnet | Mainnet | +| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `FlowEVMBridgeFactory.sol` | [`0xf8146b4aef631853f0eb98dbe28706d029e52c52`] | [`0x1c6dea788ee774cf15bcd3d7a07ede892ef0be40`] | +| `FlowEVMBridgeDeploymentRegistry.sol` | [`0x8781d15904d7e161f421400571dea24cc0db6938`] | [`0x8fdec2058535a2cb25c2f8cec65e8e0d0691f7b0`] | +| `FlowEVMBridgedERC20Deployer.sol` | [`0x4d45CaD104A71D19991DE3489ddC5C7B284cf263`] | [`0x49631Eac7e67c417D036a4d114AD9359c93491e7`] | +| `FlowEVMBridgedERC721Deployer.sol` | [`0x1B852d242F9c4C4E9Bb91115276f659D1D1f7c56`] | [`0xe7c2B80a9de81340AE375B3a53940E9aeEAd79Df`] | + +And below are the bridge escrow's EVM addresses. These addresses are [`CadenceOwnedAccount`s (COA)] and they are stored in the same Flow account as you'll find the Cadence contracts (see above). + +| Network | Address | +| ------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| Testnet | [`0x0000000000000000000000023f946ffbc8829bfd`] | +| Mainnet | [`0x00000000000000000000000249250a5c27ecab3b`] | + + + +[the bridge repo]: https://github.com/onflow/flow-evm-bridge +[the bridge guides]: ../../../blockchain-development-tutorials/cross-vm-apps/vm-bridge.md +[`0xf8146b4aef631853f0eb98dbe28706d029e52c52`]: https://evm-testnet.flowscan.io/address/0xF8146B4aEF631853F0eB98DBE28706d029e52c52 +[`0x1c6dea788ee774cf15bcd3d7a07ede892ef0be40`]: https://evm.flowscan.io/address/0x1C6dEa788Ee774CF15bCd3d7A07ede892ef0bE40 +[`0x8781d15904d7e161f421400571dea24cc0db6938`]: https://evm-testnet.flowscan.io/address/0x8781d15904d7e161f421400571dea24cc0db6938 +[`0x8fdec2058535a2cb25c2f8cec65e8e0d0691f7b0`]: https://evm.flowscan.io/address/0x8FDEc2058535A2Cb25C2f8ceC65e8e0D0691f7B0 +[`0x4d45CaD104A71D19991DE3489ddC5C7B284cf263`]: https://evm-testnet.flowscan.io/address/0x4d45CaD104A71D19991DE3489ddC5C7B284cf263 +[`0x49631Eac7e67c417D036a4d114AD9359c93491e7`]: https://evm.flowscan.io/address/0x49631Eac7e67c417D036a4d114AD9359c93491e7 +[`0x1B852d242F9c4C4E9Bb91115276f659D1D1f7c56`]: https://evm-testnet.flowscan.io/address/0x1B852d242F9c4C4E9Bb91115276f659D1D1f7c56 +[`0xe7c2B80a9de81340AE375B3a53940E9aeEAd79Df`]: https://evm.flowscan.io/address/0xe7c2B80a9de81340AE375B3a53940E9aeEAd79Df +[`CadenceOwnedAccount`s (COA)]: https://developers.flow.com/blockchain-development-tutorials/cross-vm-apps/interacting-with-coa#coa-interface +[`0x0000000000000000000000023f946ffbc8829bfd`]: https://evm-testnet.flowscan.io/address/0x0000000000000000000000023f946FFbc8829BFD +[`0x00000000000000000000000249250a5c27ecab3b`]: https://evm.flowscan.io/address/0x00000000000000000000000249250a5C27Ecab3B \ No newline at end of file diff --git a/docs/build/core-contracts/flow-ecosystem.png b/docs/build/cadence/core-contracts/flow-ecosystem.png similarity index 100% rename from docs/build/core-contracts/flow-ecosystem.png rename to docs/build/cadence/core-contracts/flow-ecosystem.png diff --git a/docs/build/core-contracts/index.md b/docs/build/cadence/core-contracts/index.md similarity index 50% rename from docs/build/core-contracts/index.md rename to docs/build/cadence/core-contracts/index.md index 0b8ffb0828..f542254114 100644 --- a/docs/build/core-contracts/index.md +++ b/docs/build/cadence/core-contracts/index.md @@ -27,24 +27,41 @@ keywords: - contract standards --- +# Flow Core Contracts + Flow relies on a set of core contracts that define key portions of the Flow protocol. These contracts control the following: -- Standard fungible token behavior. ([FungibleToken, FungibleTokenMetadataViews, FungibleTokenSwitchboard, Burner](./02-fungible-token.md)) +- Standard fungible token behavior. ([FungibleToken, FungibleTokenMetadataViews, FungibleTokenSwitchboard, Burner]) - Flow Protocol Token. ([FlowToken](./03-flow-token.md)) -- Flow Service Account. ([ServiceAccount, NodeVersionBeacon, RandomBeaconHistory](./04-service-account.md)) -- Account, transaction and storage fee payments. ([FlowFees and FlowStorageFees](./05-flow-fees.md)) -- Staking and delegation ([FlowIDTableStaking](./06-staking-contract-reference.md)) -- Epochs ([FlowEpoch, FlowClusterQC, FlowDKG](./07-epoch-contract-reference.md)) +- Flow Service Account. ([ServiceAccount, NodeVersionBeacon, RandomBeaconHistory]) +- Account, transaction and storage fee payments. ([FlowFees and FlowStorageFees]) +- Staking and delegation ([FlowIDTableStaking]) +- Epochs ([FlowEpoch, FlowClusterQC, FlowDKG]) There are other important contracts that aren't part of the core protocol but are nevertheless important to developers on Flow: -- Standard Non-Fungible Token Behavior. ([NonFungibleToken](./08-non-fungible-token.md)) -- NFT Metadata Standard. ([MetadataViews, ViewResolver](./09-nft-metadata.md)) -- Staking Collection. ([StakingCollection](./11-staking-collection.md)) -- NFT Storefronts. ([NFTStorefront](./10-nft-storefront.md)) -- Account linking and Hybrid Custody. ([AccountLinking](./12-hybrid-custody.md)) -- EVM interfacing contract. ([EVM](./13-evm.md)) +- Standard Non-Fungible Token Behavior. ([NonFungibleToken]) +- NFT Metadata Standard. ([MetadataViews, ViewResolver]) +- Staking Collection. ([StakingCollection]) +- NFT Storefronts. ([NFTStorefront]) +- Account linking and Hybrid Custody. ([AccountLinking]) +- EVM interfacing contract. ([EVM]) + + + +[FungibleToken, FungibleTokenMetadataViews, FungibleTokenSwitchboard, Burner]: ./02-fungible-token.md +[FlowToken]: ./03-flow-token.md +[ServiceAccount, NodeVersionBeacon, RandomBeaconHistory]: ./04-service-account.md +[FlowFees and FlowStorageFees]: ./05-flow-fees.md +[FlowIDTableStaking]: ./06-staking-contract-reference.md +[FlowEpoch, FlowClusterQC, FlowDKG]: ./07-epoch-contract-reference.md +[NonFungibleToken]: ./08-non-fungible-token.md)) +[MetadataViews, ViewResolver]: ./09-nft-metadata.md)) +[StakingCollection]: ./11-staking-collection.md +[NFTStorefront]: ./10-nft-storefront.md +[AccountLinking]: ./12-hybrid-custody.md +[EVM]: ./13-evm.md) \ No newline at end of file diff --git a/docs/build/core-contracts/scenario_1.png b/docs/build/cadence/core-contracts/scenario_1.png similarity index 100% rename from docs/build/core-contracts/scenario_1.png rename to docs/build/cadence/core-contracts/scenario_1.png diff --git a/docs/build/core-contracts/token-allocation.png b/docs/build/cadence/core-contracts/token-allocation.png similarity index 100% rename from docs/build/core-contracts/token-allocation.png rename to docs/build/cadence/core-contracts/token-allocation.png diff --git a/docs/build/core-contracts/token-distribution.png b/docs/build/cadence/core-contracts/token-distribution.png similarity index 100% rename from docs/build/core-contracts/token-distribution.png rename to docs/build/cadence/core-contracts/token-distribution.png diff --git a/docs/build/cadence/differences-vs-evm/_category_.yml b/docs/build/cadence/differences-vs-evm/_category_.yml new file mode 100644 index 0000000000..951e6775c9 --- /dev/null +++ b/docs/build/cadence/differences-vs-evm/_category_.yml @@ -0,0 +1 @@ +position: 2 diff --git a/docs/build/differences-vs-evm/index.md b/docs/build/cadence/differences-vs-evm/index.md similarity index 61% rename from docs/build/differences-vs-evm/index.md rename to docs/build/cadence/differences-vs-evm/index.md index dcfac90acc..8797e2462b 100644 --- a/docs/build/differences-vs-evm/index.md +++ b/docs/build/cadence/differences-vs-evm/index.md @@ -22,29 +22,31 @@ keywords: - developer tools --- -Flow [Cadence] is designed with many improvements over prior blockchain networks. As a result, you'll notice many differences between Flow vs. other blockchains, especially Ethereum. This document will be most useful to developers who are already familiar with building on the EVM, but contains details useful to all developers. Check out [Why Flow] for a more general overview of the Flow blockchain. +# Differences vs. EVM + +Flow [Cadence] is designed with many improvements over prior blockchain networks. As a result, you'll notice many differences between Flow vs. other blockchains, especially Ethereum. This document will be most useful to developers who are already familiar with building on the EVM, but contains details useful to all developers. Check out [Why Flow] for a more general overview of the Flow blockchain. :::tip -Remember, Flow also supports full [EVM] equivalence! You can start by moving over your existing contracts, then start building new features that take advantage of the power of Cadence. +Remember, Flow also supports full [EVM] equivalence! To start, you can move over your current contracts, then start to build new features that take advantage of the power of Cadence. ::: -## The Flow Cadence Account Model +## The Flow Cadence account model -Key pairs establish ownership on blockchains. In other blockchains (e.g. Bitcoin and Ethereum), the user's address is also calculated based on their public key, making a unique one-to-one relationship between accounts (addresses) and public keys. This also means there is no concrete "account creation" process other than generating a valid key pair. +Key pairs establish ownership on blockchains. In other blockchains (such as Bitcoin and Ethereum), the user's address is also calculated based on their public key, which establishes a unique one-to-one relationship between accounts (addresses) and public keys. This also means there is no concrete "account creation" process other than to generate a valid key pair. -With the advent of smart contracts, Ethereum introduced a new account type for deploying contracts that can use storage space (i.e., to store contract bytecode). You can learn more about the distinction between EOA and Contract [accounts on Ethereum]. +With the advent of smart contracts, Ethereum introduced a new account type to deploy contracts that can use storage space (for example, to store contract bytecode). You can learn more about the distinction between EOA and Contract [accounts on Ethereum]. -The [Flow account model] combines the concepts of EOAs and Contract Accounts into a single account model and decouples accounts and public keys. Flow accounts are associated with one or more public keys of varying weights that specify interested parties that need to produce valid cryptographic signatures for each transaction authorized by that account. +The [Flow account model] combines the concepts of EOAs and Contract Accounts into a single account model and decouples accounts and public keys. Flow accounts are associated with one or more public keys of various weights that specify interested parties that need to produce valid cryptographic signatures for each transaction authorized by that account. ![Screenshot 2023-08-16 at 16.43.07.png](../basics/_accounts_images/Screenshot_2023-08-16_at_16.43.07.png) -This natively enables interesting use cases, like key revocation, rotation, and multi-signature transactions. All Flow accounts can use network storage (e.g., for deploying contracts and storing resources like NFTs) based on the number of FLOW tokens they hold. +This natively allows interesting use cases, like key revocation, rotation, and multi-signature transactions. All Flow accounts can use network storage (for example, to deploy contracts and store resources like NFTs) based on the number of FLOW tokens they hold. :::warning -You must run an explicit account creation transaction on Flow to create a new account. [Flow CLI] can create an account on any network with a given public key. Doing so requires a [very small fee] to be paid in FLOW. +You must run an explicit account creation transaction on Flow to create a new account. [Flow CLI] can create an account on any network with a given public key. This requires a [very small fee] to be paid in FLOW. ::: @@ -52,16 +54,16 @@ Another key difference is that [storage] for data and assets related to an accou Check out the [Accounts] concept document to learn more about Flow accounts. -## Smart Contracts +## Smart contracts On Flow, smart contracts can be written in [Cadence], or Solidity. Cadence syntax is user-friendly and inspired by modern languages like Swift. Notable features of Cadence that make it unique and the key power of the Flow blockchain are: - **Resource-oriented**: Cadence introduces a new type called Resources. Resources enable onchain representation of digital assets natively and securely. Resources can only exist in one location at a time and are strictly controlled by the execution environment to avoid common mishandling mistakes. Each resource has a unique `uuid` associated with it on the blockchain. Examples of usage are fungible tokens, NFTs, or any custom data structure representing a real-world asset. Check out [Resources] to learn more. -- **Capability-based**: Cadence offers a [Capability-based Security] model. This also enables the use of Resources as structures to build access control. Capabilities and [Entitlements] can provide fine-grained access to the underlying objects for better security. For example, when users list an NFT on a Flow marketplace, they create a new Capability to the stored NFT in their account so the buyer can withdraw the asset when they provide the tokens. Check out [Capability-based Access Control] to learn more about Capabilities on Cadence. +- **Capability-based**: Cadence offers a [Capability-based Security] model. This also allows the use of Resources as structures to build access control. Capabilities and [Entitlements] can provide fine-grained access to the underlying objects for better security. For example, when users list an NFT on a Flow marketplace, they create a new Capability to the stored NFT in their account so the buyer can withdraw the asset when they provide the tokens. Check out [Capability-based Access Control] to learn more about Capabilities on Cadence. :::warning -Cadence is not compiled. All contracts are public and unobfuscated on Flow. This isn't that different from the EVM, where it's trivial to decompile a contract back into Solidity. +Cadence is not compiled. All contracts are public and unobfuscated on Flow. This isn't that different from the EVM, where it's trivial to decompile a contract back into Solidity. ::: @@ -73,18 +75,18 @@ Here are some additional resources that can help you get started with Cadence: - [The Cadence tutorial] - ERC-20 equivalent on Flow is the Flow Fungible Token Standard - - [Repository](https://github.com/onflow/flow-ft) - - [Tutorial](https://cadence-lang.org/docs/tutorial/fungible-tokens) + - [Flow FT Repository] + - [FT Tutorial] - ERC-721 equivalent on Flow is the Flow Non-Fungible Token Standard - - [Repository](https://github.com/onflow/flow-nft) - - [Tutorial](https://cadence-lang.org/docs/tutorial/non-fungible-tokens-1) + - [Flow NFT Repository] + - [NFT Tutorial] - Asset marketplaces with Cadence - - [Tutorial](https://cadence-lang.org/docs/tutorial/marketplace-setup) - - [NFT Storefront](https://github.com/onflow/nft-storefront/) is an example marketplace standard + - [Marketplace Setup Tutorial] + - [NFT Storefront] is an example marketplace standard -## Transactions and Scripts +## Transactions and scripts -You can interact with the state on most other blockchains by cryptographically authorizing smart contract function calls. On Flow, transactions offer rich functionality through Cadence code. This allows you to seamlessly combine multiple contracts and function calls into a single transaction that updates the blockchain state - all executing together as one unified operation. +To interact with the state on most other blockchains, you can cryptographically authorize smart contract function calls. On Flow, transactions offer rich functionality through Cadence code. This allows you to seamlessly combine multiple contracts and function calls into a single transaction that updates the blockchain state - which all execute together as one unified operation. Here is a sample transaction that mints an NFT from `ExampleNFT` contract on Testnet: @@ -138,17 +140,17 @@ transaction(recipient: Address) { } ``` -### Authorizing Transactions +### Authorize transactions The process to authorize a transaction on Flow Cadence is more complex, but also much more powerful than an EVM transaction: -- [Accounts] can have multiple keys with varying weights -- Multiple accounts can sign a single transaction (`prepare` takes any number of arguments) +- [Accounts] can have multiple keys with different weights. +- Multiple accounts can sign a single transaction (`prepare` takes any number of arguments). - Transaction computation fees can be paid by a different account, called the `Payer` account. - The [transaction nonce] is provided by the `Proposer` account. This enables rate control and order to be dictated by a different party if needed. - All of the above roles can be the same account. -The same powerful concept also exists for querying the blockchain state using Scripts. Here is a sample script that fetches the `ExampleNFT` IDs owned by a given account on Testnet: +The same powerful concept also exists to query the blockchain state with Scripts. Here is a sample script that fetches the `ExampleNFT` IDs owned by a given account on Testnet: ```cadence /// Script to get NFT IDs in an account's collection @@ -176,39 +178,39 @@ access(all) fun main(address: Address, collectionPublicPath: PublicPath): [UInt6 Check out [Transactions] and [Scripts] to learn more about the concepts. You can also read the Cadence language reference on [Transactions] to dive deeper. -## Flow Nodes +## Flow nodes Developers need a blockchain node to send transactions and fetch state. Flow is based on a multi-node architecture that separates tasks like consensus and computation into separate nodes. You can learn more about the Flow architecture in the [Flow Primer]. Access Nodes are the node type that are most useful for developers, as they provide access to the Flow network [via an API]. -## SDKs and Tools +## SDKs and tools If you're already familiar with blockchain development, here's a comparison between popular software packages and Flow's tooling: -- [Hardhat](https://hardhat.org/) / [Truffle](https://trufflesuite.com/) / [Foundry](https://getfoundry.sh/) - - [Flow CLI](https://github.com/onflow/flow-cli/) provides local development tools and the [Flow Emulator](https://github.com/onflow/flow-emulator) -- [OpenZeppelin](https://www.openzeppelin.com/) - - [Emerald OZ](https://oz.ecdao.org/overview) -- [go-ethereum](https://geth.ethereum.org/) - - [Flow Go SDK](https://github.com/onflow/flow-go-sdk/) - - [FCL](https://github.com/onflow/fcl-js/) also provides Backend API for Flow in JS -- [web3.js](https://github.com/web3/web3.js) - - [FCL](https://github.com/onflow/fcl-js/) - - [flow-cadut](https://github.com/onflow/flow-cadut) provides more utilities for using Flow on Web -- [Remix](https://remix.ethereum.org/) - - [Flow Playground](https://play.flow.com/) provides basic experimentation on the web - - [Cadence VSCode Extension](https://marketplace.visualstudio.com/items?itemName=onflow.cadence) is strongly suggested to install for local development -- [Testing Smart Contracts](https://ethereum.org/en/developers/docs/smart-contracts/testing/) - - [Cadence testing framework](https://cadence-lang.org/docs/testing-framework) enables native tests in Cadence. - - [overflow](https://github.com/bjartek/overflow) for testing in Go. +- [Hardhat] / [Truffle] / [Foundry] + - [Flow CLI] provides local development tools and the [Flow Emulator]. +- [OpenZeppelin] + - [Emerald OZ] +- [go-ethereum] + - [Flow Go SDK] + - [FCL] also provides Backend API for Flow in JS. +- [web3.js] + - [FCL] + - [flow-cadut] provides more utilities to use Flow on Web. +- [Remix] + - [Flow Playground] provides basic experimentation on the web + - [Cadence VSCode Extension] is strongly suggested to install for local development. +- [Testing Smart Contracts] + - [Cadence testing framework] allows native tests in Cadence. + - [overflow] for testing in Go. -[Why Flow]: ../flow.md -[EVM]: ../../evm/about.md +[Why Flow]: ../../flow.md +[EVM]: ../../../build/evm/quickstart.md [accounts on Ethereum]: https://ethereum.org/en/developers/docs/accounts -[Flow CLI]: ../../tools/flow-cli/accounts/create-accounts.md +[Flow CLI]: ../../../build/tools/flow-cli/accounts/create-accounts.md [very small fee]: ../basics/fees.md#fee-structure [Flow account model]: ../basics/accounts.md [Accounts]: ../basics/accounts.md @@ -225,4 +227,28 @@ If you're already familiar with blockchain development, here's a comparison betw [Scripts]: ../basics/scripts.md [Transactions]: https://cadence-lang.org/docs/language/transactions [Flow Primer]: https://flow.com/primer#primer-how-flow-works -[via an API]: ../../networks/flow-networks/index.md +[via an API]: ../../../protocol/flow-networks/index.md +[Flow FT Repository]: https://github.com/onflow/flow-ft +[FT Tutorial]: https://cadence-lang.org/docs/tutorial/fungible-tokens +[Flow NFT Repository]: https://github.com/onflow/flow-nft +[NFT Tutorial]: https://cadence-lang.org/docs/tutorial/non-fungible-tokens-1 +[Marketplace Setup Tutorial]: https://cadence-lang.org/docs/tutorial/marketplace-setup +[NFT Storefront]: https://github.com/onflow/nft-storefront/ +[Hardhat]: https://hardhat.org/) +[Truffle]: https://trufflesuite.com/) +[Foundry]: https://getfoundry.sh/) +[Flow CLI]: https://github.com/onflow/flow-cli/) +[Flow Emulator]: https://github.com/onflow/flow-emulator) +[OpenZeppelin]: https://www.openzeppelin.com/) +[Emerald OZ]: https://oz.ecdao.org/overview) +[go-ethereum]: https://geth.ethereum.org/) +[Flow Go SDK]: https://github.com/onflow/flow-go-sdk/) +[FCL]: https://github.com/onflow/fcl-js/) +[web3.js]: https://github.com/web3/web3.js) +[flow-cadut]: https://github.com/onflow/flow-cadut) +[Remix]: https://remix.ethereum.org/) +[Flow Playground]: https://play.flow.com/) +[Cadence VSCode Extension]: https://marketplace.visualstudio.com/items?itemName=onflow.cadence) +[Testing Smart Contracts]: https://ethereum.org/en/developers/docs/smart-contracts/testing/) +[Cadence testing framework]: https://cadence-lang.org/docs/testing-framework) +[overflow]: https://github.com/bjartek/overflow) \ No newline at end of file diff --git a/docs/build/cadence/quickstart.mdx b/docs/build/cadence/quickstart.mdx new file mode 100644 index 0000000000..8d2c472eb8 --- /dev/null +++ b/docs/build/cadence/quickstart.mdx @@ -0,0 +1,12 @@ +--- +title: Quickstart ↙ +sidebar_position: 1 +--- + +# Quickstart + +Go to [Quickstart](../../blockchain-development-tutorials/cadence/getting-started) + +import {Redirect} from '@docusaurus/router'; + +; \ No newline at end of file diff --git a/docs/build/smart-contracts/_category_.yml b/docs/build/cadence/smart-contracts/_category_.yml similarity index 100% rename from docs/build/smart-contracts/_category_.yml rename to docs/build/cadence/smart-contracts/_category_.yml diff --git a/docs/build/smart-contracts/best-practices/_category_.yml b/docs/build/cadence/smart-contracts/best-practices/_category_.yml similarity index 100% rename from docs/build/smart-contracts/best-practices/_category_.yml rename to docs/build/cadence/smart-contracts/best-practices/_category_.yml diff --git a/docs/build/cadence/smart-contracts/best-practices/contract-upgrades.md b/docs/build/cadence/smart-contracts/best-practices/contract-upgrades.md new file mode 100644 index 0000000000..37d3b5d7ba --- /dev/null +++ b/docs/build/cadence/smart-contracts/best-practices/contract-upgrades.md @@ -0,0 +1,49 @@ +--- +title: Contract Upgrades with Incompatible Changes +sidebar_position: 4 +description: Learn best practices for handling incompatible contract upgrades on Flow. Understand the risks and recommended approaches for upgrading smart contracts while maintaining data integrity. +keywords: + - contract upgrades + - smart contracts + - incompatible changes + - contract migration + - upgrade strategy + - contract deployment + - Flow blockchain + - contract versioning + - data migration + - contract paths + - resource management + - upgrade transactions + - contract compatibility + - best practices + - contract security +--- + +# Contract Upgrades with Incompatible Changes + +## Problem + +I have an incompatible upgrade for a contract. How can I deploy this? + +## Solution + +Please don't perform incompatible upgrades between contract versions in the same account. There is too much that can go wrong. + +You can make [compatible upgrades] and then run a post-upgrade function on the new contract code if needed. + +If you must replace your contract rather than update it, the simplest solution is to add or increase a suffix on any named paths in the contract code (for example, `/public/MyProjectVault` becomes `/public/MyProjectVault002`) in addition to making the incompatible changes, then create a new account and deploy the updated contract there. + +⚠️ Flow identifies types relative to addresses, so you will also need to provide _upgrade transactions_ to exchange the old contract's resources for the new contract's ones. Make sure to inform users as soon as possible when and how they will need to perform this task. + +If you absolutely must keep the old address when you make an incompatible upgrade, then you do so at your own risk. Make sure you perform the following actions in this exact order: + +1. Delete any resources used in the contract account, such as an Admin resource. +2. Delete the contract from the account. +3. Deploy the new contract to the account. + +⚠️ If any user accounts contain `structs` or `resources` from the _old_ version of the contract that have been replaced with incompatible versions in the new one, **they will not load and will cause transactions that attempt to access them to crash**. For this reason, after any users have received `structs` or `resources` from the contract, do not attempt an incompatible upgrade with this method! + + + +[compatible upgrades]: https://cadence-lang.org/docs/language/contract-updatability \ No newline at end of file diff --git a/docs/build/cadence/smart-contracts/best-practices/project-development-tips.md b/docs/build/cadence/smart-contracts/best-practices/project-development-tips.md new file mode 100644 index 0000000000..cc5b665093 --- /dev/null +++ b/docs/build/cadence/smart-contracts/best-practices/project-development-tips.md @@ -0,0 +1,199 @@ +--- +title: Flow Smart Contract Project Development Standards +sidebar_label: Development Standards +sidebar_position: 5 +description: Learn best practices for organizing and managing Cadence smart contract projects. Understand key aspects of design, development, testing, deployment, and community engagement. +keywords: + - development standards + - smart contracts + - project management + - best practices + - Cadence development + - testing standards + - documentation + - deployment process + - project organization + - code review + - security practices + - community engagement + - open source + - technical leadership + - Flow development +--- + +# Smart Contract Project Development Standards + +## Context + +Smart Contracts are the bedrock piece of security for many important parts of the Flow blockchain, as well as for any project that is deployed to a blockchain. + +They are also the most visible technical parts of any project, since users will query them for data, build other smart contracts that interact with them, and use them as materials to learn and templates for future projects. Furthermore, when deployed they are publicly available code on the blockchain and often also in public Github repos. + +Therefore, the process to design, build, test, document, and manage these projects needs to reflect the critical importance they hold in the ecosystem. + +Every software project strikes a balance between effort spent on product or feature delivery versus the many other demands of the software development lifecycle, whether testing, technical debt, automation, refactoring, or documentation. Since we build in Web3, we face the same trade-offs, but in a higher risk and consequence environment than what is typical for most software. A mismanaged or untested smart contract may result in **significant** financial losses because of overlooked and exploited vulnerabilities. We highly recommend builders adopt these best practices to help mitigate these risks. + +If they do so, they can build better smart contracts, avoid potential bugs, support user and third-party adoption of their projects, and increase their chances of success as a model for good software design. Additionally, the more projects that adopt good software design and management standards normalizes this behavior, and encourages other projects in the ecosystem to do the same, which creates a healthier and more vibrant community. + +When you ensure appropriate levels of testing, it results in better smart contracts which have pro-actively modeled threats and engineered against them. dApp builders who ensure appropriate levels of standards adoption ([FungibleToken](https://github.com/onflow/flow-ft), [NFT Metadata], [NFT StoreFront], and so on) amplify the network effects for all in the ecosystem. NFTs in one dApp can be readily consumed by other dApps through onchain events with no new integration required. With your help and participation, we can further accelerate healthy and vibrant network effects across the Flow ecosystem! + +Some of these suggestions might seem somewhat unnecessary, but it is important to model what a project can do to manage its smart contracts the best so that hopefully all of the other projects follow suit. + +This also assumes standard software design best practices also apply. Indeed, many of these suggestions are more general software design best practices, but there may be others that are assumed but not included here. + +### Implement These Practices + +This document serves as mostly an outline of best practices the projects should follow. As with all best practices, teams will choose which applies to them and their work process. However, we recommend that teams explicitly define a minimum acceptable set of standards for themselves along with the mechanisms to ensure that they are observed. + +Some teams may also have their own set of development standards that achieve a similar goal to these. These recommendations are not meant to be the only paths to success, so if a team disagrees with some of these and wants to do things their own way, they are welcome to pursue that. This document just shows some generic suggestions for teams who might not know how they want to manage their project. + +## Design Process + +Smart contracts usually manage a lot of value, have many users, and are difficult to upgrade for a variety of reasons. Therefore, it is important to have a clearly defined design process for the smart contracts before much code is written so that the team +can set themselves up for success. + +Here are some recommendations for how projects can organize the foundations of their projects. + +### Projects should ensure that there is strong technical leadership for their smart contracts + +To develop a dApp requires a clear vision for the role of the smart contract and how it's integrated. Security vulnerabilities may arise from bugs directly in smart contract code (and elsewhere in the system). Asynchronous interaction vectors may lead to forms of malicious abuse, Denial of Service (DOS), and so on in a contract that trigger explosive compute unit costs for the developer or other problems. + +We recommend that engineers who lead a project and deploy to mainnet understand software and security engineering fundamentals and have been thorough in their Cadence skills development. For more in-depth resources to help learn Cadence, see the [Cadence documentation]. + +The technical leader should be someone who understands Cadence well and has written Cadence smart contracts before. Production-level smart contracts are not the place for beginners to get their start. + +It should be this person's responsibility to lead design discussions with product managers and the community, write most of the code and tests, solicit reviews, make requested changes and make sure the project gets completed in a timely manner. + +The leader should also understand how to sign transactions with the CLI to deploy and upgrade smart contracts, run admin transactions, troubleshoot problems, and so on. If something goes wrong in relation to the smart contract that needs to be handled with a bespoke transaction, it is important that the owner knows how to build and run transactions and scripts safely to address the issues and upgrade the smart contracts. + +The project should also have a clear plan of succession in case the original owner is not available or leaves the project. It is important that there are others who can fill in who clearly understand the code and requirements so they can give good feedback, perform effective reviews, and make changes where needed. + +### Projects should maintain a well-organized open source Repo for their smart contracts + +As projects like NBA Topshot have shown, when a blockchain product becomes successful others can and do to build on top of what you are doing. Whether that is analytics, tools, or other value adds that could help grow your project ecosystem, composability is key and that depends on open source development. If there isn't already an open source repo, builders should consider creating one. + +Builders can start from the [the Flow open source template] and make sure all of their repo is set up with some initial documentation for what the repo is for before any code is written. External developers and users should have an easily accessible home page to go to to understand any given project. + +The repo should also have some sort of high-level design document that lays out the intended design and architecture of the smart contract. The project leads should determine what is best for them to include in the document, but some useful things to include are basic user stories, architecture of the smart contracts, and any questions that still need to be answered about it. + +Where applicable, diagrams should be made that describe state machines, user flows, etc. - This document should be shared in an issue in the open source repo where the contracts or features are developed, then later moved to the `.README` or another important docs page. + +A high level design is a key opportunity to model threats and understand the risks of the system. When we collaborate and review designs together, it helps ensure that we capture and address more edge-cases. It's also a lot less effort to iterate on a design than on hundreds of lines of Cadence. + +## Development process recommendations + +### The development process should be iterative, if possible + +The project should develop an MVP first, get reviews, and test thoroughly, then add additional features with tests. This ensures that the core features are designed thoughtfully and makes the review process easier because they can focus on each feature one at a time, rather than get overwhelmed by a huge block of code. + +### Comments and field or function descriptions are essential! + +Our experience writing many Cadence smart contracts has taught us how important documentation is. It especially matters what is documented and for whom, and in that way we are no different from any software language. The "why" is super important, if for example something - an event - that happens in one contract leads to outcomes in a different contract. The "what" helps give context, the reason that the code turned out the way it is. The "how" you don't document - you've written the code. Comments should be directed to those who will change the code after you. + +Write comments at the same time (or even before) the code is written. This helps the developer and reviewers understand the work-in-progress code better, as well as the intentions of the design (for test and review). Comment functions with: + +- A description +- Parameter descriptions +- Return value descriptions + +Top-Level comments and comments for types, fields, events, and functions should use `///` (three slashes) to be recognised by the [Cadence Documentation Generator]. Regular comments within functions should only use two slashes (`//`) + +## Test Recommendations + +Summarized below is a list of test-related recommendations for a typical smart contract project. + +Popular testing frameworks to use for Cadence are listed here: + +- Cadence: [Cadence Testing Framework] +- Go: [Overflow] + +The same person who writes the code should also write the tests. They have the clearest knowledge of the code paths and edge cases. + +Tests should be **mandatory**, not optional, even if the contract is copied from somewhere else. There should be thorough emulator unit tests in the public repo. [See the flow fungible token repo] for an example of unit tests in javascript. + +Every time there is a new Cadence version or emulator version, make sure to update the repo dependencies to confirm the tests all still pass. + +Tests should avoid being monolithic; you should set up individual test cases for each part of the contract to test them in isolation There are some exceptions, like contracts that have to run through a state machine to test different cases. Positive and negative cases need to be tested. + +You should also write integration tests to ensure that your app or backend can interact properly with the smart contracts. + +## Manage Project Keys and deployments + +Smart contract keys and deployments are very important and need to be treated as such. + +### Store Private Keys securely + +Do not keep Private Keys for the contract and admin accounts in plain text format anywhere. Projects should determine a secure solution that works best for them to store their private keys. We recommend that you them in a secure key store such as Google KMS or something similar. + +### Handle deployments to Testnet or Mainnet + +As projects become more successful, communities around them grow. In a trustless ecosystem, that also means more of others building on your contracts. Before you deploy or upgrade a contract, it is important to maintain clear community communications with sufficient notice, since changes will always bring added risk. When you give community members time to review and address issues with upgrades before they happen, it builds trust and confidence in projects. + +Here are a few suggestions for how to manage a deployment or upgrade: + +- Communicate to all stake-holders well in advance + - Share the proposal with the community at least a week in advance (unless it is a critical bug fix). + - Examples of places to share are your project's chat, forum, blog, email list, and so on. + - This will allow the community and other stakeholders to have plenty of time to view the upcoming changes and provide feedback if necessary. + - Share the time of the deployment and the deployment transaction with branch and commit hash information to ensure the transaction itself is correct. + - Coordinate deployment with stakeholders to make sure it is done correctly and on time. + +## Responsibilities to the Community + +Web3 brings tremendous possibilities for engineering applications with trustlessness and composability in mind, and Cadence and Flow offer unique features to achieve this. If every project treats their community and the Flow community with respect and care, the things we can all build together will be very powerful. + +### Projects should have thorough documentation + +Encouraging adoption of project contracts to the broader ecosystem raises the bar around code to provides clear high-level descriptions, with detailed and useful comments within contracts, transactions, and scripts. The more that users can understand a project, that it adheres to standards, and can be built upon with ease, the more likely others will build against it in turn. + +Each project should have a detailed README.md with these sections: + +- Explanation of the project itself with links to the app. +- Addresses on various networks. +- High-level technical description of the contracts with emphasis on important types and functionality +- Architecture diagram (if applicable) - Include links to tutorials if they are external - Flow smart contract standards that a project implements + +Additionally, each contract, transaction, and script should have high-level descriptions at the top of their files. This way, anyone in the community can easily come in and understand what each one is doing without the need to parse confusing code. + +### Projects should engage with and respond to their own Community + +After a contract is deployed, the work doesn't stop there. Project communities require continuous nurturing and support. As the developer of a public project on a public blockchain, the owners have an obligation to be helpful and responsive to the community so that they can encourage composability and third party interactions. + +- Keep issues open in the repo. +- The owner should turn on email notifications for new issue creation in the repo. +- Respond to issues quickly and clean up unimportant ones. +- Consider blog posts to share more details on technical aspects of the project and upcoming changes. + +### Projects should contribute to the greater Flow and Cadence community + +Flow has a vibrant and growing community of contributors around the world. Through our mutual collaboration, we've had numerous community Flow Improvement Proposals ([FLIP]s) shipped. If you have an interest in a particular improvement for Flow or Cadence, we host open meetings which you are welcome to join (announced on discord) and can participate anytime on any of the FLIPs [already proposed]. + +Responsible project maintainers should contribute to discussions about important proposals (new cadence features, standard smart contracts, metadata, and so on), and generally be aware about current best practices and anti-pattern knowledge. Projects who contribute to these discussions are able to influence them to ensure that the language and protocol changes are favorable to them and the rest of the app developers in the ecosystem. It also helps the owner to promote the project and themselves. + +Resources for Best Practices: + +- [cadence/design-pattern] +- [cadence/anti-patterns] +- [cadence/security-best-practices] + +Composability and extensibility should also be priorities while they design, develop, and document their projects. + +If you have any feedback about these guidelines, create an issue in the [onflow/cadence-style-guide] repo or make a PR to update the guidelines so we can start a discussion. + + + +[cadence/design-pattern]: https://cadence-lang.org/docs/design-patterns +[cadence/anti-patterns]: https://cadence-lang.org/docs/anti-patterns +[cadence/security-best-practices]: ./security-best-practices.md) +[FLIP]: https://github.com/onflow/flow/tree/master/flips +[already proposed]: https://github.com/onflow/flow/pulls?q=is%3Aopen+is%3Apr+label%3AFLIP +[onflow/cadence-style-guide]: https://github.com/onflow/cadence-style-guide +[See the flow fungible token repo]: https://github.com/onflow/flow-ft/tree/master/lib/js/test +[Cadence Testing Framework]: ../../smart-contracts/testing.md +[Overflow]: https://github.com/bjartek/overflow +[Cadence Documentation Generator]: https://github.com/onflow/cadence-tools/tree/master/docgen +[the Flow open source template]: https://github.com/onflow/open-source-template +[Cadence documentation]: https://cadence-lang.org/docs/ +[FungibleToken]: https://github.com/onflow/flow-ft +[NFT Metadata]: ../../advanced-concepts/metadata-views.md +[NFT StoreFront]: https://github.com/onflow/nft-storefront \ No newline at end of file diff --git a/docs/build/cadence/smart-contracts/best-practices/security-best-practices.md b/docs/build/cadence/smart-contracts/best-practices/security-best-practices.md new file mode 100644 index 0000000000..1f2da9da20 --- /dev/null +++ b/docs/build/cadence/smart-contracts/best-practices/security-best-practices.md @@ -0,0 +1,94 @@ +--- +title: Cadence Security Best Practices +sidebar_label: Security Best Practices +sidebar_position: 3 +description: Learn essential security practices for writing secure Cadence smart contracts. Understand how to handle references, account storage, capabilities, transactions, and access control safely. +keywords: + - security practices + - Cadence security + - smart contract security + - secure coding + - reference safety + - account storage + - capabilities + - access control + - transaction security + - type safety + - authorization + - secure development + - Flow security + - best practices + - security guidelines +--- + +# Cadence Security Best Practices + +This is an opinionated list of best practices Cadence developers should follow to write more secure Cadence code. + +Some practices listed below might overlap with advice in the [Cadence Anti-Patterns] section, which is a recommended read as well. + +## References + +[References] are ephemeral values and cannot be stored. If persistence is required, store a capability and borrow it when needed. + +References allow free upcasting and downcasting. For example, a restricted type can cast to its unrestricted type, which exposes all `access(all)` functions and fields of the type. So, even if your capability uses an interface to restrict its functionality, it can still downcast to expose all other public functionality. + +Therefore, any privileged functionality in a resource or struct that will have a public capability needs to have entitled accecss, for example `access(Owner)`. Then, the only way to access that functionality would be through an entitled reference, like ``. + +## Account Storage + +Don't trust a users' [account storage]. Users have full control over their data and may reorganize it as they see fit. Users may store values in any path, so paths may store values of "unexpected" types. These values may be instances of types in contracts that the user deployed. + +Always [borrow] with the specific type that is expected. Or, check if the value is an instance of the expected type. + +## Authorized Accounts + +Access to an `&Account` gives access to whatever is specified in the account entitlements list when that account reference is created. Therefore, [don't use Account references] as a function parameter or field unless absolutely necessary and only use the minimum set of entitlements required for the specified functionality so that other account functionality cannot be accessed. + +It is preferable to use capabilities over direct `&Account` references when you expose account data. Capabilities revoke access by unlinking and limits the access to a single value with a certain set of functionality. + +## Capabilities + +Don't store anything under the [public capability storage] unless strictly required. Anyone can access your public capability with `Account.capabilities.get`. If something needs to be stored under `/public/`, restrict privileged functions with entitlements to make sure only read functionality is provided. + +When you publish a capability, the capability might already be present at the given `PublicPath`. In that case, Cadence will panic with a runtime error to not override the already published capability. + +It is a good practice to check if the public capability already exists with `account.capabilities.get().check` before you create it. This function will return `nil` if the capability does not exist. + +If there's a case where borrowing a capability might fail, use the `account.check` function to verify that the target exists and has a valid type. + +Ensure that unauthorized parties cannot access capabilities. For example, capabilities should not be accessible through a public field, such as public dictionaries or arrays. When you expose a capability in such a way, anyone can borrow it and perform all actions that the capability allows. + +## Transactions + +Audits of Cadence code should also include [transactions], as they may contain arbitrary code, just, like in contracts. In addition, they are given full access to the accounts of the transaction's signers, i.e. the transaction is allowed to manipulate the signers' account storage, contracts, and keys. + +Signing a transaction gives access to the `&Account`, i.e. access to the account's storage, keys, and contracts depending on what entitlements are specified. + +Do not blindly sign a transaction. The transaction could for example change deployed contracts by upgrading them with malicious statements, revoking or adding keys, transferring resources from storage, etc. + +## Types + +Use [restricted types and interfaces]. Always use the most specific type possible, following the principle of least privilege. Types should always be as restrictive as possible, especially for resource types. + +If given a less-specific type, cast to the more specific type that is expected. For example, when implementing the fungible token standard, a user may deposit any fungible token, so the implementation should cast to the expected concrete fungible token type. + +## Access Control + +Declaring a field as [`access(all)`] only protects from replacing the field's value, but the value itself can still be mutated if it is mutable. Remember that containers, like dictionaries, and arrays, are mutable. + +Prefer non-public access to a mutable state. That state may also be nested. For example, a child may still be mutated even if its parent exposes it through a field with non-settable access. + +Do not use the `access(all)` modifier on fields and functions unless necessary. Prefer `access(self)`, `acccess(Entitlement)`, or `access(contract)` and `access(account)` when other types in the contract or account need to have access. + + + +[Cadence Anti-Patterns]: https://cadence-lang.org/docs/design-patterns +[References]: https://cadence-lang.org/docs/language/references +[account storage]: https://cadence-lang.org/docs/language/accounts#account-storage +[borrow]: https://cadence-lang.org/docs/language/capabilities +[don't use Account references]: https://cadence-lang.org/docs/anti-patterns#avoid-using-authaccount-as-a-function-parameter +[public capability storage]: https://cadence-lang.org/docs/language/capabilities +[restricted types and interfaces]: https://cadence-lang.org/docs/language/restricted-types +[`access(all)`]: https://cadence-lang.org/docs/language/access-control +[transactions]: https://cadence-lang.org/docs/language/transactions \ No newline at end of file diff --git a/docs/build/smart-contracts/codecov-in-pr.png b/docs/build/cadence/smart-contracts/codecov-in-pr.png similarity index 100% rename from docs/build/smart-contracts/codecov-in-pr.png rename to docs/build/cadence/smart-contracts/codecov-in-pr.png diff --git a/docs/build/smart-contracts/codecov-insights.png b/docs/build/cadence/smart-contracts/codecov-insights.png similarity index 100% rename from docs/build/smart-contracts/codecov-insights.png rename to docs/build/cadence/smart-contracts/codecov-insights.png diff --git a/docs/build/cadence/smart-contracts/deploying.md b/docs/build/cadence/smart-contracts/deploying.md new file mode 100644 index 0000000000..d726824269 --- /dev/null +++ b/docs/build/cadence/smart-contracts/deploying.md @@ -0,0 +1,361 @@ +--- +title: Deploying Contracts +sidebar_label: Deploying Contracts +description: Learn how to deploy and update smart contracts on Flow Mainnet and Testnet. Understand account creation, key management, and deployment best practices. +sidebar_position: 3 +sidebar_custom_props: + icon: 🥇 +keywords: + - contract deployment + - Flow mainnet + - Flow testnet + - account creation + - key management + - Flow CLI + - smart contracts + - deployment guide + - contract updates + - sporks + - network migration + - testnet faucet + - deployment security + - contract addresses + - Flow deployment +--- + +# Deploying Contracts + +Deploying smart contracts to Flow's networks is the final step for you to bring your blockchain application to life. This guide covers everything you need to know to deploy your Cadence contracts to both Flow Testnet and Mainnet, from account creation to contract updates. + +## What you'll learn + +After you complete this guide, you'll be able to: + +- **Create and fund accounts** on Flow Testnet and Mainnet. +- **Deploy contracts** with Flow CLI with proper configuration. +- **Update current contracts** and preserve their addresses. +- **Understand the differences** between testnet and mainnet deployment. +- **Follow security best practices** for production deployments. + +## Prerequisites + +Before you deploy contracts, make sure you have: + +- **Flow CLI installed** and configured. +- **A Flow project** with contracts ready for deployment. +- **Basic understanding** of Cadence smart contracts. +- **Completed testing** of your contracts locally. + +## Deployment Workflow + +The recommended deployment workflow follows this progression: + +1. **Emulator Deployment** - Deploy and test your contracts locally (free, instant). +2. **Testnet Deployment** - Deploy and test your contracts on Flow Testnet (free). +3. **Mainnet Deployment** - Deploy to Flow Mainnet after testing is complete (costs FLOW tokens). +4. **Contract Updates** - Update contracts as needed with the `update` command. + +This approach ensures your contracts work correctly before you commit real resources to mainnet deployment. + +## Deploy to emulator + +The Flow Emulator is your local development environment where you can deploy and test contracts instantly without any network costs or delays. This is the first step in your deployment journey. + +### Start the emulator + +First, start the [Flow Emulator]. In a second terminal: + +```zsh +flow emulator start +``` + +### Create an emulator account + +Create a local account for testing: + +```zsh +flow accounts create --network emulator +``` + +When prompted: + +1. **Account name**: Enter `emulator-account` +2. Select `emulator` as the network when prompted + +This creates a new account on the emulator and adds it to your `flow.json` configuration. + +### Configure emulator deployment + +Update your `flow.json` to include emulator deployment configuration: + +```zsh +flow config add deployment +``` + +Follow the prompts: + +1. **Network**: `emulator` +2. **Account**: `emulator-account` +3. **Contract**: `YourContract` +4. **Deploy more contracts**: `no` (or `yes` if you have multiple contracts) + +Your `flow.json` will now include an emulator deployment section: + +```json +{ + "deployments": { + "emulator": { + "emulator-account": ["YourContract"] + } + } +} +``` + +### Deploy contract to emulator + +Deploy your contract to the local emulator: + +```zsh +flow project deploy --network emulator +``` + +:::warning + +You cannot deploy the same contract to multiple accounts on the same network with one deployment command. If you attempt to do so, you will see: + +❌ Command Error: the same contract cannot be deployed to multiple accounts on the same network + +Edit `flow.json` to remove the duplicate. + +::: + +You will see output similar to: + +```zsh +Deploying 1 contracts for accounts: emulator-account + +YourContract -> 0xf8d6e0586b0a20c7 (contract deployed successfully) + +🎉 All contracts deployed successfully +``` + +### Test your emulator deployment + +Verify your contract works via these scripts and transactions: + +```zsh +# Run a script to read contract state +flow scripts execute cadence/scripts/YourScript.cdc --network emulator + +# Send a transaction to interact with your contract +flow transactions send cadence/transactions/YourTransaction.cdc --network emulator --signer emulator-account +``` + +:::info + +The emulator provides instant feedback and is perfect for rapid development and testing. All transactions are free and execute immediately. + +::: + +## Deploy to Testnet + +For a more complete quickstart, visit the [Getting Started] guide. + +- You should test your contracts, transactions and scripts on Testnet, have strong smart contract test coverage and follow the additional guidelines set out here: [Smart Contract Testing Guidelines]. +- Use `flow init` to [Create a Project] if you need one to practice deployment with. + +### Create a Testnet account + +First, you'll need a testnet account to deploy your contracts. Create one with: + +```zsh +flow accounts create --network testnet +``` + +:::info + +For security reasons, Flow Cadence does not allow accounts to have the same address on testnet, mainnet, and/or the emulator. + +:::: + +When prompted: + +1. **Account name**: Enter `testnet-account` +2. Select `testnet` as the network when prompted + +This creates a new account on testnet and adds it to your `flow.json` configuration. It also saves the private key for the new account in `.pkey` and uses this file to import the key because `flow.json` is visible in the repo. + +:::danger + +As with any other blockchain network, **anyone** with access to the private key for an account can access that account at any time without your knowledge. + +::: + +### Fund your Testnet account + +To deploy contracts and send transactions on testnet, you need FLOW tokens. Flow provides a faucet service to get free testnet tokens. + +```zsh +flow accounts fund testnet-account +``` + +This will open the faucet in your browser. You can also navigate there manually. + +1. Visit the [Testnet Faucet]. +2. Enter your testnet account address. +3. Complete any required verification (captcha, and so on). +4. Request tokens (you'll receive 100000 testnet FLOW tokens). + +Check your account balance: + +```zsh +flow accounts list +``` + +You will see your account details with a balance of FLOW tokens. + +### Configure Testnet deployment + +Update your `flow.json` to include testnet deployment configuration: + +```zsh +flow config add deployment +``` + +Follow the prompts: + +1. **Network**: `testnet` +2. **Account**: `testnet-account` +3. **Contract**: `YourContract` +4. **Deploy more contracts**: `no` (or `yes` if you have multiple contracts) + +Your `flow.json` will now include a testnet deployment section: + +```json +{ + "deployments": { + "testnet": { + "testnet-account": ["YourContract"] + } + } +} +``` + +### Deploy contract to Testnet + +Deploy your contract to the public testnet: + +```zsh +flow project deploy --network testnet +``` + +You will see output similar to: + +```zsh +Deploying 1 contracts for accounts: testnet-account + +YourContract -> 0x9942a81bc6c3c5b7 (contract deployed successfully) + +🎉 All contracts deployed successfully +``` + +## Deploy to Mainnet + +After you've successfully tested your contracts on testnet, you can deploy to mainnet. You'll need a mainnet account with real FLOW tokens. + +### Create a Mainnet account + +For mainnet, you'll need to acquire FLOW tokens through exchanges or other means, as there's no faucet. + +```zsh +flow accounts create --network mainnet +``` + +When prompted: + +1. **Account name**: Enter `mainnet-account` +2. **Select "Mainnet" Network** + +### Acquire FLOW tokens + +You can purchase FLOW tokens from major exchanges. Make sure your mainnet account has sufficient FLOW tokens to cover deployment costs. Flow is a very efficient network, so even 1.0 FLOW is sufficient to deploy large numbers of contracts. + +### Configure Mainnet deployment + +Add mainnet deployment configuration to your `flow.json`: + +```zsh +flow config add deployment --network mainnet +``` + +Follow the prompts: + +1. **Network**: `mainnet` +2. **Account**: `mainnet-account` +3. **Contract**: `YourContract` +4. **Deploy more contracts**: `no` (or `yes` if you have multiple contracts) + +Your `flow.json` will now include mainnet configuration: + +```json +{ + "deployments": { + "mainnet": { + "mainnet-account": ["YourContract"] + } + } +} +``` + +### Deploy to Mainnet + +Deploy your contracts to mainnet: + +```zsh +flow project deploy --network mainnet +``` + +:::warning + +This deployment costs (a relatively small amount of) real FLOW tokens and you cannot undo it. You can, however, redeploy your contracts to update them, or delete them. + +::: + +You will see output similar to: + +```zsh +Deploying 1 contracts for accounts: mainnet-account + +YourContract -> 0xABC123DEF456789 (contract deployed successfully) + +🎉 All contracts deployed successfully +``` + +:::info + +All your contract deployment addresses are stored in `flow.json`. Mainnet, Testnet and local (emulator) are stored as well. + +::: + +## Deploy updated contracts on mainnet + +You can update contracts and retain the contract address. To do this, use the [Flow CLI contract update command] to redeploy an updated version of your contract: + +```zsh +flow accounts update-contract ./YourContract.cdc --signer mainnet-account --network mainnet +``` + + +[Flow CLI]: ../../../build/tools/flow-cli/install +[Getting Started]: ../../../blockchain-development-tutorials/cadence/getting-started/smart-contract-interaction +[Smart Contract Testing Guidelines]: ./testing.md +[Create a Project]: ../../../build/tools/flow-cli/index.md +[Flow CLI contract update command]: ../../../build/tools/flow-cli/accounts/account-update-contract.md +[Flow CLI get account command]: ../../../build/tools/flow-cli/accounts/get-accounts.md +[Sporks]: ../../../protocol/node-ops/node-operation/network-upgrade +[Flow Emulator]: ../../../build/tools/emulator +[Testnet Faucet]: https://faucet.flow.com/ +[core contracts]: ../core-contracts/index.md +[some code examples from the Flow Go SDK]: https://github.com/onflow/flow-go-sdk/tree/master/examples +[Forum]: https://forum.flow.com/ +[Discord]: https://discord.com/invite/J6fFnh2xx6 diff --git a/docs/build/smart-contracts/hybrid-custody-ci.png b/docs/build/cadence/smart-contracts/hybrid-custody-ci.png similarity index 100% rename from docs/build/smart-contracts/hybrid-custody-ci.png rename to docs/build/cadence/smart-contracts/hybrid-custody-ci.png diff --git a/docs/build/smart-contracts/learn-cadence.md b/docs/build/cadence/smart-contracts/learn-cadence.md similarity index 77% rename from docs/build/smart-contracts/learn-cadence.md rename to docs/build/cadence/smart-contracts/learn-cadence.md index 389c5129ca..3863900155 100644 --- a/docs/build/smart-contracts/learn-cadence.md +++ b/docs/build/cadence/smart-contracts/learn-cadence.md @@ -1,9 +1,9 @@ --- sidebar_position: 1 -slug: /build/learn-cadence +slug: /build/cadence/learn-cadence title: Learn Cadence ↗️ --- -; \ No newline at end of file +; diff --git a/docs/build/cadence/smart-contracts/overview.md b/docs/build/cadence/smart-contracts/overview.md new file mode 100644 index 0000000000..f50a2c8fe9 --- /dev/null +++ b/docs/build/cadence/smart-contracts/overview.md @@ -0,0 +1,119 @@ +--- +title: Smart Contracts on Flow +sidebar_label: Smart Contracts on Flow +sidebar_position: 2 +sidebar_custom_props: + icon: 🛠️ +description: Learn about smart contract development on Flow blockchain. Understand data storage, standards implementation, and best practices for building decentralized applications using Cadence. +keywords: + - smart contracts + - Flow blockchain + - Cadence + - dApp development + - NFT standards + - fungible tokens + - contract storage + - IPFS storage + - blockchain data + - Flow standards + - contract interfaces + - development tools + - Flow CLI + - Flow emulator + - decentralized apps +--- + +# Smart Contracts on Flow + +At its core, a decentralized application is defined by the [smart contracts] it uses on the blockchain. Rather than rely on centralized application servers and databases, apps model their core application logic with smart contracts, often referred to as the "onchain" code. + +It is therefore helpful to develop a clear model for your app that takes into account the data and logic that will exist in your smart contracts. In particular, it is important to differentiate between the parts of your app that must live on chain and those that should live off chain. + +## How to write smart contracts on Flow + +Smart contracts on the Flow blockchain are implemented in [Cadence], a resource-oriented programming language specifically designed for smart contract development. + +### Onboard to Cadence + +To get started with Cadence, we recommended that you cover the introductory tutorials available in the [Flow Playground], a simple web IDE designed for you to learn Cadence. + +### Configure your local environment + +To build confidently, you will want to set up the appropriate local environment and have an adequate test suite to ensure your smart contracts operate as intended. To do this, familiarize yourself with the following tools: + +- [Flow CLI]: A utility to directly interact with the chain and manage accounts and contracts. +- [Flow Emulator] A lightweight server that simulates the Flow blockchain (strongly recommended during development). +- [Flow Dev Wallet] A utility to simulate user wallets in development. +- [Visual Studio Code Extension] An IDE integration used to develop smart contracts. + +## Store data on Flow + +All apps will store important data on the blockchain, and some more than others -- especially NFT apps. You'll want to consider the following when you store data on the Flow blockchain. + +### What does your data need to represent? + +Permanence is a key property of blockchains; users trust that the data they store will continue to exist for years to come, and this is a defining characteristic of assets like NFTs. Therefore, well-designed digital assets store the information necessary to retain their value without external dependencies. + +### Storage limits and fees + +However, there are practical constraints to data storage on a blockchain. Developer and user accounts must retain a small amount of FLOW tokens, known as the storage fee, for bytes of data stored in their accounts. The minimum storage fee will grant each account a minimum storage amount. If an account holds assets that demand more bytes of storage, the account will need to retain more FLOW tokens to increase the storage amount according to Flow's [fee schedule]. A more compact data model can keep storage needs down. + +Furthermore, a single Flow transaction has a size limit of 4MB, which limits the rate at which large amounts of data can be transferred to the blockchain. + +Lastly, a blockchain is not a content delivery network and therefore cannot serve media assets, such as videos, at the speeds expected by modern applications. + +For these reasons, it usually isn't practical to store large media assets such as videos and high-definition images on the Flow blockchain. Instead, consider an external storage solution. + +### External storage networks + +Decentralized storage networks such as IPFS allow you to store large digital assets off chain, but with no need to rely on centralized servers. Instead of save an entire asset to the Flow blockchain, you can save the content hash (known as a CID on IPFS) on the blockchain and then store the source file off-chain. This way, users can verify that the media file matches the digital asset. + +IPFS files can be uploaded via a pinning service such as Pinata; see their [NFT tutorial] for an example of how to use Pinata with Flow. + +IPFS files are served through [gateways], many of which leverage caching to provide fast response times. Cloudflare provides a [public IPFS Gateway], and Pinata also supports [dedicated gateways with custom domains]. + +## Use current standards + +The Flow blockchain has smart contract standards for both fungible and non-fungible tokens that you should implement when you build your contracts. + +### Non-Fungible Tokens (NFTs) + +All NFTs on the Flow blockchain implement the [NonFungibleToken] interface, which allows them to be compatible with wallets, marketplaces and other cross-app experiences. + +See the [NFT Guide] for a guide on how to create a basic NFT contract that conforms to the standard. + +- [NonFungibleToken] (NFT) contract interface + +### NFT sales and trading + +Flow has a standard contract to facilitate both the direct sales and peer-to-peer trading of NFTs. The NFT storefront contract is useful for apps that want to provide an NFT marketplace experience. + +- [NFT Storefront contract] + +### Fungible Tokens + +Fungible tokens (that is, coins, currencies) on the Flow blockchain, which includes the default cryptocurrency token FLOW, implement the [FungibleToken] interface. + +See the [FT Guide] for a guide on how to create a basic fungible token contract that conforms to the standard. + +- [FungibleToken] contract interface: + + + +[smart contracts]: https://en.wikipedia.org/wiki/Smart_contract +[Cadence]: https://github.com/onflow/cadence +[Flow Playground]: https://play.flow.com/ +[Flow CLI]: ../../../build/tools/flow-cli/index.md +[Flow Emulator]: ../../../build/tools/emulator/index.md +[Flow Dev Wallet]: https://github.com/onflow/fcl-dev-wallet/ +[Visual Studio Code Extension]: ../../../build/tools/vscode-extension/index.md +[fee schedule]: ../basics/fees.md#storage +[NFT tutorial]: https://medium.com/pinata/how-to-create-nfts-like-nba-top-shot-with-flow-and-ipfs-701296944bf +[gateways]: https://docs.ipfs.io/concepts/ipfs-gateway/ +[public IPFS Gateway]: https://developers.cloudflare.com/distributed-web/ipfs-gateway +[dedicated gateways with custom domains]: https://medium.com/pinata/announcing-dedicated-ipfs-gateways-60f599949ce +[NonFungibleToken]: ../core-contracts/08-non-fungible-token.md +[NFT Guide]: ../../../blockchain-development-tutorials/tokens/nft-cadence.md +[NFT Storefront contract]: https://github.com/onflow/nft-storefront +[FungibleToken]: ../core-contracts/02-fungible-token.md +[FT Guide]: ../../../blockchain-development-tutorials/tokens/fungible-token-cadence.md \ No newline at end of file diff --git a/docs/build/cadence/smart-contracts/testing-strategy.md b/docs/build/cadence/smart-contracts/testing-strategy.md new file mode 100644 index 0000000000..5056c4a76b --- /dev/null +++ b/docs/build/cadence/smart-contracts/testing-strategy.md @@ -0,0 +1,213 @@ +--- +title: Testing Smart Contracts +sidebar_label: Testing Smart Contracts +sidebar_position: 3 +description: A layered testing strategy for Flow—unit tests, forked integration, and a forked emulator sandbox. Guidance for reproducibility and simple CI setup. +keywords: + - testing strategy + - unit testing + - integration testing + - fork testing + - flow test --fork + - flow emulator --fork + - emulator + - testnet + - CI pipeline + - continuous integration + - reproducibility + - fork-height + - block height pinning + - test selection + - smoke tests + - E2E testing + - account impersonation + - test troubleshooting + - golden files + - test automation + - Flow CLI + - Cadence tests + - spork boundaries +--- + +# Testing Smart Contracts + +This document describes a single, pragmatic strategy to test on Flow. Use layers that are deterministic and isolated by default, add realism with forks when needed, and keep a minimal set of live network checks before release. + +## At a glance + +- **Unit & Property — Test Framework**: Hermetic correctness and invariants. +- **Integration — Fork Testing**: Real contracts and data; mutations stay local. +- **Local integration sandbox (interactive, `flow emulator --fork`)**: Drive apps/E2E against production-like state. +- **Staging (testnet)**: Final plumbing and config checks. +- **Post-deploy (read-only)**: Invariant dashboards and alerts. + +## Layers + +### Unit and property — test framework + +- Use `flow test` +- **Use when**: You validate Cadence logic, invariants, access control, error paths, footprint. +- **Why**: Fully deterministic and isolated; highest-regression signal. +- **Run**: Every commit/PR; wide parallelism. +- **Notes**: Write clear success andfailure tests, add simple “this should always hold” rules when helpful, and avoid external services. + +See also: [Running Cadence Tests]. + +### Integration — fork testing + +- **Use when**: You interact with real on-chain contracts or data (FTand NFT standards, AMMs, wallets, oracles, bridges), upgrade checks, historical repro. +- **Why**: Real addresses, capability paths, and resource schemas; catches drift early. +- **Run**: On Pull Requests (PRs), run the full forked suite if practical (pinned), or a small quick set; run more cases nightly or on main. +- **How**: Configure with `#test_fork(network: "mainnet", height: nil)` in your test file, or use `flow test --fork` CLI flags. +- **Notes**: + - Pin with `height: 85432100` in the pragma (or `--fork-height` CLI flag) where reproducibility matters. + - Prefer local deployment + impersonation over real mainnet accounts. + - Mutations are local to the forked runtime; the live network is never changed. + - Be mindful of access-node availability and rate limits. + - External oracles and protocols: forked tests do not call off-chain services or other chains; mock these or run a local stub. + +See also: [Fork Testing with Cadence], [Fork Testing Flags]. + +### Local integration sandbox — `flow emulator --fork` + +- **Use when**: You drive dApps, wallets, bots, indexers, or exploratory debugging outside the test framework. +- **Why**: Production-like state with local, disposable control; great for end to end (E2E) and migrations. +- **Run**: Dev machines and focused E2E CI jobs. +- **Notes**: + - Pin height; run on dedicated ports; impersonation is built-in; mutations are local; off-chain/oracle calls are not live—mock or run local stubs + - What to run: Manual exploration and debugging of flows against a forked state; frontend connected to the emulator (for example, `npm run dev` pointed at `http://localhost:8888`); automated E2E/FE suites (for example, Cypress or Playwright) against the local fork; headless clients, wallets/bots/indexers, and migration scripts. + - Not for the canonical Cadence test suite—prefer fork testing with `flow test` for scripted Cadence tests (see [Fork Testing Flags] and [Running Cadence Tests]) + + Quick start example: + + ```bash + # Start a fork (pinning height recommended for reproducibility) + flow emulator --fork mainnet --fork-height + ``` + + ```javascript + // In your root component (e.g., App.tsx) + import { FlowProvider } from '@onflow/react-sdk'; + import flowJSON from './flow.json'; + + function App() { + return ( + + {/* Your app components */} + + ); + } + ``` + + ```bash + # Run app + npm run dev + + # Run E2E tests + npx cypress run + ``` + +See also: [Interactive Testing with Forked Emulator], [Flow Emulator]. + +### Staging — Testnet + +- **Use when**: Final network plumbing and configuration checks before release. +- **Why**: Validates infra differences you cannot fully simulate. +- **Run**: Pre-release and on infra changes. +- **Notes**: + - Keep canaries minimal and time-boxed; protocol and partner support may be limited on testnet (not all third-party contracts are deployed or up to date). + - What to run: Minimal app smoke tests (login and auth, key flows, mint and transfer, event checks); frontend connected to Testnet with a small Cypress/Playwright smoke set; infra or config checks (endpoints, contract addresses oraliases, env vars, service or test accounts) + - Not for the canonical Cadence test suite — prefer fork testing with `flow test` for scripted tests (see [Fork Testing Flags] and [Running Cadence Tests]) + + Quick start example: + + ```javascript + // In your root component (e.g., App.tsx) + import { FlowProvider } from '@onflow/react-sdk'; + + function App() { + return ( + + {/* Your app components */} + + ); + } + ``` + + ```bash + # Run app + npm run dev + + # Run smoke tests + npx cypress run --spec "cypress/e2e/smoke.*" + ``` + +See also: [Flow Networks]. + +### Post-deploy monitoring (read-only) + +- **Use when**: After releases to confirm invariants and event rates. +- **Why**: Detects real-world anomalies quickly. +- **Run**: Continuous dashboards and alerts tied to invariants. + +## Reproducibility and data management + +- **Pin where reproducibility matters**: Use `--fork-height ` for both `flow test --fork` and `flow emulator --fork`. Pins are per‑spork; historical data beyond spork boundaries is unavailable. For best results, keep a per‑spork stable pin and also run a "latest" freshness job. +- **Named snapshots**: Maintain documented pin heights (for example, in CI vars or a simple file) with names per dependency or protocol +- **Refresh policy**: Advance pins via a dedicated “freshness” PR; compare old vs. new pins +- **Goldens**: Save a few canonical samples (for example, event payloads, resource layouts, key script outputs) as JSON in your repo, and compare them in CI to catch accidental schema/shape changes. Update the samples intentionally as part of upgrades. + +## CI tips + +- PRs: Run emulator unit or property and forked integration (pinned). Full suite is fine if practical; otherwise a small quick set. +- Nightly/Main: Add a latest pin job and expand fork coverage as needed. +- E2E (optional): Use `flow emulator --fork` at a stable pin and run your browser tests. + +## Test selection and tagging + +- **Optional naming helpers**: Use simple suffixes in test names like `_fork`, `_smoke`, `_e2e` if helpful. +- Pass files and directories to run the tests you care about: `flow test FILE1 FILE2 DIR1 ...` (most common). +- Optionally, use `--name ` to match test functions when it’s convenient. +- **Defaults**: PRs can run the full fork suite (pinned) or a small quick set; nightly runs broader coverage (and optional E2E). + +## Troubleshooting tips + +- Re-run at the same `--fork-height`, then at latest +- Compare contract addresses/aliases in `flow.json` +- Diff event or resource shapes against your stored samples +- Check access-node health and CI parallelism or sharding + +## Dos and Don’ts + +- **Do**: Keep a fast, hermetic base; pin forks; tag tests; maintain tiny PR smoke sets; document pins and set a simple refresh schedule (for example, after each spork or monthly). +- **Don't**: Make "latest" your default in CI; create or rely on real mainnet accounts; conflate fork testing (`flow test`) with the emulator's fork mode (`flow emulator --fork`). + +## Related docs + +- Guide → Running tests: [Running Cadence Tests] +- Guide → How-to: [Cadence Testing Framework] +- Tutorial → Step-by-step: [Fork Testing with Cadence] +- Tool → Emulator (including fork mode): [Flow Emulator] +- Reference → Fork testing flags: [Fork Testing Flags] + + + +[Running Cadence Tests]: ../../tools/flow-cli/tests.md +[Cadence Testing Framework]: ./testing.md +[Fork Testing with Cadence]: ../../../blockchain-development-tutorials/cadence/fork-testing/index.md +[Interactive Testing with Forked Emulator]: ../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md +[Flow Emulator]: ../../tools/emulator/index.md +[Fork Testing Flags]: ../../tools/flow-cli/tests.md#fork-testing-flags +[Flow Networks]: ../../../protocol/flow-networks/index.md +[Network Upgrade (Spork) Process]: ../../../protocol/node-ops/node-operation/network-upgrade.md +[Flow CLI Configuration (flow.json)]: ../../tools/flow-cli/flow.json/initialize-configuration.md +[Dependency Manager]: ../../tools/flow-cli/dependency-manager.md +[Cadence Testing Framework]: https://cadence-lang.org/docs/testing-framework diff --git a/docs/build/smart-contracts/testing.md b/docs/build/cadence/smart-contracts/testing.md similarity index 51% rename from docs/build/smart-contracts/testing.md rename to docs/build/cadence/smart-contracts/testing.md index a573df49bc..81739308b7 100644 --- a/docs/build/smart-contracts/testing.md +++ b/docs/build/cadence/smart-contracts/testing.md @@ -1,39 +1,38 @@ --- -title: Testing Your Contracts -sidebar_label: Testing Your Contracts -description: Learn comprehensive testing strategies for Flow smart contracts. Master unit testing, integration testing, and code coverage using the Cadence Testing Framework and Flow CLI. +title: Cadence Testing Framework +sidebar_label: Cadence Testing Framework +description: Learn how to write and run tests for Cadence contracts, scripts, and transactions using the Cadence Testing Framework and Flow CLI. sidebar_position: 4 sidebar_custom_props: icon: 📝 keywords: - - smart contract testing - Cadence testing - - test coverage - unit tests - - integration tests - - Flow CLI - - test automation - - testing framework - - test suites - code coverage + - Flow CLI - test assertions - test helpers - - automated testing - - contract verification - - testing best practices --- +# Testing Smart Contracts + Testing is an essential part of smart contract development to ensure the correctness and reliability of your code. The Cadence Testing Framework provides a convenient way to write tests for your contracts, scripts and transactions which allows you to verify the functionality and correctness of your smart contracts. +:::info + +Looking for high‑level guidance on when to use emulator, forks, or testnet? See [Testing Smart Contracts](./testing-strategy.md). + +::: + ## Install Flow CLI -The [Flow CLI](../../tools/flow-cli/index.md) is the primary tool for developing, testing, and deploying smart contracts to the Flow network. +The [Flow CLI] is the primary tool for you to develop, test, and deploy smart contracts to the Flow network. -If you haven't installed the Flow CLI yet and have [homebrew](https://brew.sh/) installed, simply run `brew install flow-cli`. Alternatively, refer to the Flow CLI [installation instructions](../../tools/flow-cli/install.md). +If you haven't installed the Flow CLI yet and have [homebrew](https://brew.sh/) installed, simply run `brew install flow-cli`. Alternatively, refer to the Flow CLI [installation instructions]. ## Create a new project -In your preferred code editor, create a new directory for your project and navigate to it in the terminal. Then initialize a new Flow project by running the command `flow init`. This will create a `flow.json` config file that contains the [project's configuration](../../tools/flow-cli/flow.json/configuration.md). +In your preferred code editor, create a new directory for your project and navigate to it in the terminal. Then initialize a new Flow project with the `flow init` command. This will create a `flow.json` config file that contains the [project's configuration]. ```bash mkdir test-cadence @@ -85,6 +84,7 @@ Next up, we need to add our new contract in the `contracts` key in the `flow.jso ``` For the time being, the address for the `testing` alias, can be one of: + - `0x0000000000000005` - `0x0000000000000006` - `0x0000000000000007` @@ -128,12 +128,13 @@ fun testSubtract() { ``` This code: + - imports the `Calculator` contract from the `calculator.cdc` file (according to `flow.json`) - deploys the `Calculator` contract to the address specified in the `testing` alias - defines two test cases: `testAdd()` and `testSubtract()` - calls `add()` and `subtract()` methods with different input values respectively. -## Running the test cases +## Run the test cases To run the test cases, use the following command in the terminal: @@ -141,7 +142,7 @@ To run the test cases, use the following command in the terminal: flow test --cover --covercode="contracts" calculator_test.cdc ``` -This command uses the Flow CLI to run the test cases and display the output. You should see the following output: +This command uses the Flow CLI to run the test cases and display the output. You will see the following output: ```bash Test results: "calculator_test.cdc" @@ -150,7 +151,7 @@ Test results: "calculator_test.cdc" Coverage: 66.7% of statements ``` -This output indicates that both test cases ran successfully, and the two smart contract methods are functioning as expected. With the supplied flags (`--cover` & `--covercode="contracts"`), we also get code coverage insights for the contracts under testing. The code coverage percentage is `66.7%`, because we have not added a test case for the `multiply` method. By viewing the auto-generated `coverage.json` file, we see: +This output indicates that both test cases ran successfully, and the two smart contract methods work as expected. With the supplied flags (`--cover` & `--covercode="contracts"`), we also get code coverage insights for the contracts under testing. The code coverage percentage is `66.7%`, because we have not added a test case for the `multiply` method. When we view the auto-generated `coverage.json` file, we see: ```json { @@ -161,9 +162,7 @@ This output indicates that both test cases ran successfully, and the two smart c "4": 1, "9": 1 }, - "missed_lines": [ - 14 - ], + "missed_lines": [14], "statements": 3, "percentage": "66.7%" } @@ -176,9 +175,10 @@ Line 14 from the `Calculator` smart contract is marked as missed. This is the li ```cadence return a * b ``` + which is the `multiply` method. -By adding a test case for the above method: +When we add a test case for the above method: ```cadence calculator_test.cdc ... @@ -201,21 +201,21 @@ Test results: "calculator_test.cdc" Coverage: 100.0% of statements ``` -## Advanced Testing Techniques +## Advanced testing techniques -The Cadence testing framework provides various features and techniques for writing comprehensive test scenarios. Some of these include: +The Cadence testing framework provides various features and techniques used to write comprehensive test scenarios. Some of these include: -- [**Code Coverage**](https://github.com/m-Peter/flow-code-coverage): You can use the `--cover` flag with the `flow test` command to view code coverage results when running your tests. This allows you to identify areas of your code that are not adequately covered by your test inputs. -- **Test Helpers**: Test helpers are reusable functions that help you set up the initial state for your test files. You can define test helpers in a Cadence program and use them in your test files by importing it whenever needed. -- [**Assertions**](https://cadence-lang.org/docs/testing-framework#assertions): The testing framework provides built-in assertion functions, such as `assertEqual`, `beNil`, `beEmpty`, `contain`, to help you verify the expected behavior of your smart contracts. +- [**Code Coverage**]: You can use the `--cover` flag with the `flow test` command to view code coverage results when you run your tests. This allows you to identify areas of your code that are not adequately covered by your test inputs. +- **Test Helpers**: Test helpers are reusable functions that help you set up the initial state for your test files. You can define test helpers in a Cadence program and use them in your test files by importing it whenever you need it. +- [**Assertions**]: The testing framework provides built-in assertion functions, such as `assertEqual`, `beNil`, `beEmpty`, `contain`, to help you verify the expected behavior of your smart contracts. - **Test Suites**: You can organize your test files into test suites to improve the readability and maintainability of your test code. Test suites allow you to group related test cases and set up common test helpers for all the tests in the suite. -- [**Integration tests**](https://github.com/bjartek/overflow): In our previous example, we would directly call the available methods on the contract under test. This is generally categorized as unit testing. You can also write integration tests, by executing scripts & transactions to interact with the contracts under testing. If you would like to write your tests in Go, instead of Cadence, you can use [Overflow tool](https://github.com/bjartek/overflow) to run integration tests against either an local emulator, testnet, mainnet or an in memory instance of the flow-emulator. +- [**Integration tests**]: In our previous example, we would directly call the available methods on the contract under test. This is generally categorized as unit testing. You can also write integration testswhen you execute scripts and transactions to interact with the contracts under testing. If you would like to write your tests in Go, instead of Cadence, you can use [Overflow tool] to run integration tests against either an local emulator, testnet, mainnet or an in memory instance of the flow-emulator. -By leveraging these advanced testing techniques, you can write more robust and reliable smart contracts in Cadence. In this example, we set up a basic testing environment, wrote a simple smart contract in Cadence, and created a test file to verify its functionality. We then used the Flow CLI to run the test file and confirm that the smart contract is working correctly. +When you leverage these advanced testing techniques, you can write more robust and reliable smart contracts in Cadence. In this example, we set up a basic testing environment, wrote a simple smart contract in Cadence, and created a test file to verify its functionality. We then used the Flow CLI to run the test file and confirm that the smart contract works correctly. -This is a basic example, and there are many more advanced features and techniques you can explore when working with the Cadence Testing Framework. +This is a basic example, and there are many more advanced features and techniques you can explore when you work with the Cadence Testing Framework. -For more in-depth tutorials and documentation, refer to the official [Cadence language documentation](https://cadence-lang.org/) and the [Flow CLI documentation](../../tools/flow-cli/index.md). +For more in-depth tutorials and documentation, refer to the official [Cadence language documentation] and the [Flow CLI documentation]. ## Testing Requirements @@ -228,25 +228,24 @@ It is suggested to follow the following best practices: Make sure you test all contracts - and the integration into your application extensively before proceeding to the mainnet. You should aim to replicate all conditions as closely as possible to the usage patterns on mainnet. -## Writing Tests +## Write Tests -There are official SDKs/frameworks for Flow in Cadence, Go and JavaScript. +There are official SDKsand frameworks for Flow in Cadence, Go and JavaScript. -In all three cases, the test code will need to deploy the contracts, configure accounts to interact with them and send transactions to them. It will then have to wait for the transactions to be sealed and check the results by catching exceptions, checking for events, and querying state using scripts. +In all three cases, the test code will need to deploy the contracts, configure accounts to interact with them and send transactions to them. It will then have to wait for the transactions to be sealed and check the results. To do this, it catches exceptions, checks for events, and querys state via scripts. ### Cadence tests -Cadence comes with built-in support for code coverage, as well as a native testing framework which allows developers to write their tests using Cadence. -This framework is bundled with the [Flow CLI](../../tools/flow-cli/index.md) tool, which includes a dedicated command for running tests (`flow test`). +Cadence comes with built-in support for code coverage, as well as a native testing framework which allows developers to write their tests with Cadence. This framework is bundled with the [Flow CLI] tool, which includes a dedicated command to run tests (`flow test`). -You can find examples of Cadence tests in the following projects: [hybrid-custody](https://github.com/onflow/hybrid-custody/tree/main/test), [flow-nft](https://github.com/onflow/flow-nft/tree/master/tests), [flow-ft](https://github.com/onflow/flow-ft/tree/master/tests). -Visit the [documentation](https://cadence-lang.org/docs/testing-framework) to view all the available features. +You can find examples of Cadence tests in the following projects: [hybrid-custody], [flow-nft], [flow-ft]. +Visit the [Cadence documentation] to view all the available features. -The [Hybrid Custody](https://github.com/onflow/hybrid-custody#readme) project is a prime example which utilizes both the Cadence testing framework and code coverage in its CI. +The [Hybrid Custody] project is a prime example which utilizes both the Cadence testing framework and code coverage in its CI. ![Hybrid Custody CI](./hybrid-custody-ci.png) -There is also a [repository](https://github.com/m-Peter/flow-code-coverage#readme) which contains some sample contracts and their tests. +There is also a [repository] which contains some sample contracts and their tests. ![Automated CI Coverage Report](./codecov-in-pr.png) @@ -256,38 +255,37 @@ There is also a [repository](https://github.com/m-Peter/flow-code-coverage#readm The Cadence testing framework utilizes the emulator under the hood. -### Go Tests - -Tests in Go can be written using [flow-go-sdk](https://github.com/onflow/flow-go-sdk) and the go test command. - -You can find examples of Go tests in the following projects: [flow-core-contracts](https://github.com/onflow/flow-core-contracts/tree/master/lib/go/test), [flow-nft](https://github.com/onflow/flow-nft/tree/master/lib/go/test), [flow-ft](https://github.com/onflow/flow-ft/tree/master/lib/go/test). - - -These tests are tied to the emulator but can be refactored to run on testnet - - -## Testing Your Application - -### Automated Testing of Contract Code - -All contracts should include test coverage for _all contract functions_. Make sure you've accounted for success and failure cases appropriately. - -Tests should also be runnable in automated environments (CI). You can use the [Cadence testing utils](https://cadence-lang.org/docs/testing-framework) to create tests for your smart contract code. - -### Stress Testing Live Applications Before Mainnet - -Once you deployed your application to the testnet, you should record how your application handles non-trivial amounts of traffic to ensure there are no issues. - - -Get familiar with the [Cadence anti-patterns](https://cadence-lang.org/docs/anti-patterns) to avoid avoid problematic or unintended behavior. - +### Fork testing (overview) +For running tests against a fork of mainnet/testnet, see the dedicated tutorial: [Fork Testing with Cadence (Step-by-Step)]. For available flags, see [Fork Testing Flags]. To interactively explore a forked state outside the test framework, see [Flow Emulator]. For when to use forks vs emulator, see [Testing Strategy on Flow]. ## References -- [Reference documentation for Cadence testing](https://cadence-lang.org/docs/testing-framework) -- [Overflow](https://github.com/bjartek/overflow) is a powerful Golang-based DSL for efficient testing and execution of blockchain interactions -- projects that have good examples of robust test cases: - - [hybrid-custody](https://github.com/onflow/hybrid-custody/tree/main/test), - - [flow-nft](https://github.com/onflow/flow-nft/tree/master/tests), - - [flow-ft](https://github.com/onflow/flow-ft/tree/master/tests). +- [Cadence documentation] for testing. +- [Overflow tool] is a powerful Golang-based DSL for efficient testing and execution of blockchain interactions +- Projects that have good examples of robust test cases: + - [hybrid-custody] + - [flow-nft] + - [flow-ft] + + +[Testing Strategy on Flow]: ./testing-strategy.md +[Flow CLI]: ../../../build/tools/flow-cli/index.md +[installation instructions]: ../../../build/tools/flow-cli/install.md +[project's configuration]: ../../../build/tools/flow-cli/flow.json/configuration.md +[Flow CLI documentation]: ../../../build/tools/flow-cli/index.md +[Network Upgrade (Spork) Process]: ../../../protocol/node-ops/node-operation/network-upgrade.md +[Fork Testing Flags]: ../../tools/flow-cli/tests.md#fork-testing-flags +[Flow Emulator]: ../../tools/emulator/index.md +[Fork Testing with Cadence (Step-by-Step)]: ../../../blockchain-development-tutorials/cadence/fork-testing/index.md +[**Code Coverage**]: https://github.com/m-Peter/flow-code-coverage +[**Assertions**]: https://cadence-lang.org/docs/testing-framework#assertions +[**Integration tests**]: https://github.com/bjartek/overflow +[Overflow tool]: https://github.com/bjartek/overflow +[Cadence language documentation]: https://cadence-lang.org/ +[hybrid-custody]: https://github.com/onflow/hybrid-custody/tree/main/test +[flow-nft]: https://github.com/onflow/flow-nft/tree/master/tests +[flow-ft]: https://github.com/onflow/flow-ft/tree/master/tests +[Cadence documentation]: https://cadence-lang.org/docs/testing-framework +[Hybrid Custody]: https://github.com/onflow/hybrid-custody#readme +[repository]: https://github.com/m-Peter/flow-code-coverage#readme \ No newline at end of file diff --git a/docs/build/core-contracts/07-epoch-contract-reference.md b/docs/build/core-contracts/07-epoch-contract-reference.md deleted file mode 100644 index fe134da88f..0000000000 --- a/docs/build/core-contracts/07-epoch-contract-reference.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: Flow Epoch Contracts Reference -sidebar_position: 7 -sidebar_label: Epoch Contracts -description: Learn about Flow's epoch-related contracts that manage network phases, quorum certificates, and distributed key generation. Understand how FlowEpoch, FlowClusterQC, and FlowDKG contracts work together. -keywords: - - epoch contracts - - FlowEpoch - - FlowClusterQC - - FlowDKG - - epoch phases - - quorum certificates - - distributed key generation - - epoch metadata - - epoch counter - - epoch scripts - - QC voting - - DKG participants - - network phases - - Flow protocol - - epoch management ---- - -# Contract - -The `FlowEpoch` contract is the state machine that manages Epoch phases and emits service events. -The `FlowClusterQC` and `FlowDKG` contracts manage the processes that happen during the Epoch Setup phase. - -These contracts are all deployed to the same account as the `FlowIDTableStaking` contract. - -Sources: - -- [FlowEpoch.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/epochs/FlowEpoch.cdc) -- [FlowClusterQC.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/epochs/FlowClusterQC.cdc) -- [FlowDKG.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/epochs/FlowDKG.cdc) - -| Network | Contract Address | -| ------------------------- | -------------------- | -| Emulator | `0xf8d6e0586b0a20c7` | -| Cadence Testing Framework | `0x0000000000000001` | -| Testnet | `0x9eca2b38b18b5dfe` | -| Mainnet | `0x8624b52f9ddcd04a` | - -# Transactions - -## Getting Epoch Info - -These scripts are read-only and get info about the current state of the epoch contract. - -| ID | Name | Source | -| ----------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| **`EP.01`** | Get Epoch Metadata | [epoch/get_epoch_metadata.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/epoch/scripts/get_epoch_metadata.cdc) | -| **`EP.02`** | Get Configurable Metadata | [epoch/get_config_metadata.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/epoch/scripts/get_config_metadata.cdc) | -| **`EP.03`** | Get Epoch Counter | [epoch/get_epoch_counter.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/epoch/scripts/get_epoch_counter.cdc) | -| **`EP.04`** | Get Epoch Phase | [epoch/get_epoch_phase.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/epoch/scripts/get_epoch_phase.cdc) | - -## Quorum Certificate Transactions and Scripts - -| ID | Name | Source | -| ----------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`QC.01`** | Create QC Voter | [quorumCertificate/get_epoch_metadata.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/create_voter.cdc) | -| **`QC.02`** | Submit QC Vote | [quorumCertificate/get_config_metadata.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/submit_vote.cdc) | -| **`QC.03`** | Get Collector Cluster | [quorumCertificate/scripts/get_cluster.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/scripts/get_cluster.cdc) | -| **`QC.04`** | Get QC Enabled | [quorumCertificate/scripts/get_qc_enabled.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/scripts/get_qc_enabled.cdc) | -| **`QC.05`** | Get Node Has Voted | [quorumCertificate/scripts/get_node_has_voted.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/scripts/get_node_has_voted.cdc) | -| **`QC.06`** | Get QC Voting Complete | [quorumCertificate/scripts/get_voting_completed.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/quorumCertificate/scripts/get_voting_completed.cdc) | - -## DKG Transactions and Scripts - -| ID | Name | Source | -| ------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`DKG.01`** | Create DKG Participant | [dkg/create_participant.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/create_participant.cdc) | -| **`DKG.02`** | Get Configurable Metadata | [dkg/send_whiteboard_message.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/send_whiteboard_message.cdc) | -| **`DKG.03`** | Send Final Submission | [dkg/send_final_submission.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/send_final_submission.cdc) | -| **`DKG.04`** | Get DKG Enabled | [dkg/scripts/get_dkg_enabled.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/scripts/get_dkg_enabled.cdc) | -| **`DKG.05`** | Get DKG Completed | [dkg/scripts/get_dkg_completed.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/scripts/get_dkg_completed.cdc) | -| **`DKG.06`** | Get Whiteboard Messages | [dkg/scripts/get_whiteboard_messages.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/scripts/get_whiteboard_messages.cdc) | -| **`DKG.07`** | Get Final Submissions | [dkg/scripts/get_final_submissions.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/scripts/get_final_submissions.cdc) | -| **`DKG.08`** | Get Node Has Submitted | [dkg/scripts/get_node_has_submitted.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/dkg/scripts/get_node_has_submitted.cdc) | - -# Events - -See the [epoch documentation](../../networks/staking/05-epoch-scripts-events.md) -for a list and documentation for important `FlowEpoch` events. diff --git a/docs/build/core-contracts/11-staking-collection.md b/docs/build/core-contracts/11-staking-collection.md deleted file mode 100644 index 9728d6520f..0000000000 --- a/docs/build/core-contracts/11-staking-collection.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Flow Staking Collection Contract Reference -sidebar_position: 11 -sidebar_label: Staking Collection -description: Learn about Flow's Staking Collection contract that manages user stake and delegation resources. Understand how to interact with nodes, delegators, and locked tokens through the collection interface. -keywords: - - staking collection - - Flow staking - - node management - - delegation - - locked tokens - - machine accounts - - staking operations - - node registration - - delegator registration - - stake management - - token delegation - - staking interface - - Flow protocol - - staking transactions - - collection events ---- - -# Contract - -The `FlowStakingCollection` contract is a contract that manages a resource containing a user's stake and delegation objects. - -The `FlowStakingCollection` allows a user to manage multiple active nodes or delegators -and interact with node or delegator objects stored in either their optional locked account -or in the StakingCollection itself (stored in the main account). -If a user has locked tokens, StakingCollection allows a user to interact with their locked tokens -to perform staking actions for any of their nodes or delegators. - -The staking collection also manages creating a node's machine accounts if they have any collector or consensus nodes. -It also allows them to deposit and withdraw tokens from any of their machine accounts through the staking collection. - -See the [Staking Collection Docs](../../networks/staking/14-staking-collection.md) for more information on the design of the staking collection contract. - -Source: [FlowStakingCollection.cdc](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowStakingCollection.cdc) - -| Network | Contract Address | -| ------------------------- | -------------------- | -| Emulator | `0xf8d6e0586b0a20c7` | -| Cadence Testing Framework | `0x0000000000000001` | -| Testnet | `0x95e019a17d0e23d7` | -| Mainnet | `0x8d0e87b65159ae63` | - -## Transactions - -Use the following transactions to interact with the StakingCollection. - -\_Note: The StakingCollection differentiates between stake and delegation requests through -passing an optional DelegatorID argument. For example, if you wish to Stake New Tokens for an active node, -pass `nil` as the optional DelegatorID argument to the Stake New Tokens transaction. -The same applies for all the other staking operation transactions. - -| ID | Name | Source | -| ------------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`SCO.01`** | Setup Staking Collection | [stakingCollection/setup_staking_collection.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/setup_staking_collection.cdc) | -| **`SCO.02`** | Register Delegator | [stakingCollection/register_delegator.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/register_delegator.cdc) | -| **`SCO.03`** | Register Node | [stakingCollection/register_node.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/register_node.cdc) | -| **`SCO.04`** | Create Machine Account | [stakingCollection/create_machine_account.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/create_machine_account.cdc) | -| **`SCO.05`** | Request Unstaking | [stakingCollection/request_unstaking.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/request_unstaking.cdc) | -| **`SCO.06`** | Stake New Tokens | [stakingCollection/stake_new_tokens.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/stake_new_tokens.cdc) | -| **`SCO.07`** | Stake Rewarded Tokens | [stakingCollection/stake_rewarded_tokens.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/stake_rewarded_tokens.cdc) | -| **`SCO.08`** | Stake Unstaked Tokens | [stakingCollection/stake_unstaked_tokens.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/stake_unstaked_tokens.cdc) | -| **`SCO.09`** | Unstake All | [stakingCollection/unstake_all.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/unstake_all.cdc) | -| **`SCO.10`** | Withdraw Rewarded Tokens | [stakingCollection/withdraw_rewarded_tokens.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/withdraw_rewarded_tokens.cdc) | -| **`SCO.11`** | Withdraw Unstaked Tokens | [stakingCollection/withdraw_unstaked_tokens.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/withdraw_unstaked_tokens.cdc) | -| **`SCO.12`** | Close Stake | [stakingCollection/close_stake.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/close_stake.cdc) | -| **`SCO.13`** | Transfer Node | [stakingCollection/transfer_node.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/transfer_node.cdc) | -| **`SCO.14`** | Transfer Delegator | [stakingCollection/transfer_delegator.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/transfer_delegator.cdc) | -| **`SCO.15`** | Withdraw From Machine Account | [stakingCollection/withdraw_from_machine_account.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/withdraw_from_machine_account.cdc) | -| **`SCO.22`** | Update Networking Address | [stakingCollection/update_networking_address.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/update_networking_address.cdc) | - -## Scripts - -| ID | Name | Source | -| ------------ | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`SCO.16`** | Get All Delegator Info | [stakingCollection/scripts/get_all_delegator_info.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_all_delegator_info.cdc) | -| **`SCO.15`** | Get All Node Info | [stakingCollection/scripts/get_all_node_info.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_all_node_info.cdc) | -| **`SCO.22`** | Get Delegator Ids | [stakingCollection/scripts/get_delegator_ids.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_delegator_ids.cdc) | -| **`SCO.17`** | Get Node Ids | [stakingCollection/scripts/get_node_ids.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_node_ids.cdc) | -| **`SCO.18`** | Get Does Stake Exist | [stakingCollection/scripts/get_does_stake_exist.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_does_stake_exist.cdc) | -| **`SCO.19`** | Get Locked Tokens Used | [stakingCollection/scripts/get_locked_tokens_used.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_locked_tokens_used.cdc) | -| **`SCO.20`** | Get Unlocked Tokens Used | [stakingCollection/scripts/get_unlocked_tokens_used.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_unlocked_tokens_used.cdc) | -| **`SCO.21`** | Get Machine Accounts | [stakingCollection/scripts/get_machine_accounts.cdc](https://github.com/onflow/flow-core-contracts/blob/master/transactions/stakingCollection/scripts/get_machine_accounts.cdc) | - -## Setup Transaction - -To setup the Staking Collection for an account, use the `SC.01` transaction. - -The setup process finds any node or delegator records already stored in the main account's storage, -as well as any in the associated locked account if an associated locked account exists. -It connects these node and delegator records with the new Staking Collection, allowing them -to be interacted with using the Staking Collection API. - -## Events - -The `StakingCollection` contract emits an event whenever an important action occurs. - -```cadence - access(all) event NodeAddedToStakingCollection(nodeID: String, role: UInt8, amountCommitted: UFix64, address: Address?) - access(all) event DelegatorAddedToStakingCollection(nodeID: String, delegatorID: UInt32, amountCommitted: UFix64, address: Address?) - - access(all) event NodeRemovedFromStakingCollection(nodeID: String, role: UInt8, address: Address?) - access(all) event DelegatorRemovedFromStakingCollection(nodeID: String, delegatorID: UInt32, address: Address?) - - access(all) event MachineAccountCreated(nodeID: String, role: UInt8, address: Address) -``` diff --git a/docs/build/core-contracts/15-bridge.md b/docs/build/core-contracts/15-bridge.md deleted file mode 100644 index 9058f7d18b..0000000000 --- a/docs/build/core-contracts/15-bridge.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: VM Bridge Contracts -sidebar_position: 15 -sidebar_label: VM Bridge -description: Learn about Flow's bridge contracts that manage bridging tokens between the Cadence and EVM environments. -keywords: - - core contracts - - transaction fees - - EVM - - bridge - - fungible tokens - - non fungible tokens - - nft ---- - -The Flow VM bridge is the account and series of smart contracts that manage how -assets are safely bridged between the Cadence and EVM Flow Environments. - -| Network | Contract Address | -| ------------------------- | -------------------- | -| Emulator | `0xf8d6e0586b0a20c7` | -| Cadence Testing Framework | `0x0000000000000001` | -| Testnet | `0xdfc20aee650fcbdf` | -| Mainnet | `0x1e4aa0b87d10b141` | - -# Contracts - -There are many important contracts deployed to the bridge account. -You should refer to [the bridge repo](https://github.com/onflow/flow-evm-bridge) -and [the bridge guides](../../tutorials/cross-vm-apps/vm-bridge.md) -for more detailed information about the bridge and tutorials for how to use the bridge properly. - -Here is a list of each Cadence contract used for the bridge: - -| Contract | Purpose | -| ------------------------------------- | --------------------------------------------------------------------------------------------------------- | -| `CrossVMNFT` | Contract defining cross-VM NFT-related interfaces | -| `CrossVMToken` | Contract defining cross-VM Fungible Token Vault interface | -| `FlowEVMBridgeHandlerInterfaces` | Defines interface for custom bridged token handlers | -| `IBridgePermissions` | Defines an interface to prevent bridging for a specific token | -| `ICrossVM` | Defines an interface to get EVM contract addresses | -| `ICrossVMAsset` | Defines an interface to represent a Cadence bridged version of an EVM asset | -| `IEVMBridgeNFTMinter` | Defines an interface that allows the bridge to mint NFTs | -| `IEVMBridgeTokenMinter` | Defines an interface that allows the bridge to mint FTs | -| `IFlowEVMNFTBridge` | Defines core methods for bridging NFTs | -| `IFlowEVMTokenBridge` | Defines core methods for bridging FTs | -| `FlowEVMBridge` | The main entrypoint for briding tokens across Flow VMs | -| `FlowEVMBridgeAccessor` | Defines methods to route bridge requests from the EVM contract to the Flow-EVM bridge contract | -| `FlowEVMBridgeConfig` | Used to store configuration options for the VM Bridge | -| `FlowEVMBridgeCustomAssociations` | Stores configuration information about custom bridged asset configurations | -| `FlowEVMBridgeCustomAssociationTypes` | Defines interfaces used to specify custom bridged asset associations | -| `FlowEVMBridgeHandlers` | Defines mechanisms for handling assets with custom associations (Deprecated) | -| `FlowEVMBridgeNFTEscrow` | Handles locking of NFTs that are bridged from Flow to EVM and back | -| `FlowEVMBridgeResolver` | Defines methods to resolve Metadata Views for bridged assets | -| `FlowEVMBridgeTemplates` | Serves Cadence code from chunked templates for bridge-deployed assets | -| `FlowEVMBridgeTokenEscrow` | Handles locking of FTs that are bridged from Flow to EVM and back | -| `FlowEVMBridgeUtils` | Defines many different utility methods that are used by bridge contracts | -| `ArrayUtils` | Provides useful utility functions for manipulating arrays | -| `ScopedFTProviders` | Provides utilities for creating provider capabilities for tokens that are restricted to a specific amount | -| `Serialize` | Provides utilities for serializing common types to json-compatible strings | -| `SerializeMetadata` | Provides methods for serializing NFT metadata as a JSON compatible string | -| `StringUtils` | Provides useful utility functions for manipulating strings | - -# EVM Bridge Solidity Contracts - -There are also Solidity contracts that are deployed in Flow EVM that are needed for the bridge. -Here are their addresses: - -| Contracts | Testnet | Mainnet | -| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -| `FlowEVMBridgeFactory.sol` | [`0xf8146b4aef631853f0eb98dbe28706d029e52c52`](https://evm-testnet.flowscan.io/address/0xF8146B4aEF631853F0eB98DBE28706d029e52c52) | [`0x1c6dea788ee774cf15bcd3d7a07ede892ef0be40`](https://evm.flowscan.io/address/0x1C6dEa788Ee774CF15bCd3d7A07ede892ef0bE40) | -| `FlowEVMBridgeDeploymentRegistry.sol` | [`0x8781d15904d7e161f421400571dea24cc0db6938`](https://evm-testnet.flowscan.io/address/0x8781d15904d7e161f421400571dea24cc0db6938) | [`0x8fdec2058535a2cb25c2f8cec65e8e0d0691f7b0`](https://evm.flowscan.io/address/0x8FDEc2058535A2Cb25C2f8ceC65e8e0D0691f7B0) | -| `FlowEVMBridgedERC20Deployer.sol` | [`0x4d45CaD104A71D19991DE3489ddC5C7B284cf263`](https://evm-testnet.flowscan.io/address/0x4d45CaD104A71D19991DE3489ddC5C7B284cf263) | [`0x49631Eac7e67c417D036a4d114AD9359c93491e7`](https://evm.flowscan.io/address/0x49631Eac7e67c417D036a4d114AD9359c93491e7) | -| `FlowEVMBridgedERC721Deployer.sol` | [`0x1B852d242F9c4C4E9Bb91115276f659D1D1f7c56`](https://evm-testnet.flowscan.io/address/0x1B852d242F9c4C4E9Bb91115276f659D1D1f7c56) | [`0xe7c2B80a9de81340AE375B3a53940E9aeEAd79Df`](https://evm.flowscan.io/address/0xe7c2B80a9de81340AE375B3a53940E9aeEAd79Df) | - -And below are the bridge escrow's EVM addresses. These addresses are [`CadenceOwnedAccount`s (COA)](https://developers.flow.com/tutorials/cross-vm-apps/interacting-with-coa#coa-interface) and they are stored stored in the same Flow account as you'll find the Cadence contracts (see above). - -| Network | Address | -| ------- | ---------------------------------------------------------------------------------------------------------------------------------- | -| Testnet | [`0x0000000000000000000000023f946ffbc8829bfd`](https://evm-testnet.flowscan.io/address/0x0000000000000000000000023f946FFbc8829BFD) | -| Mainnet | [`0x00000000000000000000000249250a5c27ecab3b`](https://evm.flowscan.io/address/0x00000000000000000000000249250a5C27Ecab3B) | diff --git a/docs/build/differences-vs-evm/_category_.yml b/docs/build/differences-vs-evm/_category_.yml deleted file mode 100644 index 71b6ec9c24..0000000000 --- a/docs/build/differences-vs-evm/_category_.yml +++ /dev/null @@ -1 +0,0 @@ -position: 3 \ No newline at end of file diff --git a/docs/build/evm/_category_.yml b/docs/build/evm/_category_.yml new file mode 100644 index 0000000000..f922aa8ff3 --- /dev/null +++ b/docs/build/evm/_category_.yml @@ -0,0 +1,3 @@ +label: Solidity (EVM) +position: 3 +collapsed: false diff --git a/docs/evm/accounts.md b/docs/build/evm/accounts.md similarity index 95% rename from docs/evm/accounts.md rename to docs/build/evm/accounts.md index 5b1ad4455a..cb6ff52253 100644 --- a/docs/evm/accounts.md +++ b/docs/build/evm/accounts.md @@ -6,7 +6,7 @@ sidebar_position: 7 :::info -Are you a Cadence developer looking for information about Accounts on Cadence? If so, check out the Cadence specific documentation [here](../build/basics/accounts.md) +Are you a Cadence developer looking for information about Accounts on Cadence? If so, check out the Cadence specific documentation [here](../cadence/basics/accounts.md) ::: @@ -48,7 +48,7 @@ COAs create powerful new opportunities to improve the UX, functionality and util - **Atomic Interactions**: Developers are able to execute multiple EVM transactions atomically from a COA. This is particularly useful for applications that require multiple transactions to be executed within a single block, or require all prior transactions' state changes to revert if a single transaction in the batch fails. This is not possible natively using EOAs or with `UserOperations` when using the ERC-4337 standard; in both cases each individual transaction is distinct and cannot be reverted back once state has changed. -- **Native Account Abstraction**: COAs are controlled by Cadence resources, which are in turn owned by Flow accounts. [Flow accounts](./accounts.md) have built-in support for multi-signature authentication, key rotation, and account recovery. As a Cadence resource, COAs naturally inherit [these features](../build/advanced-concepts/account-abstraction.md). +- **Native Account Abstraction**: COAs are controlled by Cadence resources, which are in turn owned by Flow accounts. [Flow accounts](./accounts.md) have built-in support for multi-signature authentication, key rotation, and account recovery. As a Cadence resource, COAs naturally inherit [these features](../cadence/advanced-concepts/account-abstraction.md). - **Fine-Grained Access Control**: As Cadence resources, access to a COA can be governed by more sophisticated policies than those available with basic EVM accounts. By utilizing powerful Cadence access control primitives such as [capabilities and entitlements](https://cadence-lang.org/docs/language/access-control), developers can restrict who is able to interact with a COA and what actions they are permitted to perform. @@ -64,6 +64,6 @@ Because COAs are owned by Cadence resources, an EVM transaction is not required ### More Information -To learn how to create and interact with COAs in Cadence, see the guide for [Interacting with COAs from Cadence](../tutorials/cross-vm-apps/interacting-with-coa.md). +To learn how to create and interact with COAs in Cadence, see the guide for [Interacting with COAs from Cadence](../../blockchain-development-tutorials/cross-vm-apps/interacting-with-coa.md). For more information about Cadence Owned Accounts, see the [Flow EVM Support FLIP](https://github.com/onflow/flips/pull/225/files) diff --git a/docs/build/evm/fees.md b/docs/build/evm/fees.md new file mode 100644 index 0000000000..b68c8bef6f --- /dev/null +++ b/docs/build/evm/fees.md @@ -0,0 +1,209 @@ +--- +title: Fees +sidebar_label: Fees +sidebar_position: 6 +--- + +:::info + +Are you a Cadence developer looking for information about Fees on Cadence? If so, check out the Cadence specific documentation [here](../cadence/basics/fees.md) + +::: + +EVM transactions are ultra low-cost and use the native FLOW token as gas. [Externally Owned Accounts (EOAs)](./accounts.md) function the same on Flow as other EVM networks like Ethereum. + +
+

How Transaction Fees are Computed on EVM

+ +With Flow EVM, EVM operations can now be called within Cadence transactions. EVM operations also have an associated effort measured in gas which needs to be factored into the execution effort calculation in addition to the Flow computation for any EVM transaction. + +``` +Transaction fee on EVM = surge x [inclusion fee + (execution effort * unit cost)] +``` + +- `Surge' factor` dynamically accounts for network pressure and market conditions. +- `Inclusion fee` accounts for the resources required to process a transaction due to its core properties (byte size, signatures). This is currently constant at 1E-4 FLOW, but subject to change with community approval. +- `Execution fee` The fee that accounts for the operational cost of running the transaction script, processing the results, sending results for verification, generating verification receipts, etc. and is calculated as a product of `computation units` and the `cost per unit`. + - `Execution Effort (measured in computation units)` is based on transaction type and operations that are called during the execution of a transaction. The weights determine how costly (time-consuming) each operation is. + - `Execution Effort Unit Cost` = `4E-05 FLOW` (currently constant, but subject to change with community approval) + +

Calculation of Execution Effort

+ +``` +Execution Effort (computation) = + 3.271E+01 * create_account + + 2.348E+01 * blsverify_pop + + 7.408E+00 * get_account_balance + + 6.145E+00 * blsaggregate_public_keys + + 6.059E+00 * get_storage_capacity + + 5.726E+00 * get_account_available_balance + + 5.637E+00 * update_account_contract_code + + 4.964E+00 * blsaggregate_signatures + + 1.152E+00 * generate_account_local_id + + 5.000E-01 * get_account_contract_names + + 3.878E-01 * get_storage_used + + 3.770E-01 * account_keys_count + + 2.346E-01 * allocate_slab_index + + 1.348E-01 * atree_map_get + + 1.125E-01 * atree_map_remove + + 6.659E-02 * create_array_value + + 5.826E-02 * create_dictionary_value + + 5.579E-02 * atree_map_set + + 5.573E-02 * atree_array_insert + + 5.074E-02 * atree_map_read_iteration + + 4.442E-02 * encode_event + + 3.598E-02 * transfer_composite_value + + 2.910E-02 * atree_array_append + + 2.701E-02 * statement + + 2.650E-02 * atree_array_set + + 2.135E-02 * function_invocation + + 1.846E-02 * atree_map_pop_iteration + + 1.123E-02 * atree_array_pop_iteration + + 7.874E-03 * rlpdecoding + + 4.242E-03 * graphemes_iteration + + 3.922E-03 * ufix_parse + + 3.403E-03 * fix_parse + + 2.731E-03 * loop + + 2.701E-03 * atree_array_batch_construction + + 1.907E-03 * transfer_dictionary_value + + 1.053E-03 * big_int_parse + + 7.324E-04 * transfer_array_value + + 7.324E-04 * set_value + + 4.730E-04 * uint_parse + + 4.272E-04 * int_parse + + 3.510E-04 * get_value + + 7.629E-05 * string_to_lower + + 4.578E-05 * evmgas_usage +``` + +where + +``` +`evmgas_usage` is reported by EVM as the cost in gas for executing the transaction within the EVM, for instance, 21K gas for a simple send transaction. +``` + +
+ +
+

Demonstration of Transaction Fees on EVM

+ +Assume a simple Token transfer transaction: + +**Scenario 1 - Cadence-only Transaction** + +The token transfer transaction: + +- makes 76 atree_map_get calls, +- reads 9431 bytes (get_value), +- sets 2448 bytes (set_value), +- invokes 55 cadence statements, +- makes 2 get_storage_used calls, +- makes 28 cadence function_invocation calls, +- makes 8 transfer_composite_value calls, +- makes 5 atree_map_set calls, +- makes 4 encode_event calls, +- makes 2 create_array_value calls, +- makes 2 atree_array_append calls, +- makes 4 atree_array_batch_construction calls, +- makes 2 loop calls, +- makes 2 transfer_array_value calls + + +``` +Compute Units = + 76 * 0.135 + + 9431 * 0.000 + + 2448 * 0.001 + + 55 * 0.027 + + 2 * 0.388 + + 28 * 0.021 + + 8 * 0.036 + + 5 * 0.056 + + 4 * 0.044 + + 2 * 0.067 + + 2 * 0.029 + + 4 * 0.003 + + 2 * 0.003 + + 2 * 0.001 +``` + +But since `EVMGasUsage` is 0 for a Cadence transaction, + +``` +Compute Units = 19.2 +``` + +Thus + +``` +Transaction fee = [1E-4 FLOW + (19.2 * 4E-05 FLOW)] x 1 = 8.68E-04 +``` + +**Scenario 2 - EVM Transaction** +If the EVMGasUsage can be assumed to be 21,000 gas (typical for a simple transfer): + +- uses 377806 evm gas (evmgas_usage), +- reads 22840 bytes (get_value), +- makes 1676 atree_array_batch_construction calls, +- makes 30 atree_map_get calls, +- makes 325 atree_array_pop_iteration calls, +- sets 3182 bytes (set_value), +- makes 273 rlpdecoding calls, +- makes 20 atree_map_read_iteration calls, +- makes 1329 transfer_array_value calls, +- invokes 25 cadence statements, +- makes 12 atree_map_set calls, +- makes 17 transfer_composite_value calls, +- makes 8 create_array_value calls, +- makes 19 function_invocation calls, +- makes 1 get_storage_used calls, +- makes 87 graphemes_iteration calls, +- makes 2 encode_event calls, +- makes 2 atree_array_append calls, +- makes 1 atree_map_pop_iteration calls, +- makes 2 loop calls, +- makes 40 string_to_lower calls + + +``` +Compute Units = + 377806 * 0.00005 + + 22840 * 0.00035 + + 1676 * 0.00270 + + 30 * 0.13484 + + 325 * 0.01123 + + 3182 * 0.00073 + + 273 * 0.00787 + + 20 * 0.05074 + + 1329 * 0.00073 + + 25 * 0.02701 + + 12 * 0.05579 + + 17 * 0.03598 + + 8 * 0.06659 + + 19 * 0.02135 + + 1 * 0.38782 + + 87 * 0.00424 + + 2 * 0.04442 + + 2 * 0.02910 + + 1 * 0.01846 + + 2 * 0.00273 + + 40 * 0.00008 + = 47.8 + +``` + +Thus + +``` +Transaction fee = [1E-4 FLOW + (47.8 * 4E-05 FLOW)] x 1 = 2.012E-03 FLOW +``` + +**Note**: Please be aware that this example serves solely for illustrative purposes to elucidate the calculations. Actual transaction fees may differ due to various factors, including the byte size of the transaction. + +
+ +## Gasless Transactions + +Fees needed to execute transactions on a Web3 app are often a major challenge for new users and can be a barrier to adoption. Builders can easily extend their apps with Cadence to create ‘gasless’ experiences by specifying their app as the [sponsor](../cadence/advanced-concepts/account-abstraction.md#sponsored-transactions) instead of the user. + +To learn more about storage fee and transaction fee, visit [Flow Tokenomics page](https://flow.com/flow-tokenomics/technical-overview). diff --git a/docs/evm/flow-evm-account-model.png b/docs/build/evm/flow-evm-account-model.png similarity index 100% rename from docs/evm/flow-evm-account-model.png rename to docs/build/evm/flow-evm-account-model.png diff --git a/docs/evm/hardhat-init.png b/docs/build/evm/hardhat-init.png similarity index 100% rename from docs/evm/hardhat-init.png rename to docs/build/evm/hardhat-init.png diff --git a/docs/evm/how-it-works.md b/docs/build/evm/how-it-works.md similarity index 90% rename from docs/evm/how-it-works.md rename to docs/build/evm/how-it-works.md index 2e0751583d..5ab153ed57 100644 --- a/docs/evm/how-it-works.md +++ b/docs/build/evm/how-it-works.md @@ -16,11 +16,23 @@ Flow EVM is designed with these major goals in mind: - Minimizing breaking changes to the Cadence ecosystem, software and tools - Maximum composability across environments: Allowing atomic and smooth interaction between EVM and Cadence environments. +
+ +
+ ### EVM - A Smart Contract In Cadence To satisfy the design goals and thanks to the extensibility properties of the Cadence runtime, Flow EVM is designed as a higher-level environment incorporated as a smart contract deployed to Cadence. This smart contract is not owned by anyone and has its own storage space, allows Cadence to query, and is updated through EVM transactions. EVM transactions can be wrapped inside Cadence transactions and passed to the EVM contract for execution. The artifacts of EVM transaction execution (e.g. receipts and logs) are emitted as special Cadence events (TransactionExecuted, BlockExecuted) and available to the upstream process (Flow transaction) to enable atomic operations. -The EVM environment has its own concept of blocks, and every Flow block includes at most one EVM Block. The EVM block is formed at the end of Flow Block execution and includes all the transaction executed during the EVM block execution. Note that since EVM blocks are formed on-chain and Flow provides fast finality, as long as the user of these events waits for Flow block finality, it doesn’t have to worry about EVM block forks, uncle chains, and other consensus-related challenges. +The EVM environment has its own concept of blocks, and every Flow block includes at most one EVM Block. The EVM block is formed at the end of Flow Block execution and includes all the transaction executed during the EVM block execution. Note that since EVM blocks are formed onchain and Flow provides fast finality, as long as the user of these events waits for Flow block finality, it doesn’t have to worry about EVM block forks, uncle chains, and other consensus-related challenges. ### No Shared Memory Design @@ -91,8 +103,8 @@ Functions currently available on the Cadence Arch smart contract are: - `FlowBlockHeight() uint64` (signature: `0x53e87d66`) returns the current Flow block height, this could be used instead of Flow EVM block heights to trigger scheduled actions given it's more predictable when a block might be formed. - `VerifyCOAOwnershipProof(bytes32 _hash, bytes memory _signature)(bool success)` returns true if the proof is valid. An ownership proof verifies that a Flow wallet controls a COA account (see the next section for more details on COA). -- `revertibleRandom() uint64` returns a safe pseudo-random value that is produced by the Flow VRF (using Flow internal randomness beacon). The function invokes Cadence's `revertibleRandom` described [here](https://developers.flow.com/build/advanced-concepts/randomness). Although the random value is safe, a transaction may revert its results in the case of an unfavourable outcome. The function should only be used by trusted calls where there is no issue with reverting the results. `getRandomSource` must be used instead with untrusted calls. -- `getRandomSource(uint64) bytes32` should be used when implementing a [commit-reveal](https://developers.flow.com/build/advanced-concepts/randomness#commit-reveal-scheme) scheme. It returns a secure random source from the Cadence randomness history contract. Learn more about the secure usage of randomness on Flow [here](https://developers.flow.com/build/advanced-concepts/randomness). +- `revertibleRandom() uint64` returns a safe pseudo-random value that is produced by the Flow VRF (using Flow internal randomness beacon). The function invokes Cadence's `revertibleRandom` described [here](https://developers.flow.com/build/cadence/advanced-concepts/randomness). Although the random value is safe, a transaction may revert its results in the case of an unfavourable outcome. The function should only be used by trusted calls where there is no issue with reverting the results. `getRandomSource` must be used instead with untrusted calls. +- `getRandomSource(uint64) bytes32` should be used when implementing a [commit-reveal](https://developers.flow.com/build/cadence/advanced-concepts/randomness#commit-reveal-scheme) scheme. It returns a secure random source from the Cadence randomness history contract. Learn more about the secure usage of randomness on Flow [here](https://developers.flow.com/build/cadence/advanced-concepts/randomness). Here is a sample demonstrating how to call the Cadence Arch. @@ -122,7 +134,7 @@ These smart contract wallets are only deployable through the Cadence environment A COA is not controlled by a key. Instead, every COA account has a unique resource accessible on the Cadence side, and anyone who owns that resource submits transactions on behalf of this address. These direct transactions have COA’s EVM address as the `tx.origin` and a new EVM transaction type (`TxType = 0xff`) is used to differentiate these transactions from other types of EVM transactions (e.g, DynamicFeeTxType (`0x02`). Currently, to make integration and tracking of these transactions byte EVM ecosystem tools, these types of transactions are encoded as legacy EVM transactions (hash computation is based on legacy tx rlp encoding). Controlling through a resource makes a COA a powerful smart contract wallet. It makes the transfer of ownership of the EVM address super easy without the need to transfer all the assets that an EVM address owns. It also allows a Cadence smart contract to take ownership of an EVM address and makes fully decentralized exchange and bridges across environments possible. -To learn more about how to interact with a COA from the Cadence side, [see here](../tutorials/cross-vm-apps/interacting-with-coa.md). +To learn more about how to interact with a COA from the Cadence side, [see here](../../blockchain-development-tutorials/cross-vm-apps/interacting-with-coa.md). ## Proofs diff --git a/docs/build/evm/metamask-network.png b/docs/build/evm/metamask-network.png new file mode 100644 index 0000000000..a49047d9cf Binary files /dev/null and b/docs/build/evm/metamask-network.png differ diff --git a/docs/evm/using.mdx b/docs/build/evm/networks.md similarity index 81% rename from docs/evm/using.mdx rename to docs/build/evm/networks.md index 4def09a92c..c183b9464e 100644 --- a/docs/evm/using.mdx +++ b/docs/build/evm/networks.md @@ -1,71 +1,35 @@ --- -title: Using Flow EVM -sidebar_label: Using Flow EVM -sidebar_position: 4 +title: Network Information +sidebar_label: Network Information +sidebar_position: 5 --- -import BrowserOnly from '@docusaurus/BrowserOnly'; -import { AddNetworkButton } from '@site/src/components/addNetworkButton'; +# Network Information -# Using Flow +Flow EVM has the following public RPC nodes available: -## EVM Wallets - -Applications deployed to Flow EVM will work with popular EVM-compatible wallets such as [MetaMask](https://chromewebstore.google.com/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn), all you need to do is add the correct [RPC endpoint](./networks) as a custom network. - -### [MetaMask](https://metamask.io) - - - {() => { - // ******* If Chain Id changes, update the Chain ID in the AddNetworkButton component ******* - return ; - }} - -Manual method: Add Flow EVM as a custom network to MetaMask: - -1. Open the MetaMask browser extension -2. Open the network selection dropdown menu by clicking the dropdown button at the top of the extension -3. Click the **`Add network`** button -4. Click **`Add a network manually`** -5. In the **`Add a network manually`** dialog that appears, enter the following information: +# Mainnet | Name | Value | | --------------- | ------------------------------------ | | Network Name | Flow EVM Mainnet | -| Description | The public RPC url for Flow Mainnet | +| Description | The public RPC URL for Flow Mainnet | | RPC Endpoint | https://mainnet.evm.nodes.onflow.org | | Chain ID | 747 | | Currency Symbol | FLOW | -| Block Explorer | https://evm.flowscan.io/ | - -6. Tap the Save button to save Flow EVM as a network. - -You should now be able to connect to the Flow EVM by selecting it from the network selection dropdown menu. +| Block Explorer | https://evm.flowscan.io | -To additionally add the Flow EVM Testnet to MetaMask, follow the same steps as above, but use the following information: +# Testnet | Name | Value | | --------------- | ------------------------------------ | | Network Name | Flow EVM Testnet | -| Description | The public RPC url for Flow Testnet | +| Description | The public RPC URL for Flow Testnet | | RPC Endpoint | https://testnet.evm.nodes.onflow.org | | Chain ID | 545 | | Currency Symbol | FLOW | | Block Explorer | https://evm-testnet.flowscan.io | -Use the [Flow Testnet Faucet](https://faucet.flow.com/fund-account) to fund your account for testing. - -## Flow Native Wallets - -### [Flow Wallet](https://wallet.flow.com) - -Flow Wallet is available on [Android](https://play.google.com/store/apps/details?id=com.flowfoundation.wallet) and [iOS](https://apps.apple.com/ca/app/flow-wallet-nfts-and-crypto/id6478996750), with desktop support using the Flow Wallet [Chrome extension](https://chromewebstore.google.com/detail/flow-reference-wallet/hpclkefagolihohboafpheddmmgdffjm). In addition to being able to transact in both EVM and Cadence environments, Flow Wallet will also allow you to view and move assets between EVM and Cadence, making it possible to manage all your assets in one place. - -To use the Flow Wallet Chrome extension: - -1. Open the Flow Wallet browser extension and create your account. -2. Connect to an app using Flow Wallet. - ## EVM Specification - Flow EVM is a virtual EVM-based blockchain using the latest EVM byte-code interpreter `Geth v1.13` diff --git a/docs/evm/quickstart.md b/docs/build/evm/quickstart.md similarity index 54% rename from docs/evm/quickstart.md rename to docs/build/evm/quickstart.md index bfdeb7086a..ed2b4108d5 100644 --- a/docs/evm/quickstart.md +++ b/docs/build/evm/quickstart.md @@ -1,7 +1,7 @@ --- title: EVM Quickstart description: Deploy your first contract on Flow testnet and connect it to a rainbowkit/wagmi/viem app -sidebar_position: 5 +sidebar_position: 1 keywords: - Flow EVM - EVM quickstart @@ -17,12 +17,41 @@ keywords: # EVM Quickstart -Flow EVM is an EVM-equivalent blockchain that combines the advantages of Flow, including security, low-cost gas, and native VRF with compatibility with exiting blockchain applications tools, and contracts. If it works on another EVM-equivalent blockchain, it should work on Flow EVM! +Flow EVM is an EVM-equivalent blockchain that combines the advantages of Flow, including security, low-cost gas, and native VRF with compatibility with existing blockchain applications tools and contracts. If it works on another EVM-equivalent blockchain, it should work on Flow EVM! -This guide is a self-contained quickstart that will walk you through deploying a contract on Flow EVM testnet with [Hardhat] and testing it with [testnet Flowscan]. +This guide is a self-contained quickstart that walks you through deploying a contract on Flow EVM testnet with [Hardhat] and testing it with [testnet Flowscan]. If you prefer, check out our tutorials for [Remix] and [Foundry] for information on how to deploy a contract with those platforms. +To learn more about wallets and configurations, see [this article]. + +## Network information + +Flow EVM has the following public RPC nodes available: + +### Mainnet + +| Name | Value | +| --------------- | ------------------------------------ | +| Network Name | Flow EVM Mainnet | +| Description | The public RPC URL for Flow Mainnet | +| RPC Endpoint | https://mainnet.evm.nodes.onflow.org | +| Chain ID | 747 | +| Currency Symbol | FLOW | +| Block Explorer | https://evm.flowscan.io | + +### Testnet + +| Name | Value | +| --------------- | ------------------------------------ | +| Network Name | Flow EVM Testnet | +| Description | The public RPC URL for Flow Testnet | +| RPC Endpoint | https://testnet.evm.nodes.onflow.org | +| Chain ID | 545 | +| Currency Symbol | FLOW | +| Block Explorer | https://evm-testnet.flowscan.io | + + ## Objectives After completing this guide, you'll be able to: @@ -34,45 +63,55 @@ After completing this guide, you'll be able to: ## Prerequisites -### Traditional Cryptocurrency Wallet +### Traditional cryptocurrency wallet -EVM [Accounts] created by the Flow wallet have unique properties that allow for powerful features, but they do **not** have recovery phrases or private keys that can be exported in a way that's compatible with [Hardhat]. As a result, you'll need to use a traditional EOA and [MetaMask], or the wallet of your choice, to deploy your contracts. +EVM [Accounts] created by the Flow wallet have unique properties that allow for powerful features, but they do **not** have recovery phrases or private keys that can be exported in a way that's compatible with [Hardhat]. As a result, you'll need to use a traditional EOA and [MetaMask] or the wallet of your choice to deploy your contracts. -## Deploy Your Contract +## Deploy your contract For this exercise, we'll use a [Button Clicker Contract] that's relatively simple, but includes several [OpenZeppelin] contracts. This way, we can walk through the process to configure your project to use these common imports. :::info -If you **really** want to speedrun this tutorial, fork the [Button Clicker Contract] repo, run `npm install`, add a `.env` with your deploy wallet key as `DEPLOY_WALLET_1`, and deploy with `npx hardhat ignition deploy ./ignition/modules/ClickToken.ts --network flowTestnet`. +If you **really** want to speedrun this tutorial: + +1. Fork the [Button Clicker Contract] repo. +2. Run `npm install`. +3. Add a `.env` with your deploy wallet key as `DEPLOY_WALLET_1`. +4. Deploy with `npx hardhat ignition deploy ./ignition/modules/ClickToken.ts --network flowTestnet`. -Then skip to the frontend section. +When finished, skip to the frontend section. ::: -### Hardhat Setup +### Hardhat setup -Open a terminal window and navigate either to the folder where you wish to create your project folder, or an empty project folder. Run: +Open a terminal window and navigate either to the folder where you wish to create your project folder or an empty project folder: -```bash -npx hardhat init -``` +1. Run the following command: -![Hardhat Init](hardhat-init.png) + ```bash + npx hardhat init + ``` -Select `Create a TypeScript project (with Viem)` + ![Hardhat Init](hardhat-init.png) -Enter `.` if you ran the command from an empty folder, or enter a path. +2. Select **Create a TypeScript project (with Viem)**. -Choose the defaults for the remaining options, then open the project in your editor. +3. Enter `.` if you ran the command from an empty folder, or enter a path. -### Environment Setup +4. Choose the defaults for the remaining options, then open the project in your editor. -Add a `.env` and in it, add an environment variable called `DEPLOY_WALLET_1` with your deployment wallet's [private key]. +### Environment setup -```text -DEPLOY_WALLET_1= -``` +To set up an environment: + +1. Add a `.env`. +2. Within it, add an environment variable called `DEPLOY_WALLET_1` with your deployment wallet's [private key]: + + ```text + DEPLOY_WALLET_1= + ``` :::danger @@ -80,90 +119,92 @@ The [private key] functions the same as the recovery phrase for a wallet. Anyone ::: -### Hardhat Config - -We'll be using [OpenZeppelin Contracts], so install them, then open the project in your editor: - -```bash -npm install --save-dev @openzeppelin/hardhat-upgrades -npm install --save-dev @nomicfoundation/hardhat-ethers ethers # peer dependencies -``` - -Then install the contracts themselves: +### Hardhat config -```bash -npm install --save-dev @openzeppelin/contracts -``` - -You'll also need `dotenv` to better protect your wallet key, so go ahead and add that too: - -```bash -npm install dotenv -``` +We'll be using [OpenZeppelin Contracts] in the following steps: -Open `hardhat.config`. Below the imports, add the `require` statements for the contracts and `dotenv`: +1. Install them and then open the project in your editor: -```tsx -require('@openzeppelin/hardhat-upgrades'); -require('dotenv').config(); -``` + ```bash + npm install --save-dev @openzeppelin/hardhat-upgrades + npm install --save-dev @nomicfoundation/hardhat-ethers ethers # peer dependencies + ``` -The default config is pretty bare. We'll need to add quite a few items. We'll do these one at a time, then provide a complete copy at the end. +2. Install the contracts themselves: -First, add a `networks` property containing the network information for Flow Testnet and Mainnet: + ```bash + npm install --save-dev @openzeppelin/contracts + ``` -```tsx -networks: { - flow: { - url: 'https://mainnet.evm.nodes.onflow.org', - accounts: [process.env.DEPLOY_WALLET_1 as string], - }, - flowTestnet: { - url: 'https://testnet.evm.nodes.onflow.org', - accounts: [process.env.DEPLOY_WALLET_1 as string], - }, -}, -``` +3. To better protect your wallet key, add `dotenv`: -Then, add an entry for `etherscan`: + ```bash + npm install dotenv + ``` -```tsx -etherscan: { -} -``` +4. Open `hardhat.config`. Below the imports, add the `require` statements for the contracts and `dotenv`: -In it, add a property for `apiKey` and add keys for Flow Mainnet and Testnet. Note that the Etherscan API requires this to be here, but at the time of writing, API keys aren't actually needed. Any text can be used: + ```tsx + require('@openzeppelin/hardhat-upgrades'); + require('dotenv').config(); + ``` -```tsx -apiKey: { - // Is not required by blockscout. Can be any non-empty string - 'flow': "abc", - 'flowTestnet': "abc" -}, -``` + The default config is pretty bare. We'll need to add quite a few items. We'll do these one at a time, then provide a complete copy at the end. -Next, add `customChains` and the network information for Flow: +5. Add a `networks` property containing the network information for Flow Testnet and Mainnet: -```tsx -customChains: [ - { - network: 'flow', - chainId: 747, - urls: { - apiURL: 'https://evm.flowscan.io/api', - browserURL: 'https://evm.flowscan.io/', - }, - }, - { - network: 'flowTestnet', - chainId: 545, - urls: { - apiURL: 'https://evm-testnet.flowscan.io/api', - browserURL: 'https://evm-testnet.flowscan.io/', - }, - }, -]; -``` + ```tsx + networks: { + flow: { + url: 'https://mainnet.evm.nodes.onflow.org', + accounts: [process.env.DEPLOY_WALLET_1 as string], + }, + flowTestnet: { + url: 'https://testnet.evm.nodes.onflow.org', + accounts: [process.env.DEPLOY_WALLET_1 as string], + }, + }, + ``` + +6. Add an entry for `etherscan`: + + ```tsx + etherscan: { + } + ``` + +7. In it, add a property for `apiKey` and add keys for Flow Mainnet and Testnet. Note that the Etherscan API requires this to be here, but at the time of writing, API keys aren't actually needed. Any text can be used: + + ```tsx + apiKey: { + // Is not required by blockscout. Can be any non-empty string + 'flow': "abc", + 'flowTestnet': "abc" + }, + ``` + +8. Add `customChains` and the network information for Flow: + + ```tsx + customChains: [ + { + network: 'flow', + chainId: 747, + urls: { + apiURL: 'https://evm.flowscan.io/api', + browserURL: 'https://evm.flowscan.io/', + }, + }, + { + network: 'flowTestnet', + chainId: 545, + urls: { + apiURL: 'https://evm-testnet.flowscan.io/api', + browserURL: 'https://evm-testnet.flowscan.io/', + }, + }, + ]; + ``` You should end up with: @@ -216,9 +257,13 @@ const config: HardhatUserConfig = { export default config; ``` -### Contract Setup +### Contract setup + +To set up the contract: -Delete `Lock.sol` and add `ClickToken.sol`. In it add, the [Button Clicker Contract]. +1. Delete `Lock.sol`. +2. Add `ClickToken.sol`. +3. Within it, add the [Button Clicker Contract]. :::warning @@ -228,9 +273,13 @@ Hardhat only installs the most current version of Solidity. `^0.8.27` means that We won't go into the details of the contract for this tutorial. It's a relatively simple [ERC-20] implementation that mints one token any time the `mintTo` function is called. Perfect for a Button Clicker game! -### Deployment Setup +### Deployment setup -Delete `Lock.ts` from the `ignition/modules` folder, and add `ClickToken.ts`. In it, add: +To set up the deployment: + +1. Delete `Lock.ts` from the `ignition/modules` folder. +2. Add `ClickToken.ts`. +3. Within it, add the following: ```tsx // This setup uses Hardhat Ignition to manage smart contract deployments. @@ -247,19 +296,19 @@ const ClickerModule = buildModule('ClickTokenModule', (m) => { export default ClickerModule; ``` -### Obtain Testnet Funds +### Obtain testnet funds -Visit the [Flow Faucet] and follow the instructions to add testnet funds. Compared to other networks, the [Flow Faucet] grants a vast amount of tokens - enough gas for millions of transactions. +Visit the [Flow Faucet] and follow the instructions to add testnet funds. Compared to other networks, the [Flow Faucet] grants a vast amount of tokens — enough gas for millions of transactions. :::warning -EVM accounts created by the [Flow Wallet] are [Cadence-Owned Accounts], or COAs - **Not** EOAs. COAs have many advantages over EOAs, but they are generated differently, which means they don't have a key that's compatible with Hardhat. +EVM accounts created by the [Flow Wallet] are [Cadence-Owned Accounts] or COAs — **Not** EOAs. COAs have many advantages over EOAs, but they are generated differently, which means they don't have a key that's compatible with Hardhat. Use your [MetaMask] or similar EOA account to deploy contracts on Flow EVM. ::: -### Deploy the Contract +### Deploy the contract Deploy the contract with: @@ -285,7 +334,7 @@ Deployed Addresses ClickTokenModule#ClickToken - 0x5Ff8221DfDD1F82fd538391D231502B4b927fbD7 ``` -### Verify the Contract +### Verify the contract Next, verify the contract with: @@ -302,17 +351,20 @@ Successfully verified contract "contracts/ClickToken.sol:ClickToken" for network - https://evm-testnet.flowscan.io//address/0x64366c923d5046F8417Dcd8a0Cb4a789F8722387#code ``` -## Testing the Contract +## Testing the contract + +To test the contract: -Click the link to open the contract in [testnet Flowscan]. Click the `Connect` button and connect your wallet, then navigate to the `Contract` tab and `Read/Write contract`. +1. Click the link to open the contract in [testnet Flowscan]. +2. Click the `Connect` button and connect your wallet, then navigate to the **Contract > Read/Write contract** tab: -![read write contract](read-write.png) + ![read write contract](read-write.png) -Find the `mintTo` function and expand the UI to mint yourself a few tokens. You can click the `self` button to automatically add your address without needing to copy/paste. +3. Find the `mintTo` function and expand the UI to mint yourself a few tokens. You can click the `self` button to automatically add your address without needing to copy/paste. -Once you've "earned" a few tokens, use `balanceOf` to see how many tokens you have. You can also use `getAllScores` to get a list of everyone with the tokens, and how many they have. +4. Once you've "earned" a few tokens, use `balanceOf` to see how many tokens you have. You can also use `getAllScores` to get a list of everyone with the tokens, and how many they have. -### Testing with Free Gas +### Testing with free gas If you don't have it yet, set up the [Flow Wallet], connect, and try minting some more tokens. You'll see that the wallet automatically sponsors your gas: @@ -340,14 +392,16 @@ In our [Cross-VM Apps] tutorial series, you'll learn how to supercharge your EVM Ready to unlock the full potential of Flow EVM? Start with our [Batched Transactions] tutorial to learn how to build your first cross-VM application. + + [Cadence]: https://cadence-lang.org/docs [Next.js]: https://nextjs.org/docs/app/getting-started/installation [wagmi]: https://wagmi.sh/ [viem]: https://viem.sh/ [rainbowkit]: https://www.rainbowkit.com/ [Hardhat]: https://hardhat.org/ -[Remix]: ./guides/remix.md -[Foundry]: ./guides/foundry.md +[Remix]: ../../blockchain-development-tutorials/evm/development-tools/remix.md +[Foundry]: ../../blockchain-development-tutorials/evm/development-tools/foundry.md [Flow Faucet]: https://faucet.flow.com/fund-account [Flowscan]: https://evm-testnet.flowscan.io/ [Flow Wallet]: https://wallet.flow.com/ @@ -359,7 +413,8 @@ Ready to unlock the full potential of Flow EVM? Start with our [Batched Transact [private key]: https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/ [ERC-20]: https://ethereum.org/en/developers/docs/standards/tokens/erc-20/ [testnet Flowscan]: https://evm-testnet.flowscan.io/ -[Cross-VM Apps]: ../tutorials/cross-vm-apps/introduction.md -[Batched Transactions]: ../tutorials/cross-vm-apps/introduction.md +[Cross-VM Apps]: ../../blockchain-development-tutorials/cross-vm-apps/introduction.md +[Batched Transactions]: ../../blockchain-development-tutorials/cross-vm-apps/introduction.md [OpenZeppelin Contracts]: https://www.openzeppelin.com/contracts [Cadence-Owned Accounts]: ./accounts.md#cadence-owned-accounts +[this article]: ../../blockchain-development-tutorials/evm/setup/integrating-metamask.mdx \ No newline at end of file diff --git a/docs/evm/read-write.png b/docs/build/evm/read-write.png similarity index 100% rename from docs/evm/read-write.png rename to docs/build/evm/read-write.png diff --git a/docs/evm/sponsored-gas.png b/docs/build/evm/sponsored-gas.png similarity index 100% rename from docs/evm/sponsored-gas.png rename to docs/build/evm/sponsored-gas.png diff --git a/docs/build/evm/using.mdx b/docs/build/evm/using.mdx new file mode 100644 index 0000000000..963841f7ec --- /dev/null +++ b/docs/build/evm/using.mdx @@ -0,0 +1,70 @@ +--- +title: EVM Wallet Setup +sidebar_label: EVM Wallet Setup +sidebar_position: 4 +--- + +import BrowserOnly from '@docusaurus/BrowserOnly'; +import { AddNetworkButton } from '@site/src/components/addNetworkButton'; + +# EVM Wallet Setup + +## Flow Native Wallet + +The [Flow Wallet](https://wallet.flow.com) is the preferred wallet for Flow EVM. It's also compatible with Cadence transactions, and it currently sponsors all transactions on testnet and mainnet! + +Flow Wallet is available on [Android](https://play.google.com/store/apps/details?id=com.flowfoundation.wallet) and [iOS](https://apps.apple.com/ca/app/flow-wallet-nfts-and-crypto/id6478996750), with desktop support using the Flow Wallet [Chrome extension](https://chromewebstore.google.com/detail/flow-reference-wallet/hpclkefagolihohboafpheddmmgdffjm). In addition to being able to transact in both EVM and Cadence environments, Flow Wallet will also allow you to view and move assets between EVM and Cadence, making it possible to manage all your assets in one place. + +To use the Flow Wallet Chrome extension: + +1. Open the Flow Wallet browser extension and create your account. +2. Connect to an app using Flow Wallet. + +## Other EVM Wallets + +Applications deployed to Flow EVM will work with popular EVM-compatible wallets such as [MetaMask](https://chromewebstore.google.com/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn), all you need to do is add the correct [RPC endpoint](./networks) as a custom network. + +### Add Flow to Browser Wallets + + + {() => { + // ******* If Chain Id changes, update the Chain ID in the AddNetworkButton component ******* + return ; + }} + + +### Add Manually to MetaMask + +Manual method: Add Flow EVM as a custom network to MetaMask: + +1. Open the MetaMask browser extension +2. Open the network selection dropdown menu by clicking the dropdown button at the top of the extension +3. Click the **`Add network`** button +4. Click **`Add a network manually`** +5. In the **`Add a network manually`** dialog that appears, enter the following information: + +| Name | Value | +| --------------- | ------------------------------------ | +| Network Name | Flow EVM Mainnet | +| Description | The public RPC url for Flow Mainnet | +| RPC Endpoint | https://mainnet.evm.nodes.onflow.org | +| Chain ID | 747 | +| Currency Symbol | FLOW | +| Block Explorer | https://evm.flowscan.io/ | + +6. Tap the Save button to save Flow EVM as a network. + +You should now be able to connect to the Flow EVM by selecting it from the network selection dropdown menu. + +To additionally add the Flow EVM Testnet to MetaMask, follow the same steps as above, but use the following information: + +| Name | Value | +| --------------- | ------------------------------------ | +| Network Name | Flow EVM Testnet | +| Description | The public RPC url for Flow Testnet | +| RPC Endpoint | https://testnet.evm.nodes.onflow.org | +| Chain ID | 545 | +| Currency Symbol | FLOW | +| Block Explorer | https://evm-testnet.flowscan.io | + +Use the [Flow Testnet Faucet](https://faucet.flow.com/fund-account) to fund your account for testing. diff --git a/docs/build/explore-more.md b/docs/build/explore-more.md deleted file mode 100644 index b98aa75b83..0000000000 --- a/docs/build/explore-more.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Explore More -sidebar_label: Explore More -description: Discover additional tutorials, guides, and resources for building on Flow blockchain. Learn about NFTs, fungible tokens, dApp development, and core blockchain concepts. -sidebar_position: 999 -keywords: - - Flow tutorials - - dApp development - - NFT guide - - fungible tokens - - Flow CLI - - FCL quickstart - - web3 apps - - Flow basics - - blockchain tutorials - - Emerald Academy - - Flow guides - - smart contracts - - Flow development - - learning resources - - Flow ecosystem ---- - -import DocCardList from '@theme/DocCardList'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faWindowMaximize, faCoins, faGem, faBook, faLandmark } from '@fortawesome/free-solid-svg-icons' - - -Below are some additional tutorials to help you get started with Flow: - -, - author: { - name: 'Flow Blockchain', - profileImage: - 'https://avatars.githubusercontent.com/u/62387156?s=200&v=4', - }, - }, - }, - { - type: 'link', - label: 'Fungible Token Guide', - href: '/build/guides/fungible-token', - description: 'Steps to create, deploy, mint, and transfer fungible tokens on Flow', - customProps: { - icon: , - author: { - name: 'Flow Blockchain', - profileImage: - 'https://avatars.githubusercontent.com/u/62387156?s=200&v=4', - }, - }, - }, - { - type: 'link', - label: 'NFT Guide', - href: 'https://academy.ecdao.org/en/quickstarts/1-non-fungible-token-next', - description: 'A DApp that lets users create an empty collection, mint some pre-loaded NFTs, and transfer them to another account on Flow testnet.', - customProps: { - icon: , - author: { - name: 'Emerald City DAO', - profileImage: - 'https://pbs.twimg.com/profile_images/1687225095557632005/tUCmv8_P_400x400.jpg', - }, - }, - }, - { - type: 'link', - label: 'Walkthrough Guides', - href: '/build/getting-started/fcl-quickstart', - description: 'Longer form guides to help you get started with Flow', - customProps: { - icon: , - author: { - name: 'Flow Blockchain', - profileImage: - 'https://avatars.githubusercontent.com/u/62387156?s=200&v=4', - }, - }, - }, - { - type: 'link', - label: 'Emerald Academy', - href: 'https://academy.ecdao.org/en/quickstarts', - description: 'Quickstart Tutorials for Flow created by Emerald City Dao', - customProps: { - icon: '/images/logos/ea-logo.png', - author: { - name: 'Emerald City DAO', - profileImage: - 'https://pbs.twimg.com/profile_images/1687225095557632005/tUCmv8_P_400x400.jpg', - }, - }, - }, - { - type: 'link', - label: 'Basic Concepts', - href: '/build/basics/blocks', - description: 'Basic Concepts of Flow Blockchain', - customProps: { - icon: , - author: { - name: 'Flow Blockchain', - profileImage: - 'https://avatars.githubusercontent.com/u/62387156?s=200&v=4', - }, - }, - } -]} /> diff --git a/docs/build/flow.md b/docs/build/flow.md index 2e8d0bbc4d..243a6fe537 100644 --- a/docs/build/flow.md +++ b/docs/build/flow.md @@ -1,16 +1,19 @@ --- -title: Why Flow +title: Why Flow - The Consumer DeFi Layer-One Network sidebar_label: Why Flow sidebar_position: 1 -description: Flow is the best blockchain for onchain consumer apps and web3 apps. It's scalable, EVM-equivalent, with native account abstraction and a unique multi-role architecture. +description: Flow is a purpose-built L1 blockchain designed for large-scale consumer finance applications and automated DeFi. It's the leading consumer layer-one network with Flow Actions, Scheduled Transactions, and support for both Cadence and Solidity development. keywords: - Flow blockchain + - Consumer DeFi - Best Web3 Apps - Best Consumer Apps - blockchain scaling - multi-role architecture - Cadence language + - Solidity language - EVM equivalence + - Flow Virtual Machine - account abstraction - blockchain security - Flow features @@ -24,17 +27,170 @@ keywords: - MEV - miner-extractable value - maximum extractable value + - VM bridge + - cross-vm development + - Forte upgrade + - Flow Actions + - Scheduled Transactions --- -# Why Flow is the Best for Consumer Apps +# Why Flow: The Consumer DeFi Layer-One Network -Flow was designed to be the [best blockchain for consumer apps] and Web3 as a whole. Flow was built by consumer-facing, onchain app developers to solve the problem of building consumer-facing, onchain apps. Dieter Shirley, Chief Architect of Flow and co-author of the [ERC-721 NFT standard] calls it: +Flow is powering the future of Consumer DeFi. Flow is the home of Consumer DeFi. -> **A computer that anyone can use, everyone can trust, and no one can shut down.** +Flow is a purpose-built L1 blockchain designed for large-scale consumer finance applications. It is the leading consumer layer-one network, boasting over 1 million monthly active users across ecosystem applications built in collaboration with top global brands like NBA, Disney, PayPal, NFL, and Ticketmaster. -Much of the protocol design is based on lessons learned from building web3 applications while working at [Dapper Labs], particularly [CryptoKitties] - the first onchain game to reach [widespread popularity]. The game went viral, then [struggled under its own success] when it caused so much traffic that Ethereum network itself was overwhelmed by the load. +## The Consumer DeFi Movement -The design of Flow was guided by the need to alleviate this burden while creating the best experience possible for both developers and users. The blockchain network of the future must be able to handle millions of users while upholding the key pillars of decentralization: +Today's fintech is a digital facade on analog rails, subject to the same outdated limitations of your brick-and-mortar bank. These platforms gave us the appearance of digital money without the benefits of digital-native assets. Your accounts there are mere pointers to the underlying legacy system. But that is about to change with the Consumer DeFi movement: turning decentralized finance into personal finance. + +The new chapter for Flow in leading Consumer DeFi is not a sudden shift, but rather the culmination of many years of focused dedication in providing the best consumer experience. Within the past 12 months, Flow network achieved remarkable feats: nearly 10x throughput increase for consumer-scale ambitions, 600% year-over-year increase in total value locked (TVL) to over $100M, and the pivotal Forte upgrade that drastically reduced the development time for consumer finance applications from months to mere days. + +The next generation of consumer finance is not just facilitated by the internet; assets themselves are of the internet. Fintech apps serve as opinionated frontends to a new financial layer that is: + +- **Global**: Accessible everywhere, by everyone. +- **Always-On**: Operating 24/7/365, unbound by business hours. +- **Real-Time**: Settling transactions in seconds, not days. +- **Open**: Programmable and composable across apps. + +The foundation for the future of consumer finance is already being laid. After years of development, DeFi technology is ready to transition from a niche market to the mainstream. However, a significant hurdle remains: current DeFi platforms are designed for crypto-savvy users, demanding steep learning curves and willingness to take on unlimited risk. We must move beyond this crypto native phase to the new consumer DeFi era with better-than-fintech user experiences, safer and sustainable yields, and most importantly delivering a tangible impact on users' daily lives. + +**What is Consumer DeFi?** Consumer DeFi is any app or experience that provides the benefits powered by DeFi rails to audiences with zero crypto knowledge. Apps powered by Flow win consumer mindshare because they offer features and benefits that are extremely hard to replicate with just web2 rails while ensuring users do not require crypto-specific knowledge to understand and use them. + +Flow has demonstrated its capability to attract global brands and institutions, offering an innovative and safe platform for their millions of users. With the DeFi sector now ready to transition from a niche market to the mainstream, Flow is uniquely positioned to lead the Consumer DeFi charge. + +Dieter Shirley, Chief Architect of Flow and co-author of the [ERC-721 NFT standard], calls Flow: + +> **_A computer that anyone can use, everyone can trust, and no one can shut down_** + +
+ +
+ +## Flow: Automated DeFi and Consumer Applications + +Flow is a high-performance layer-one blockchain designed for automated DeFi and large-scale consumer applications. Its multi-role architecture isolates heavy computation to Execution Nodes while keeping validation lightweight, so developers gain incredible performance and users benefit from low-cost transactions, even at scale. + +The Forte upgrade expands the core protocol with Flow Actions for atomic multi-step DeFi operations and Scheduled Transactions for fully onchain automation. Developers can compose swaps, staking, or yield workflows that self-execute without off-chain keepers, scripts, or relayers required. + +Flow delivers a unified environment for automation-heavy, composable applications that demand reliability and precision at scale. It's where DeFi, fintech, and consumer-grade performance converge in a single L1. + +## Forte Network Upgrade: Autonomous DeFi Execution + +The Forte network upgrade marks a turning point for builders creating DeFi systems on Flow. Until now, blockchains have largely been reactive, responding only when a user or off-chain keeper sends a transaction. Forte changes that model by giving developers a native framework for composable, autonomous execution. + +> **_ERC-20 and ERC-721 unlocked nouns. Actions and scheduled transactions unlock verbs._** + +Forte transforms Flow from a reactive blockchain into an autonomous, intelligent network capable of executing complex workflows without external dependencies. The upgrade introduces native time scheduling, protocol-level composability, and AI-optimized development tools that enable entirely new categories of applications. + +Together, these systems turn Flow into a self-governing financial runtime that is precise with 128-bit fixed-point math for lossless calculations, secure through resource-based execution, and fully composable across protocols. In this environment, DeFi logic can schedule itself, chain together across protocols, and operate autonomously—a blockchain that finally does more than react. + +### Flow Actions: Protocol-native composability + +[**Flow Actions**] are protocol-native, composable operations that enable developers to create multi-step workflows across protocols in a single atomic transaction. With Flow Actions, builders can link together standardized DeFi primitives such as sources, sinks, swappers, price oracles, and flashers into atomic, protocol-agnostic workflows. + +A single transaction can claim rewards, swap assets, add liquidity, and restake LP tokens without any off-chain orchestration. These building blocks eliminate custom integrations and ensure every operation either fully succeeds or safely reverts, unlocking complex strategies like automated yield farming, arbitrage, and rebalancing through simple, auditable Cadence code. + +This means developers can: + +- **Compose complex operations**: Build sophisticated DeFi strategies by combining multiple Actions in one transaction +- **Eliminate integration complexity**: Use standardized interfaces instead of custom contract integrations +- **Ensure atomicity**: All operations succeed together or fail together, eliminating partial execution risks +- **Reduce gas costs**: Execute multiple protocol interactions more efficiently than separate transactions + +### Scheduled Transactions: Autonomous onchain execution + +[**Scheduled Transactions**] introduce the first truly onchain time scheduler. Developers can schedule or trigger transactions directly within Flow accounts, enabling recurring actions, deferred settlements, and autonomous portfolio management without external cron jobs or trusted servers. + +Scheduled Transactions are onchain resources that run entirely within a Flow account, enabling fully autonomous, secure transaction execution. They can self-trigger based on conditions and operate without external keepers. + +Key capabilities: + +- **Autonomous operation**: Execute transactions automatically based on programmed logic +- **Self-contained**: Run entirely onchain without external dependencies +- **Trigger-based**: React to onchain events, time schedules, or custom conditions + +Combined, Actions and Scheduling allow DeFi protocols to become self-maintaining: positions can compound automatically, vaults can adjust exposure based on time or events, and protocols can enforce predictable behavior entirely onchain. + +Scheduled Transactions are the first native time scheduler that lets onchain apps run tasks automatically, like cron jobs for blockchains. Applications are no longer restricted to being reactive only to user transactions. They can be used for: + +- **DeFi protocols** that automatically rebalance portfolios on schedule +- **AI-driven agents** that proactively settle, sweep, or optimize positions +- **Subscription services** with automatic recurring payments +- **Gaming mechanics** with time-based events and rewards + +Scheduled Transactions run natively on the network, simplifying operations, reducing off-chain dependencies, and making behavior auditable and predictable in code. This implements [FLIP 330: Scheduled Transaction]. + +### High-precision DeFi with 128-bit fixed-point types + +Cadence now supports **Fix128** and **UFix128** - 128-bit fixed-point types enabling precision up to **24 decimal places** for advanced DeFi, risk engines, and interest accrual workloads. + +The native precision in Forte with built-in 128-bit fixed-point support eliminates the need for bespoke arithmetic scaffolding while minimizing rounding-related errors common in integer-based math. This ensures lossless conversion where all existing Fix64 and UFix64 values convert seamlessly, providing financial-grade accuracy that supports sophisticated financial calculations requiring extreme precision. + +This implements [FLIP 341: Add 128-bit Fixed-point Types to Cadence]. + +### WebAuthn and passkey support + +Forte adds **native WebAuthn support** including passkeys, enabling wallets to use device-backed credentials on iOS, Android, and popular password managers to sign transactions. + +Native WebAuthn support on Flow eliminates seed phrases by enabling biometric authentication while preserving self-custody, with cross-device portability that securely syncs credentials across devices. The native integration requires no additional smart contract layers like ERC-4337, providing a seamless UX where users can sign transactions with Touch ID, Face ID, or hardware keys. + +Combined with native account abstraction on Flow, developers can build [smart wallets without relying on complex contract architectures]. This implements [FLIP 264: WebAuthn Credential Support]. + +### AI-friendly Cadence errors + +Cadence compiler and linter errors are now **designed for AI assistance**, making it easier for agents and IDE copilots to fix issues automatically. Error messages: + +- **Explain the cause** with context-aware descriptions +- **Suggest concrete fixes** with actionable recommendations +- **Link directly** to reference docs and migration notes +- **Surface through language server** for AI-powered editors like Cursor + +This enables faster feedback, fewer documentation round trips, and smoother AI agent workflows for code refactoring and migration. + +### Boosting Efficiency and Scalability + +#### Enhanced node performance with PebbleDB + +Forte upgrades node storage from BadgerDB to **PebbleDB**, delivering up to 80% memory usage reduction depending on node type and up to 60% CPU usage improvement for typical operations. The upgrade provides up to 30% annual disk usage reduction through effective pruning, higher stability under load by eliminating memory spikes, and improved ROI for operators through better resource efficiency. + +#### Optimized state storage with account key de-duplication + +Public key de-duplication eliminates redundancy while preserving multi-key account flexibility, consolidating 53% of all keys that were duplicates. This optimization delivers a 6% reduction in the Flow execution state (saving 21 GB from 349 GB), removes 0.29 billion entries from the storage trie, and provides a 6-18% reduction in Execution Node memory usage, resulting in faster state access through leaner data structures. + +#### Adaptive collection rate limiting for overload resilience + +The [assembly line architecture] on Flow gains intelligent rate limiting to prevent pipeline bottlenecks through automatic throttling when execution or sealing lags behind collection. The system maintains steady pipeline flow even at several hundred TPS while providing priority handling for governance and protocol transactions, creating a self-regulating system that disengages once the backlog clears. + +#### Near real-time transaction results + +Building on the [data availability vision] for Flow, Access Nodes ingest account data and transaction results **before finalization**, enabling soft finality access for high-frequency DeFi applications with early state reads that include graceful rollback handling. This approach provides reduced latency for real-time applications and direct data serving without third-party dependencies. + +### Protocol Autonomy + +#### Hardened data integrity across the network + +A major milestone on the [protocol autonomy roadmap] ensures every data structure has a **canonical, verifiable identity** through collision-resistant hashing for all inter-node communications and immediate tampering detection by message recipients. The system provides protected data structures with custom linter validation and immutable message semantics for simplified development. + +This provides developers and AI agents with a simpler mental model where network messages are treated as immutable objects with stable identities. + +## What makes Flow unique + +Flow is a fast, decentralized, and developer-friendly blockchain designed to be the foundation for a new generation of games, apps, and the [digital assets] that power them. It is based on a unique [multi-role architecture] and designed to [scale without sharding], allowing for massive improvements in speed and throughput while preserving a developer-friendly, ACID-compliant environment. + +Much of the protocol design is based on lessons learned from building Web3 applications while working at [Dapper Labs], particularly [CryptoKitties] — the first onchain game to reach [widespread popularity]. The game went viral, then [struggled under its own success] when it caused so much traffic that the Ethereum network itself was overwhelmed by the load. + +The design of Flow was guided by the need to alleviate this burden while creating the best experience possible for both developers and users. Flow Foundation (the core team) and Dapper Labs (the leading ecosystem builder) work together as two integral parts of a unified effort, combining their strengths to position Flow as the leader in Consumer DeFi. This synergy brings together deep protocol and infrastructure expertise hardened by over 10 years of production experience with the highest security standards, alongside deep consumer audience expertise honed by operating multiple production apps that generated over $1 billion in revenue combined. + +The blockchain network of the future must be able to handle millions of users while upholding the key pillars of decentralization: 1. Verifiability 1. Predictability/Reliability @@ -43,126 +199,209 @@ The design of Flow was guided by the need to alleviate this burden while creatin 1. Interoperability 1. Security -Flow solves the [blockchain trilemma] and represents the next generation of blockchain technology. It's built to enable seamless consumer-scale apps without compromising decentralization or user experience and is the chosen blockchain network for [NBA Top Shot], [NFL All Day], [Mattel Creations], and [Disney Pinnacle]. +Flow solves the [blockchain trilemma] and represents the next generation of blockchain technology. It's built to enable seamless consumer-scale apps without compromising decentralization or user experience, and is the chosen blockchain network for [NBA Top Shot], [NFL All Day], [Mattel Creations], and [Disney Pinnacle]. + +### Dual language architecture + +Flow is unique in supporting two powerful programming languages for smart contract development: + +- **Cadence**: A modern programming language developed by smart contract application builders. +- **Solidity**: The industry-standard language for EVM development, fully supported on Flow with full EVM equivalence. + +EVM and Cadence environments both use FLOW as gas for transactions and are connected by a native bridge that allows seamless and cheap communication between them. Fungible and non-fungible tokens can also be seamlessly transferred between environments using the native VM token bridge, taking place instantly in a single atomic transaction. + +This means developers can choose the language that best fits their needs while maintaining full interoperability between both environments. + +### Cadence development on Flow + +Flow supports two smart contract languages: + +[Cadence] provides native resource safety, 128-bit fixed-point arithmetic for financial precision, built-in WebAuthn authentication for secure, seedless user onboarding, and vastly increased contract size, storage, and computation limits. It also grants native data availability, and Cadence transactions are written in the language itself, which allows for multiple calls to multiple functions on multiple smart contracts all with a single user signature. + +Key Cadence features: -## What Makes Flow Unique +- **Advanced Transactions**: [Transactions] in Cadence smart contracts are not simply calls to existing functions on already deploy contracts. Instead, transactions are code written in Cadence that can **call any function (with appropriate access) on any smart contract by any author**, all in a single, atomic transaction with a single user signature. +- **AI Ready**: Cadence transactions have [pre- and post-conditions] that clearly define the inputs to a transactions, such as the tokens that may be withdrawn, and outcomes, such as collectibles that must be purchased. With these definitions, Cadence transactions of immense complexity can be written safely. Regardless of code in the actual execution, the user can be sure that they get what they expected and only pay the price they authorized. +- **Data Availability**: Similarly, any author can construct a **view** function to access any public data on any smart contract without needing the author of that smart contract to have anticipated the need to view that data or reliance a provider to cache it and make it available. +- **Native account abstraction**: Cadence transactions have protocol-native [account abstraction]. All accounts are smart accounts, supporting scripting, multiple keys, multi-signature transactions, and walletless onboarding with social logins. +- **Gasless transactions**: Cadence transactions have multiple [signing roles] for each transaction. Most notably, the payer can be set independently of the authorizer. In other words, having one account sign a transaction and another pay for that transaction is a built-in feature. +- **Security**: Smart contracts on Flow are natively written in Cadence, an easier, safer, and more secure programming language for crypto assets and apps. It's the first high-level, [resource-oriented] programming language. +- **Developer ergonomics**: The Flow network is designed to maximize developer productivity. Examples range from upgradeable smart contracts to built-in logging support to the Flow Emulator. -Flow is a fast, decentralized, and developer-friendly blockchain designed to be the foundation for a new generation of games, apps, and the [digital assets] that power them. It is based on a unique [multi-role architecture], and designed to [scale without sharding], allowing for massive improvements in speed and throughput while preserving a developer-friendly, ACID-compliant environment. It natively allows development of smart contracts in the powerful [Cadence] language, and also supports full [Ethereum Virtual Machine (EVM)] equivalence with contracts written in Solidity. +### Solidity development on Flow EVM -### Flow Blockchain +[Solidity] allows developers to deploy existing contracts on a fast and efficient, fully EVM-equivalent network while benefitting from access to native VRF, batched transactions, and all the benefits of the Flow protocol. A native bridge allows seamless transfers of assets between these two networks. -- **Multi-role architecture:** The [multi-role architecture] of Flow allows the network to [scale without sharding] to serve billions of users without reducing the decentralization of consensus and verification. -- **True Fast Finality**: For most other networks, it takes minutes, [a day], or even [a week] to reach hard finality - the point in which a transaction cannot be reversed. On Flow, the median time for finality is [under 10 seconds], without compromising security. +Flow EVM provides the best EVM experience available anywhere: + +- **Speed, cost, and compatibility**: Flow EVM can already run all of your audited Solidity contracts at an average of less than 1 cent per transaction ([usually way less!]). Unlike L2 solutions, Flow EVM reaches true finality in seconds — not in [a week]. +- **Bridge from Other EVM networks**: You can [bridge] hundreds of assets from dozens of chains to Flow. +- **VM token bridge**: Assets can be bridged between Flow Cadence and Flow EVM easily and atomically with the VM token bridge. Assets can even be bridged **and used** in a **single** transaction, allowing full composability between the EVM and Cadence environments. +- **Access to Cadence features**: Access Cadence features and contracts from Flow EVM to take advantage of native [VRF], higher computation for lower cost, and any asset on Cadence Flow. You can also build [cross-vm apps] on top of the _wagmi/viem/RainbowKit_ stack, enabling batched transactions and more. +- **EVM equivalence:** Flow EVM is truly _EVM Equivalent_, not just _EVM Compatible_. It runs exactly the same as EVM mainnet, which means builders do not run into _minor_ variances or endless 'quirks' when they try to integrate. If it works on Ethereum Mainnet, it works with Flow EVM. + +### Seamless integration for Ethereum developers + +Flow EVM is designed to work out-of-the-box with the Ethereum toolchain or other clients. Native EVM transactions continue to be supported when using Metamask and other EVM-compatible clients. + +EVM-equivalency on Flow works behind-the-scenes by implementing a minimal transaction script in Cadence to integrate Flow features with EVM. This is made possible because EVM transactions are composed and executed within Cadence transactions, enabling novel use-cases and patterns for integration. + +### Flow blockchain core features + +- **MEV resistance**: Flow is designed to [ensure equitable access] by resisting MEV. Maximum Extractable Value, also know as Miner-Extractable Value (MEV), is a practice common in other blockchains in which the builder of a block can profit at your expense by manipulating where and how your transaction is included. - **Native VRF**: Flow provides [onchain randomness] at the protocol level. Instead of implementing a complex setup and [paying $10+ USD per number], simply call the built-in function. -- **MEV Resistance**: Flow is designed to [ensure equitable access] by resisting MEV. Maximum Extractable Value, also know as Miner-Extractable Value (MEV), is a practice common in other blockchains in which the builder of a block can profit at your expense by manipulating where and how your transaction is included. -- **Consumer Onboarding:** Flow was designed for mainstream consumers, with payment onramps catalyzing a safe and low-friction path from fiat to crypto. -- **EVM Equivalence**: The [Cadence] Virtual Machine (VM) is powerful enough to allow other VMs to run inside of it, almost like a Docker Container. The first one integrated in this way is [EVM] and the EVM RPC API. -- **Efficient Gas Costs**: The Flow blockchain is extremely efficient, allowing apps to do more computation at lower costs. +- **Scalable and Secure Architecture**: The [multi-role architecture] of Flow allows the network to [scale without sharding] to serve billions of users without reducing the decentralization of consensus and verification. +- **True, fast finality**: For most other networks, it takes minutes, [a day], or even [a week] to reach hard finality — the point at which a transaction cannot be reversed. On Flow, the median time for finality is [under 10 seconds], without compromising security. +- **Consumer onboarding**: Flow was designed for mainstream consumers, with payment onramps catalyzing a safe and low-friction path from fiat to crypto. +- **Efficient gas costs**: The Flow blockchain is extremely efficient, allowing apps to do more computation at lower costs. -### Flow Cadence +### MEV resilience -- **Native Account Abstraction**: Flow has protocol-native [account abstraction]. All accounts are smart accounts, supporting scripting, multiple keys, multi-signature transactions, and walletless onboarding with social logins. -- **Gasless Transactions**: Flow has multiple [signing roles] for each transaction. Most notably, the payer can be set independently of the authorizer. In other words, having one account sign a transaction and another pay for that transaction is a built-in feature. -- **Security:** Smart contracts on Flow are natively written in [Cadence], an easier, safer, and more secure programming language for crypto assets and apps. It's the first high-level, [resource-oriented] programming language. -- **Developer Ergonomics:** The Flow network is designed to maximize developer productivity. Examples range from upgradeable smart contracts to built-in logging support to the Flow Emulator. +The [MEV Resilient] design on Flow offers DeFi builders improved market efficiency, fairness, trust, and long-term viability for their apps. Since Flow EVM transactions are composed and executed within a Cadence transaction, block production is handled by the [multi-role architecture] on Flow. -### Flow EVM +This robust MEV resilience is a significant difference from other EVM-compatible networks and results in reasonably priced and predictable gas fees. The impracticality of frontrunning or other attacks improves the user experience by eliminating failed transactions and invisible fees. -- **Speed, Cost, and Compatibility**: Flow EVM can already run all of your audited Solidity contracts at an average of less than 1 cent per transaction ([usually way less!]). Unlike L2 solutions, Flow EVM reaches true finality in seconds - not in [a week]. 😳 -- **Bridge from Other EVM Networks**: You can [bridge] hundreds of assets from dozens of chains to Flow. -- **VM Token Bridge**: Assets can be bridged between Flow Cadence and Flow EVM easily and atomically with the VM token bridge. Assets can even be bridged **and used** in a **single** transaction, allowing full composability between the EVM and Cadence environments. -- **Access to Cadence**: Access Cadence features and contracts from Flow EVM to take advantage of native [VRF], higher computation for lower cost, and any asset on Cadence Flow. You can also build [cross-vm apps] on top of the wagmi/viem/RainbowKit stack, enabling batched transactions and more. -- **EVM Equivalence:** Flow EVM is truly _EVM Equivalent_, not just _EVM Compatible_. It runs exactly the same as EVM mainnet, which means builders won't run into "minor" variances or endless "quirks" when they try to integrate. If it works on Ethereum Mainnet, it will work with Flow EVM. +### Flow track record in Consumer DeFi -## Learning Shortcuts +Flow leadership in Consumer DeFi is built on a foundation of proven expertise and real-world validation: -To get a complete picture on how to build on Flow, follow the 👈 sidebar top to bottom. This path will give you the most thorough onboarding experience. +**Consumer expertise:** -If you like to jump right into the deep end of the pool, take a look below for direct links to advanced topics! +- The leading consumer chain that onboarded millions of net new users onchain and still boasts over 1 million monthly active users +- Deep consumer audience expertise honed by operating multiple production apps that generated over $1 billion in revenue combined +- Vast network of global consumer brands and platforms like NBA, Disney, PayPal, Ticketmaster -### Learn Cadence +**DeFi and fintech expertise:** -[Cadence] is a modern smart contract programming language designed to work with Flow. Learning a new language is an investment, but you'll find that Cadence is safer, more explicit, and less dangerous than other blockchain languages. Plus, it unlocks the full power of the Flow protocol! +- Deep protocol and infrastructure expertise hardened by over 10 years of production experience with the highest security standards (since CryptoKitties days) +- Built the first smart contract wallet (Dapper Wallet plugin) on Ethereum back in 2018, ahead of the account abstraction movement +- Managed the end-to-end infrastructure for on/off-ramp, KYC, and risk monitoring platform that handles hundreds of millions of dollars in volume (Dapper Wallet) +- Flow ALP provides the best risk-adjusted yield opportunities in DeFi for consumers and institutional capital +- The best infrastructure layer that offers the fastest time to market for consumer DeFi apps -:::tip +Flow is where consumers deposit their funds and access the best risk-adjusted yields, making it the ideal platform for Consumer DeFi applications that prioritize safety and sustainable returns. -If you're already comfortable with Solidity, be sure to check out how [Cadence] works in our [Guide for Solidity Developers]! +### Scalability, performance, and low gas fees -::: +For sustainable user adoption, apps require the network they build on to be secure, efficient, affordable, and fast. Gas fees are ultra-low cost on the network, but Flow goes a step further allowing for gasless experiences through sponsored transactions. -### Build with the EVM +The state space on Flow is extensible to the petabyte scale, making it easy to store application data onchain. This means contracts can maintain a full working dataset — including metadata — together with contract logic. -Not ready to take the plunge and learn [Cadence]? Try out "EVM++" by deploying existing [EVM] contracts to see that Flow EVM is faster and cheaper than nearly every other EVM solution without compromising on security. +Transaction throughput on the Flow network has reached as many as 2 million daily transactions, a similar average transaction volume as Ethereum. Unlike Ethereum, Flow has always operated well under its maximum throughput ceiling, and that ceiling is scalable to even greater performance when it becomes necessary. -Deploying on Flow EVM also gives your Solidity contracts access to many Flow Cadence features, such as native [VRF]. +## Getting started -### Getting Started with App Development +Whether you're ready to dive into the advantages of building with [Cadence], or are starting with Flow [EVM], we've got paths to get you up and running as quickly as possible. + +### Getting started with Cadence app development The [Getting Started] tutorial covers everything you need to know to build a Flow Cadence application: -- Setting up your local development environment (it's fast and easy!) -- Deploying and interacting with Flow Cadence contracts -- Building a frontend that can interact with smart contracts written by you, or other developers +- Setting up your local development environment (it's fast and easy!). +- Deploying and interacting with Flow Cadence contracts. +- Building a frontend that can interact with smart contracts written by you or other developers. + +### Learn Cadence + +[Cadence] is a modern smart contract programming language designed to work with Flow. Learning a new language is an investment, but you'll find that Cadence is safer, more explicit, and less dangerous than other blockchain languages. Plus, it unlocks the full power of the Flow protocol! + +:::tip -### Core Contracts +If you're already comfortable with Solidity, be sure to check out how [Cadence] works in our [Guide for Solidity Developers]! -The Flow blockchain implements core functionality using its own smart contract language, [Cadence]. The core functionality is split into a set of contracts, called the [core contracts]: +::: -- **Fungible Token:** The FungibleToken contract implements the Fungible Token Standard. It is the second contract ever deployed on Flow. -- **Flow Token:** The FlowToken contract defines the FLOW network token. -- **Flow Fees:** The FlowFees contract is where all the collected Flow fees are gathered. -- **Service Account:** The FlowServiceAccount contract tracks transaction fees and deployment permissions and provides convenient methods for Flow Token operations. -- **Staking Table:** The FlowIDTableStaking contract is the central table that manages staked nodes, delegation, and rewards. -- **Epoch Contract:** The FlowEpoch contract is the state machine that manages Epoch phases and emits service events. +### Build with Solidity on Flow EVM -### FLOW Token +Not ready to take the plunge and learn [Cadence]? Try out **EVM++** by deploying existing [EVM] contracts to see that Flow EVM is faster and cheaper than nearly every other EVM solution without compromising on security. + +Deploying on Flow EVM also gives your Solidity contracts access to many Flow Cadence features, such as native [VRF]. + +## FLOW token The [FLOW] (or $FLOW) token is the native currency for the Flow network. Developers and users can use FLOW to transact on the network. Developers can integrate FLOW directly into their apps for peer-to-peer payments, service charges, or consumer rewards. FLOW can be held, transferred, or transacted peer-to-peer. - To understand more about Flow Token Economics and the FLOW token, read the [Flow Token Economics] guide. - FLOW tokens are the native Fungible Token on Flow. To learn more about how to work with them in your applications, review the [FLOW] article. -### Technical Background +## Technical background - The [Flow Technical Primer] is a great place to start to understand how Flow works. - The [Three technical whitepapers] cover the unique innovation behind the Flow blockchain network in-depth. +## Flow Improvement Proposals (FLIPs) + +Those wishing to understand the technical specifics of how Flow EVM works, we recommend reviewing the following improvement proposals: + +- Understanding [EVM Support on Flow] +- Exploring the [Flow VM Bridge] +- Insights into the [Flow EVM Gateway] +- Integration of the [Cadence Interface] + +## Build with Flow + +Whether you're building with Cadence or Solidity, porting an existing Solidity dApp or building from scratch, Flow offers a **fast, scalable blockchain with low fees** and the tooling you already know. As a **purpose-built L1 for consumer finance applications**, Flow combines familiar development workflows with performance and UX enhancements you can't get elsewhere. Build the next generation of Consumer DeFi applications that deliver better-than-fintech user experiences, safer and sustainable yields, and tangible impact on users' daily lives. + +## Join the community + +Are you interested in launching a project on Flow or partnering with us? Visit our weekly Flow [office hours] for discussions on project development and other opportunities for collaboration. You can also connect with us in our developers-chat in the Flow [Discord]. + -[best blockchain for consumer apps]: https://flow.com/ -[ERC-721 NFT standard]: https://github.com/ethereum/eips/issues/721 -[CryptoKitties]: https://www.cryptokitties.co/ -[Dapper Labs]: https://www.dapperlabs.com/ -[struggled under its own success]: https://spectrum.ieee.org/cryptokitties -[blockchain trilemma]: https://coinmarketcap.com/academy/glossary/blockchain-trilemma -[NBA Top Shot]: https://nbatopshot.com/ -[NFL All Day]: https://nflallday.com/ -[Mattel Creations]: https://creations.mattel.com/pages/virtual -[Disney Pinnacle]: https://disneypinnacle.com/ -[digital assets]: https://www.flow.com/post/flow-blockchain-cadence-programming-language-resources-assets -[widespread popularity]: https://www.cnn.com/style/article/cryptokitty-blockchain/index.html -[multi-role architecture]: https://www.flow.com/primer -[onchain randomness]: ./advanced-concepts/randomness.md -[paying $10+ USD per number]: https://docs.chain.link/vrf/v2-5/billing -[ensure equitable access]: ./basics/mev-resistance.md -[scale without sharding]: https://www.flow.com/post/flow-blockchain-multi-node-architecture-advantages [a day]: https://docs.zksync.io/zk-stack/concepts/finality#finality-on-zksync-era [a week]: https://docs.optimism.io/stack/rollup/overview#fault-proofs -[usually way less!]: https://evm.flowscan.io/stats -[under 10 seconds]: ./basics/transactions.md#flow -[signing roles]: ./basics/transactions.md#signer-roles +[account abstraction]: https://flow.com/account-abstraction +[best platform for consumer apps]: https://flow.com/ +[blockchain trilemma]: https://coinmarketcap.com/academy/glossary/blockchain-trilemma +[bridge]: ../ecosystem/bridges.md +[Cadence Interface]: https://github.com/onflow/flips/blob/f646491ec895442dcccdb24d80080bab1c56188e/protocol/20231116-evm-support.md [Cadence]: https://cadence-lang.org/ -[resource-oriented]: https://flow.com/post/resources-programming-ownership +[Transactions]: https://cadence-lang.org/docs/language/transactions +[pre- and post-conditions]: https://cadence-lang.org/docs/language/pre-and-post-conditions +[cross-vm apps]: ../blockchain-development-tutorials/cross-vm-apps/index.md +[CryptoKitties]: https://www.cryptokitties.co/ +[Dapper Labs]: https://www.dapperlabs.com/ +[digital assets]: https://www.flow.com/post/flow-blockchain-cadence-programming-language-resources-assets +[Discord]: https://discord.gg/flow +[Disney Pinnacle]: https://disneypinnacle.com/ +[ensure equitable access]: ./cadence/basics/mev-resistance.md +[ERC-721 NFT standard]: https://github.com/ethereum/eips/issues/721 [Ethereum Virtual Machine (EVM)]: https://flow.com/upgrade/crescendo/evm.md +[EVM Support on Flow]: https://github.com/onflow/flips/pull/225 [EVM]: https://flow.com/upgrade/crescendo/evm.md -[Guide for Solidity Developers]: https://cadence-lang.org/docs/solidity-to-cadence -[account abstraction]: https://flow.com/account-abstraction -[bridge]: ../ecosystem/bridges.md -[cross-vm apps]: ../tutorials/cross-vm-apps/index.md -[Getting Started]: ./getting-started/contract-interaction.md -[core contracts]: ./core-contracts/index.md -[FLOW]: ./core-contracts/03-flow-token.md +[Flow EVM Gateway]: https://github.com/onflow/flips/pull/235/files [Flow Technical Primer]: https://www.flow.com/primer -[Three technical whitepapers]: https://www.flow.com/technical-paper [Flow Token Economics]: https://www.flow.com/flow-token-economics -[VRF]: ../tutorials/native-vrf/vrf-in-solidity.md +[Flow VM Bridge]: https://github.com/onflow/flips/pull/233/files/d5bc46c4b13f0b9b168a94f994c77a5a689f6b24..122e938b7acae7e774246b1b66aaf5979ca21444 +[FLOW]: ./cadence/core-contracts/03-flow-token.md +[Getting Started]: ../blockchain-development-tutorials/cadence/getting-started/index.md +[Guide for Solidity Developers]: https://cadence-lang.org/docs/solidity-to-cadence +[Mattel Creations]: https://creations.mattel.com/pages/virtual +[MEV Resilient]: ./cadence/basics/mev-resistance.md +[multi-role architecture]: https://flow.com/post/flow-blockchain-multi-node-architecture-advantages +[multi-role architecture]: https://www.flow.com/primer +[NBA Top Shot]: https://nbatopshot.com/ +[NFL All Day]: https://nflallday.com/ +[office hours]: https://calendar.google.com/calendar/ical/c_47978f5cd9da636cadc6b8473102b5092c1a865dd010558393ecb7f9fd0c9ad0%40group.calendar.google.com/public/basic.ics +[onchain randomness]: ./cadence/advanced-concepts/randomness.md +[paying $10+ USD per number]: https://docs.chain.link/vrf/v2-5/billing +[resource-oriented]: https://flow.com/post/resources-programming-ownership +[scale without sharding]: https://www.flow.com/post/flow-blockchain-multi-node-architecture-advantages +[signing roles]: ./cadence/basics/transactions.md#signer-roles +[Solidity]: https://soliditylang.org/ +[struggled under its own success]: https://spectrum.ieee.org/cryptokitties +[Three technical whitepapers]: https://www.flow.com/technical-paper +[under 10 seconds]: ./cadence/basics/transactions.md#flow +[usually way less!]: https://evm.flowscan.io/stats +[VRF]: ../blockchain-development-tutorials/native-vrf/vrf-in-solidity.md +[widespread popularity]: https://www.cnn.com/style/article/cryptokitty-blockchain/index.html +[**Scheduled Transactions**]: ../blockchain-development-tutorials/forte/scheduled-transactions/scheduled-transactions-introduction.md +[FLIP 330: Scheduled Transaction]: https://github.com/onflow/flips/blob/main/protocol/20250609-scheduled-callbacks.md +[FLIP 341: Add 128-bit Fixed-point Types to Cadence]: https://github.com/onflow/flips/blob/main/cadence/20250815-128-bit-fixed-point-types.md +[smart wallets without relying on complex contract architectures]: https://flow.com/post/transforming-smartphones-into-hardware-wallets-how-secure-enclave-support-on-flow-is-ushering-in-the-next-wave-of-web3-applications +[FLIP 264: WebAuthn Credential Support]: https://github.com/onflow/flips/blob/cfaaf5f6b7c752e8db770e61ec9c180dc0eb6543/protocol/20250203-webauthn-credential-support.md +[protocol autonomy roadmap]: https://flow.com/protocol-autonomy-roadmap +[**Flow Actions**]: ../blockchain-development-tutorials/forte/flow-actions/index.md +[fundamental DeFi primitives]: ../blockchain-development-tutorials/forte/flow-actions/index.md +[assembly line architecture]: https://flow.com/multi-node +[data availability vision]: https://flow.com/protocol-autonomy-roadmap diff --git a/docs/build/getting-started/contract-interaction.md b/docs/build/getting-started/contract-interaction.md deleted file mode 100644 index 5c5c4ef835..0000000000 --- a/docs/build/getting-started/contract-interaction.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -sidebar_position: 1 -sidebar_label: Contract Interaction -title: Contract Interaction -description: Learn how to interact with your first smart contract on Flow's Testnet. Understand how to read data from Cadence contracts, execute scripts, and explore the Counter contract example. -keywords: - - smart contracts - - Flow Testnet - - contract interaction - - Cadence scripts - - Counter contract - - contract deployment - - Flow CLI - - contract examples - - blockchain interaction - - Flow development - - contract reading - - script execution - - Flow dApps - - contract tutorial - - Flow quickstart ---- - -import VerticalSplit from "./vertical-split.svg" - -# 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. - -Smart contracts on Flow are permanent pieces of code that live on the blockchain. They allow you to encode business logic, define digital assets, and much more. By leveraging smart contracts, you can create decentralized applications (dApps) that are transparent, secure, and open to anyone. - -Flow supports modern smart contracts written in [Cadence], a resource-oriented programming language designed specifically for smart contracts. Cadence focuses on safety and security, making it easier to write robust contracts. Flow also supports traditional [EVM]-compatible smart contracts written in Solidity, allowing developers to port their existing Ethereum contracts to Flow. In this guide, we'll focus on interacting with Cadence smart contracts. - -## Objectives - -After completing this guide, you'll be able to: - -* 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: - -* Create a Flow project using the [Flow CLI](../../tools/flow-cli/index.md). -* Add an already-deployed contract to your project with the [Dependency Manager](../../tools/flow-cli/dependency-manager.md). -* Deploy a smart contract locally to the [Flow Emulator](../../tools/emulator/index.md). -* 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 `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 Counter from 0x8a4dce54554b225d - -access(all) -fun main(): Int { - return Counter.getCount() -} -``` - -Let's break down what this script does: - -- **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 `count` variable, which is `0` unless it has been modified. - - - -## Understanding the `Counter` 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 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 - } - - // Public function to increment the counter - access(all) fun increment() { - self.count = self.count + 1 - emit CounterIncremented(newCount: self.count) - } - - // Public function to decrement the counter - access(all) fun decrement() { - self.count = self.count - 1 - emit CounterDecremented(newCount: self.count) - } - - // 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 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 `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 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 `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/getting-started/flow-cli.md b/docs/build/getting-started/flow-cli.md deleted file mode 100644 index 62e2f68f75..0000000000 --- a/docs/build/getting-started/flow-cli.md +++ /dev/null @@ -1,420 +0,0 @@ ---- -sidebar_position: 2 -sidebar_label: Local Development -title: Local Development with Flow CLI -description: Learn how to use the Flow Command Line Interface (CLI) for local blockchain development. Create projects, run tests, manage dependencies, deploy contracts, and interact with the Flow emulator. -keywords: - - Flow CLI - - local development - - Flow emulator - - smart contracts - - contract deployment - - dependency management - - blockchain testing - - Flow projects - - contract testing - - script execution - - transactions - - Flow tools - - development environment - - contract management - - blockchain development ---- - -# Local Development - -The [Flow Command Line Interface] (CLI) is a set of tools that developers can use to interact with the Flow blockchain by managing accounts, sending transactions, deploying smart contracts, running the emulator, and more. This quickstart will get you familiar with its main concepts and functionality. - -## Objectives - -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 - -## Installation - -The first thing you'll need to do is install the Flow CLI. If you have [homebrew] installed you can run: - -```zsh -brew install flow-cli -``` - -For other ways of installing, please refer to the [installation guide]. - -### Flow Cadence VSCode Extension - -Install the [Flow Cadence VSCode Extension] from the marketplace. - -## Creating a New Project - -To create a new project, navigate to the directory where you want to create your project and run: - -```zsh -flow init -``` - -Upon running this command, you'll be prompted to enter a project name. Enter a name and press `Enter`. - -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`. - -The `init` command will create a new directory with the project name and the following files: - -- `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. - -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. - -:::info - -For additional details on how `flow.json` is configured, review the [configuration docs]. - -::: - -### Running the Tests - -To run the example test for the `Counter` contract located in `cadence/tests`, you can run: - -```zsh -flow test -``` - -:::tip - -For a more detailed guide on running Cadence tests, check out the [tests documentation](../../tools/flow-cli/tests.md). - -::: - -## Deploying the Contract to Emulator - -The emulator is a local version of the Flow blockchain that you can use to test your contracts and scripts. It's a great way to develop and test your contracts locally - before you try them on the `testnet` or `mainnet`. - -Before we deploy, let's open a new terminal window and run the emulator. From the root of your project directory, where your `emulator-account.pkey` and `flow.json` files are located, run: - -```zsh -flow emulator start -``` - -Your emulator will now be running. - -### Deploying a Contract - -#### Creating an Account - -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 automatically created `emulator-account`, but for this example lets also create a new account on the emulator to deploy it to. - -:::info - -**Reminder**: On Flow Cadence, contracts are deployed to the storage of the account that deploys them. - -::: - -Leave your emulator running, and open a second terminal. 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`. - -#### 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 config add deployment -``` - -First, pick `emulator` as the network for deployment. Select your `test-account` as the account to deploy to. Next, pick `Counter` as the contract to deploy. Finally, choose `no` when asked if you wish to deploy more contracts. - -#### Deploying the Contract - -To deploy the `Counter` contract to the emulator, run: - -```zsh -flow project deploy -``` - -You'll see something similar to: - -```zsh -Deploying 1 contracts for accounts: test-account - -Counter -> 0x179b6b1cb6755e31 (a98c155fe7afc8eb2af5551748759b08a80a0ae85d1b09f92f1afc293c61ca98) - -🎉 All contracts deployed successfully -``` - -That's it! You've just deployed your first contract to the Flow Emulator. - -::warning - -You can't deploy the same contract to multiple accounts at the same time with the `deploy` command. If you've experimented with the above, you may need to manually edit the `"deployments"` property in `flow.json` to remove extra deployments. - -::: - -## 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. - -If we wanted to generate a new script, we could run: - -```zsh -flow generate script ScriptName -``` - -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. - -To run the script, you can run: - -```zsh -flow scripts execute cadence/scripts/GetCounter.cdc -``` - -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. - -```zsh -Result: 0 -``` - -:::tip - -If you'll like to learn more about writing scripts, please check out the docs for [basic scripts]. - -::: - -## Executing Transactions - -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 run the transaction, you can run: - -```zsh -flow transactions send cadence/transactions/IncrementCounter.cdc -``` - -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. - -```zsh -Transaction ID: 9cc7ac4d3d5239016965aba89b9692d3401a48a090d1ad1a8d9ef9cfca685e6e - -Block ID b8537860b0fc9ca8b3195b121e762502f9a220874b605d6a810998e8b62321a3 -Block Height 3 -Status ✅ SEALED -ID 9cc7ac4d3d5239016965aba89b9692d3401a48a090d1ad1a8d9ef9cfca685e6e -Payer f8d6e0586b0a20c7 -Authorizers [f8d6e0586b0a20c7] - -Proposal Key: - Address f8d6e0586b0a20c7 - Index 0 - Sequence 1 - -No Payload Signatures - -Envelope Signature 0: f8d6e0586b0a20c7 -Signatures (minimized, use --include signatures) - -Events: - Index 0 - Type A.179b6b1cb6755e31.Counter.CounterIncremented - Tx ID 9cc7ac4d3d5239016965aba89b9692d3401a48a090d1ad1a8d9ef9cfca685e6e - Values - - newCount (Int): 1 - - - -Code (hidden, use --include code) - -Payload (hidden, use --include payload) - -Fee Events (hidden, use --include fee-events) -``` - -Run the script to check the counter again. You'll see that it has incremented: - -```zsh -Result: 1 -``` - -:::tip - -If you want to learn more about writing transactions, please read the docs for [basic transactions]. - -::: - -## 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. - -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`] from `testnet` that has a function to format numbers. - -To grab it, run: - -```zsh -flow dependencies install 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 `emulator-account` account to deploy the contract to the emulator. - -You'll then see the `NumberFormatter` in your deployments for emulator in your `flow.json`. - -Now we can deploy the `NumberFormatter` contract to the emulator by running: - -```zsh -flow project deploy -``` - -```zsh -Deploying 2 contracts for accounts: test-account - -Counter -> 0x179b6b1cb6755e31 [skipping, no changes found] -NumberFormatter -> 0x179b6b1cb6755e31 (f8ce6dfa1771c7bad216e72e7f7aac7f1987c4261d425d27e689c701b9ec69cd) - -🎉 All contracts deployed successfully -``` - -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: - -```cadence -import "Counter" -import "NumberFormatter" - -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 -} -``` - -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`. - -:::warning - -Do **not** simply add a new file. Use `flow generate transaction IncrementBy1000.cdc` - -::: - -Add a new transaction called `IncrementBy1000.cdc`. Fill it with a variant of `IncrementCounter.cdc` that instead loops through the `increment` function 1000 times. - -```cadence -import "Counter" - -transaction { - - prepare(acct: &Account) { - // Authorizes the transaction - } - - execute { - // Increment the counter 1000 times - var i = 0 - while i < 1000 { - Counter.increment() - i = i + 1 - } - - // Retrieve the new count and log it - let newCount = Counter.getCount() - log("New count after incrementing: ".concat(newCount.toString())) - } -} -``` - -Try out your new transaction with: - -```zsh -flow transactions send cadence/transactions/IncrementBy1000.cdc --signer test-account - -``` - -Finally, to test the updated script, you can run: - -```zsh -flow scripts execute cadence/scripts/GetCounter.cdc -``` - -You should now see the result with commas. - -:::info - -If you're a Solidity developer, did you catch what we just did here? We updated the features and functionality available in the smart contract **without updating the contract itself!** - -Even more importantly, we did this **without needing access or permission.** You can use the power of composability in Flow Cadence to add new features to contracts you don't own. - -::: - -## 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]. - -After that, it's easy to add your contract to your project configuration using the Flow CLI [`config` commands]. - -## Conclusion - -In this tutorial, we've accomplished all of our learning objectives: - -1. ✅ Created a Flow project using the Flow CLI - - - Initialized a new project with `flow init` - - Set up the project structure with contracts, scripts, and tests - - Configured the project using `flow.json` - -2. ✅ Ran tests for a smart contract - - - Executed the example test for the `Counter` contract - - Learned about the testing capabilities of the Flow CLI - -3. ✅ Added an already-deployed contract to your project - - - Used the Dependency Manager to install the `NumberFormatter` contract - - Configured the contract deployment in `flow.json` - - Deployed the contract to the emulator - -4. ✅ Deployed a smart contract locally to the Flow Emulator - - - Started the Flow Emulator - - Created a test account - - Deployed the `Counter` contract to the emulator - - Deployed the `NumberFormatter` contract - -5. ✅ Wrote and executed scripts to interact with deployed contracts - - Created and executed the `GetCounter` script - - Modified the script to use the `NumberFormatter` contract - - Created and executed the `IncrementBy1000` transaction - - Demonstrated the power of Cadence's composability - - - -[Flow Cadence VSCode Extension]: https://marketplace.visualstudio.com/items?itemName=onflow.cadence -[Flow Command Line Interface]: ../../tools/flow-cli/index.md -[Cadence]: https://cadence-lang.org/ -[configuration docs]: ../../tools/flow-cli/flow.json/configuration.md -[homebrew]: https://brew.sh/ -[installation guide]: ../../tools/flow-cli/install -[0xa1296b1e2e90ca5b]: https://contractbrowser.com/A.9dca641e9a4b691b.HelloWorld -[Dependency Manager]: ../../tools/flow-cli/dependency-manager -[basic scripts]: ../basics/scripts.md -[basic transactions]: ../basics/transactions.md -[`generate` documentation]: ../../tools/flow-cli/boilerplate.md -[`config` commands]: ../../tools/flow-cli/flow.json/manage-configuration.md -[`NumberFormatter`]: https://contractbrowser.com/A.8a4dce54554b225d.NumberFormatter diff --git a/docs/build/getting-started/index.md b/docs/build/getting-started/index.md deleted file mode 100644 index edc1f7e731..0000000000 --- a/docs/build/getting-started/index.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Getting Started -sidebar_position: 1 -description: Start building on Flow with these beginner-friendly guides and quickstarts. -keywords: - - getting started - - Flow - - quickstart - - Flow CLI - - FCL - - contract interaction ---- - -# Getting Started - -Kick off your Flow development journey with these beginner-friendly guides. Learn how to set up your environment, interact with smart contracts, and use essential tools. - -## Guides - -- **[Contract Interaction]** - Discover how to interact with smart contracts on Flow, including reading and writing data. -- **[Local Development]** - Get set up for local development and started with the Flow Command Line Interface for deploying and managing smart contracts. -- **[Simple Frontend]** - Learn how to quickly set up and use @onflow/react-sdk with hooks for frontend development. - -[Simple Frontend]: ./fcl-quickstart.md -[Local Development]: ./flow-cli.md -[Contract Interaction]: ./contract-interaction.md diff --git a/docs/build/getting-started/vertical-split.svg b/docs/build/getting-started/vertical-split.svg deleted file mode 100644 index e1bcbdcc35..0000000000 --- a/docs/build/getting-started/vertical-split.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/build/guides/_category_.json b/docs/build/guides/_category_.json deleted file mode 100644 index afdb49ff43..0000000000 --- a/docs/build/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Guides", - "position": 8 -} diff --git a/docs/build/guides/account-linking/index.md b/docs/build/guides/account-linking/index.md deleted file mode 100644 index 9493bc1024..0000000000 --- a/docs/build/guides/account-linking/index.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -title: Account Linking (FLIP 72) -sidebar_position: 4 -description: Learn about Flow's unique account linking feature that enables shared ownership of accounts. Understand how accounts can be accessed, delegated, and managed through capabilities and hybrid custody. -keywords: - - account linking - - FLIP 72 - - account capabilities - - hybrid custody - - account access - - account delegation - - Flow accounts - - account ownership - - account security - - parent accounts - - child accounts - - account management - - Flow protocol - - account control - - custody model ---- - -# Account Linking - -Account linking is a unique Flow concept that enables sharing ownership over [accounts](../../basics/accounts.md). In -order to understand how we can achieve that we must first understand how accounts on Flow are accessed. - -Accounts on flow can be accessed in Cadence through two types, `PublicAccount` and `Account`. As the name implies the -`PublicAccount` type gives access to all public account information such as address, balance, storage capacity, etc., -but doesn't allow changes to the account. The `Account` type (or more specifically, an -[entitled](https://cadence-lang.org/docs/language/access-control#entitlements) `&Account`) allows the same access as -`PublicAccount` but also allows changes to the account, including adding/revoking account keys, managing the deployed -contracts, as well as linking and publishing Capabilities. - -![Flow account structure](resources/account-structure.png) - -## Accessing Account - -Accessing `Account` allows for modification to account storage, so it's essential to safeguard this access by mandating -that transactions are signed by the account being accessed. [Account -entitlements](https://cadence-lang.org/docs/language/accounts/#performing-write-operations) enable for more granular -access control over the specific parts of the account that can be accessed from within the signed transaction. A -transaction can list multiple authorizing account it wants to access as part of the `prepare` section of the -transaction. Read more about transaction signing in the [transaction documentation](../../basics/transactions.md). - -Since access to the `Account` object enables state change, the idea of account ownership actually translates to the -ability to access the underlying account. Traditionally, you might consider this the same as having key access on an -account, but we'll see in just a minute how programmatic, ownership-level access is unlocked with [Capabilities on -Flow](https://cadence-lang.org/docs/language/capabilities). - -## Account Capabilities - -Before proceeding the reader will need a clear understanding of [Cadence -capabilities](https://cadence-lang.org/docs/language/capabilities) to follow this section. Advanced features such as -Account Capabilities are powerful but if used incorrectly can put your app or users at risk. - -Cadence allows the creation of Capabilities to delegate access to account storage, meaning any account obtaining a valid -Ccapability to another account object in the storage can access it. This is a powerful feature on its own - accessing -another account programmatically without the need for an active key on the accessible account. The access to the object -can be limited when creating a Capability so only intended functions or fields can be accessed. - -Account linking is made possible by the extension of Capabilities on the `Account` object itself. Similar to how storage -capabilities allow access to a value stored in an account's storage, `&Account` Capabilities allow delegated access to -the issuing `Account`. These Capabilities allow for access to key assignment, contract deployment, and other privileged -actions on the delegating `Account` - effectively sharing ownership of the account without ever adding or sharing a key. -This Capability can of course be revoked at any time by the delegating account. - -### Creating Account Links - -When referring to 'account linking' we mean that an `&Account` Capability is created by the parent account and published -to another account. The account owning the `&Account` Capability which was made available to another account is the child -account. The account in possession of the Capability given by the child account becomes its parent account. - -![Account linking on Flow relational diagram](resources/account-linking-relational-diagram.png) - -A link between two existing accounts on Flow can be created in two steps: - -1. A child account creates an `&Account` Capability and publishes it to the parent account. -2. The parent account, claims that Capability and can access the child's account through it. - -![Account linking steps on Flow](resources/account-linking-steps-high-level.png) - -These two steps are implemented in Cadence as two transactions: - -****************\*\*\*\*****************Create capability****************\*\*\*\***************** - -The account B creates and publishes the `&Account` Capability to the account A at the address `0x01` - -```cadence -#allowAccountLinking - -transaction { - prepare(signer: auth(IssueAccountCapabilityController, PublishInboxCapability) &Account) { - // Issue a fully-entitled account capability - let capability = signer.capabilities - .account - .issue() - // Publish the capability for the specified recipient - signer.inbox.publish(capability, name: "accountCapA", recipient: 0x1) - } -} -``` - -************\*\*\*\*************Claim capability************\*\*\*\************* - -The account A claims the Capability published by account B. - -```cadence -transaction { - prepare(signer: auth(ClaimInboxCapability) &Account) { - let capabilityName = "accountCapB" - let providerAddress = 0x2 - // Claim the capability published by the account 0x2 - let capability = signer.inbox - .claim( - capabilityName, - provider: providerAddress - ) ?? panic( - "Capability with name ".concat(capabilityName) - .concat(" from provider ").concat(providerAddress.toString()) - .concat(" not found") - ) - // Simply borrowing an Account reference here for demonstration purposes - let accountRef = capability.borrow()! - } -} -``` - -## What is account linking most useful for? - -Account linking was specifically designed to enable smooth and seamless custodial onboarding of users to your Flow based -application without them first requiring a wallet to do so. This pattern overcomes both the technical hurdle, as well as -user's reluctance to install a wallet, opening access to Flow applications to every user. Users can experience an app -without any delay while still offering a path to self-sovreign ownership. - -Naturally, users may expect to use their account with another application, or otherwise move assets stored in that -account elsewhere - at minimum from their wallet. When an app initially leverages account linking, the app creates the -account instead of the user and stores that user's specific state in the app-created account. At a later point, users -can take ownership of the app account providing they possess a full [Flow account](../../basics/accounts.md), typically -by installing a wallet app. - -Account linking enables users to possess multiple linked child accounts from different apps. Complexities associated -with accessing those child accounts are eliminated by abstracting access to them through the user's parent account. - -:::info - -Simply put, child accounts are accessed and can be treated as a seamless part of the parent account. - -::: - -All assets in the app account can now jump the walled garden to play in the rest of the Flow ecosystem. The user does -not need to rely on the custodial app to execute transactions moving assets from the child account as the parent account -already has access to the assets in the child account. - -![Multiple parent-child accounts on Flow](resources/account-linking-multiple-accounts.png) - -This shared control over the digital items in the in-app account enables users to establish real ownership of the items -beyond the context of the app, where they can use their parent account to view inventory, take the items to other apps -in the ecosystem, such as a marketplace or a game. - -Most importantly, users are able to do this without the need to transfer the digital items between accounts, making it -seamless to continue using the original app while also enjoying their assets in other contexts. - -## Security Considerations - -Account linking is a _very_ powerful Cadence feature, and thus it must be treated with care. So far in this document, -we've discussed account linking between two accounts we own, even if the child account is managed by a third-party -application. But, we can't make the same trust assumptions about custodial accounts in the real world. - -Creating an `&Account` Capability and publishing it to an account we don't own means we are giving that account full -access to our account. This should be seen as an anti-pattern. - -:::warning - -Creating an `&Account` Capability and sharing it with third-party account effectually the same as giving that person your -account's private keys. - -::: - -Because unfiltered account linking can be dangerous, Flow introduces the [`HybridCustody` -contract](./parent-accounts.md) that helps custodial applications regulate access while enabling parent accounts to -manage their many child accounts and assets within them. - -## Hybrid Custody and Account Linking - -Apps need assurances that their own resources are safe from malicious actors, so giving out full access might not be the -form they want. Using hybrid custody contracts, the app still maintains control of their managed accounts, but they can: - -1. Share capabilities freely, with a few built-in controls over the types of capabilities that can be retrieved by - parent accounts via helper contracts (the `CapabilityFactory`, and `CapabilityFilter`) -2. Share additional capabilities (public or private) with a parent account via a `CapabilityDelegator` resource - -Learn more about it in the [Hybrid Custody documentation](./parent-accounts.md). - -### Guides - -- [Building Walletless Applications Using Child Accounts](./child-accounts.md) covers how apps can leverage Account - Linking to create a seamless user experience and enable future self-custody. -- [Working With Parent Accounts](./parent-accounts.md) covers features enabled by the core `HybridCustody` contract to - access child account assets from parent accounts. This is useful for apps like marketplaces or wallets that are - working with accounts that have potential child accounts. - -### Resources - -- [Forum Post](https://forum.flow.com/t/hybrid-custody/4016) where core concepts were introduced and discussed. -- [GitHub repository](https://github.com/onflow/hybrid-custody) where `HybridCustody` core contracts and scripts are - maintained. Check out the repository for more advanced script or transaction examples. -- [Example](https://github.com/jribbink/magic-link-hc-sample/) Account Linking project with - [Magic](https://magic.link/). -- [Starter template](https://github.com/Niftory/niftory-samples/tree/main/walletless-onboarding) for - [Niftory](https://niftory.com/) Account Linking API. diff --git a/docs/build/guides/mobile/_category_.yml b/docs/build/guides/mobile/_category_.yml deleted file mode 100644 index 3eae228d44..0000000000 --- a/docs/build/guides/mobile/_category_.yml +++ /dev/null @@ -1,5 +0,0 @@ -label: Building on Mobile -position: 7 -customProps: - icon: 📱 - description: Learn to build applications for iOS and Android by leveraging native SDKs, React Native plugins, and supported mobile wallets. diff --git a/docs/build/guides/mobile/overview.md b/docs/build/guides/mobile/overview.md deleted file mode 100644 index 207e6f4583..0000000000 --- a/docs/build/guides/mobile/overview.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Overview -sidebar_label: Overview -sidebar_position: 1 -description: Discover Flow's mobile development capabilities for building native blockchain applications. Learn about Flow's unique features for mobile apps, including secure key management, wallet integration, and progressive onboarding. -keywords: - - Flow mobile - - mobile development - - blockchain apps - - native applications - - mobile SDK - - secure enclave - - wallet integration - - WalletConnect - - account linking - - mobile security - - Flow features - - mobile wallets - - Cadence mobile - - user experience - - blockchain mobile ---- - -Building mobile native applications that interact with the blockchain enables a much richer end user experiences and provides access to OS capabilities. With Flow Mobile, developers can build native applications for iOS and Android leveraging SDKs and mobile wallets. - -## Why Flow - -Millions of users with Flow accounts are exploring the ecosystem and looking for applications. Most of these users purchased Flow NFTs and are comfortable with web3 principles. - -In addition to the existing user base, developers can tap into smart contracts deployed on the Flow blockchain. These contracts, including their on-chain state, provide unique possibilities to build experiences that enrich applications users are already using. - -The following key capabilities make Flow a standout choice for mobile applications: -- On-device key encryption via Secure Enclave & Keychain -- Mobile wallet compatibility and support for WalletConnect 2.0 -- Simple, progressive onboarding experience with postponed account linking -- Seamless in-app experience with on-chain interactions without constant signing requests -- Account flexibility enabling secure account recovery and sharing - -## Why Flow Mobile - -### Proven - -Flow is built with mainstream adoption in mind. Mobile applications can leverage the best-in-class user experiences millions of users have enjoyed on the web, through applications like NBA TopShot or NFL AllDay. - -### Best-in-class UX - -Flow's Client Library makes it very intuitive to sign up and sign in with their wallet of choice. For transaction signing, Flow offers human readable security, so users get a clear understanding of what they are approving. An increased sense of trust for Flow applications is the outcome. - -Furthermore, Flow's powerful account model allows for seamless user flows of on-chain operations. Apps can perform transactions on behalf of the users (with their approval) in the background, without the need to switch between apps. The account model also allows apps to pay for transactions to postpone fiat on-ramps to get them to experience the value of an application before committing to buying tokens. - -Last but not least, developers can leverage progressive web3 onboarding, in which any identity provider can be used to authenticate users, without having to deal with keys. Developers can create Flow accounts for the users and link them to a wallet at a later point in time. - -### Security first - -Flow's mobile SDKs use on-device key encryption via Apple's Secure Enclave and Android's Keystore. The flexible account model makes it possible for an account to have multiple keys with different weights, which enables secure social recovery, account sharing, and much more. - -## Smart contract language inspired by mobile languages - -Cadence, Flow's smart contract language, will look and feel very familiar to mobile languages developers are already familiar with. Cadence was inspired by Move, Swift, and Kotlin. This reduces the ramp-up period to develop mobile applications leveraging on-chain logic. - -## What is available - -Developers can leverage the following features to get productive quickly: - -- Swift & Kotlin FCL SDKs to auth and interact with the Flow blockchain (query + execute scripts) -- FCL-compatible mobile wallets -- User auth using WalletConnect 2.0 -- Basic mobile sample application (MonsterMaker) - -Coming soon: - -- Samples for key in-app functionality, like in-app purchasing -- Progressive user onboarding diff --git a/docs/build/guides/more-guides.mdx b/docs/build/guides/more-guides.mdx deleted file mode 100644 index 3b605360b7..0000000000 --- a/docs/build/guides/more-guides.mdx +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: More Guides -description: Various guides for Flow -sidebar_position: 5 -sidebar_custom_props: - icon: 🏟️ ---- - -import DocCardList from '@theme/DocCardList'; - -Explore an array of exciting, grassroots initiatives, and projects that thrive within the Flow Blockchain community, each contributing to the platform's growth and innovation. - diff --git a/docs/build/smart-contracts/best-practices/contract-upgrades.md b/docs/build/smart-contracts/best-practices/contract-upgrades.md deleted file mode 100644 index 8acf65b090..0000000000 --- a/docs/build/smart-contracts/best-practices/contract-upgrades.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Contract Upgrades with Incompatible Changes -sidebar_position: 4 -description: Learn best practices for handling incompatible contract upgrades on Flow. Understand the risks and recommended approaches for upgrading smart contracts while maintaining data integrity. -keywords: - - contract upgrades - - smart contracts - - incompatible changes - - contract migration - - upgrade strategy - - contract deployment - - Flow blockchain - - contract versioning - - data migration - - contract paths - - resource management - - upgrade transactions - - contract compatibility - - best practices - - contract security ---- - -### Problem - -I have an incompatible upgrade for a contract. How can I deploy this? - -### Solution - -Please don't perform incompatible upgrades between contract versions in the same account. -There is too much that can go wrong. - -You can make [compatible upgrades](https://cadence-lang.org/docs/language/contract-updatability) and then run a post-upgrade function on the new contract code if needed. - -If you must replace your contract rather than update it, -the simplest solution is to add or increase a suffix on any named paths in the contract code -(e.g. `/public/MyProjectVault` becomes `/public/MyProjectVault002`) in addition to making the incompatible changes, -then create a new account and deploy the updated contract there. - -⚠️ Flow identifies types relative to addresses, so you will also need to provide _upgrade transactions_ to exchange the old contract's resources for the new contract's ones. Make sure to inform users as soon as possible when and how they will need to perform this task. - -If you absolutely must keep the old address when making an incompatible upgrade, then you do so at your own risk. Make sure you perform the following actions in this exact order: - -1. Delete any resources used in the contract account, e.g. an Admin resource. -2. Delete the contract from the account. -3. Deploy the new contract to the account. - -⚠️ Note that if any user accounts contain `structs` or `resources` from the _old_ version of the contract that have been replaced with incompatible versions in the new one, **they will not load and will cause transactions that attempt to access them to crash**. For this reason, once any users have received `structs` or `resources` from the contract, this method of making an incompatible upgrade should not be attempted! diff --git a/docs/build/smart-contracts/best-practices/project-development-tips.md b/docs/build/smart-contracts/best-practices/project-development-tips.md deleted file mode 100644 index 2e8dc8e66e..0000000000 --- a/docs/build/smart-contracts/best-practices/project-development-tips.md +++ /dev/null @@ -1,309 +0,0 @@ ---- -title: Flow Smart Contract Project Development Standards -sidebar_label: Development Standards -sidebar_position: 5 -description: Learn best practices for organizing and managing Cadence smart contract projects. Understand key aspects of design, development, testing, deployment, and community engagement. -keywords: - - development standards - - smart contracts - - project management - - best practices - - Cadence development - - testing standards - - documentation - - deployment process - - project organization - - code review - - security practices - - community engagement - - open source - - technical leadership - - Flow development ---- - -# Smart Contract Project Development Standards - -## Context - -Smart Contracts are the bedrock piece of security for many important parts -of the Flow blockchain, as well as for any project that is deployed to a blockchain. - -They are also the most visible technical parts of any project, -since users will be querying them for data, building other smart contracts that interact with them, -and using them as learning materials and templates for future projects. -Furthermore, when deployed they are publicly available code on the blockchain -and often also in public Github repos. - -Therefore, the process around designing, building, testing, documenting, -and managing these projects needs to reflect the critical importance they hold in the ecosystem. - -Every software project strikes a balance between effort spent on product/feature delivery -vs the many other demands of the software development lifecycle, whether testing, technical debt, -automation, refactoring, or documentation etc. Building in Web3 we face the same trade-offs, -but in a higher risk and consequence environment than what is typical for most software. -A mismanaged or untested smart contract may result in **significant** financial losses -as a result of vulnerabilities which were overlooked then exploited. -We highly recommend builders adopt these best practices to help mitigate these risks. - -If they do so, they will be able to build better smart contracts, avoid potential bugs, -support user and third-party adoption of their projects, and increase their chances of success -by being a model for good software design. Additionally, the more projects that adopt -good software design and management standards normalizes this behavior, -encouraging other projects in the ecosystem to do the same which creates a healthier -and more vibrant community. - -Ensuring appropriate levels of testing results in better smart contracts which have -pro-actively modeled threats and engineered against them. Ensuring appropriate levels -of standards adoption ([FungibleToken](https://github.com/onflow/flow-ft), -[NFT Metadata](../../advanced-concepts/metadata-views.md), [NFT StoreFront](https://github.com/onflow/nft-storefront), etc) by dapp -builders amplifies the network effects for all in the ecosystem. NFTs in one dapp can be -readily consumed by other dapps through on-chain events with no new integration -required. With your help and participation we can further accelerate healthy and vibrant -network effects across the Flow ecosystem! - -Some of these suggestions might seem somewhat unnecessary, -but it is important to model what a project can do to manage its smart contracts the best -so that hopefully all of the other projects follow suit. - -This also assumes standard software design best practices also apply. -Indeed, many of these suggestions are more general software design best practices, -but there may be others that are assumed but not included here. - -### Implementing These Practices - -This document serves as mostly an outline of best practices the projects should follow. -As with all best practices, teams will choose which applies to them and their work process, -however, we recommend that teams explicitly define a minimum acceptable set of standards -for themselves along with the mechanisms to ensure they are being observed. - -Some teams may also have their own set of development standards that achieve a similar goal -to these. These recommendations are not meant to be the only paths to success, -so if a team disagrees with some of these and wants to do things their own way, -they are welcome to pursue that. This document just shows some generic suggestions -for teams who might not know how they want to manage their project. - -## Design Process - -Smart contracts usually manage a lot of value, have many users, and are difficult to upgrade -for a variety of reasons. Therefore, it is important to have a clearly defined design -process for the smart contracts before much code is written so that the team -can set themselves up for success. - -Here are some recommendations for how projects can organize the foundations of their projects. - -### Projects should ensure that there is strong technical leadership for their smart contracts - -Developing a dapp requires a clear vision for the role of the smart contract and how it's integrated. -Security vulnerabilities may arise from bugs directly in smart contract code (and elsewhere in the system). -Asynchronous interaction vectors may lead to forms of malicious abuse, -DOS etc in a contract triggering explosive gas costs for the developer or other problems. - -We recommend that engineers leading a project and deploying to mainnet have an understanding -of software and security engineering fundamentals and have been thorough -in their Cadence skills development. More in-depth resources for learning Cadence -are available [here](https://cadence-lang.org/docs/). - -The technical leader should be someone who understands Cadence well and has written Cadence smart contracts -before. Production-level smart contracts are not the place for beginners to get their start. - -It should be this person's responsibility to lead design discussions -with product managers and the community, write most of the code and tests, -solicit reviews, make requested changes and make sure the project gets completed in a timely manner. - -The leader should also understand how to sign transactions with the CLI -to deploy/upgrade smart contracts, run admin transactions, and troubleshoot problems, etc. -If something goes wrong in relation to the smart contract -that needs to be handled with a bespoke transaction, it is important that the owner -knows how to build and run transactions and scripts safely to address the issues -and/or upgrade the smart contracts. - -The project should also have a clear plan of succession in case the original owner -is not available or leaves the project. It is important that there are others who -can fill in who have a clear understanding of the code and requirements so they can give good feedback, -perform effective reviews, and make changes where needed. - -### Projects should maintain a well-organized open source Repo for their smart contracts - -As projects like NBA Topshot have shown, when a blockchain product becomes successful -others can and do to build on top of what you are doing. -Whether that is analytics, tools, or other value adds that could help grow your project ecosystem, -composability is key and that depends on open source development. -If there isn't already an open source repo, builders should consider creating one. - -Builders can start from the [the Flow open source template](https://github.com/onflow/open-source-template) -and make sure all of their repo is set up with some initial documentation for what the repo is for -before any code is written. External developers and users should have an easily accessible home page -to go to to understand any given project. - -The repo should also have some sort of high-level design document that lays out -the intended design and architecture of the smart contract. -The project leads should determine what is best for them to include in the document, -but some useful things to include are basic user stories, architecture of the smart contracts, -and any questions that still need to be answered about it. - - Where applicable, diagrams should be made describing state machines, user flows, etc. - - This document should be shared in an issue in the open source repo - where the contracts or features are being developed, - then later moved to the README or another important docs page. - -A high level design is a key opportunity to model threats -and understand the risks of the system. The process of collaborating -and reviewing designs together helps ensure that more edge-cases are captured and addressed. -It's also a lot less effort to iterate on a design than on hundreds of lines of Cadence. - -## Development Process Recommendations - -### The Development process should be iterative, if possible - -The project should develop an MVP first, get reviews, and test thoroughly, -then add additional features with tests. This ensures that the core features are designed -thoughtfully and makes the review process easier because they can focus on each feature -one at a time instead of being overwhelmed by a huge block of code. - -### Comments and field/function descriptions are essential! - -Our experience writing many Cadence smart contracts has taught us how important documentation -is. It especially matters what is documented and for whom, and in that way we are no different from -any software language. The Why is super important, if for example something - an event - that -happens in one contract leads to outcomes in a different contract. The What helps give context, -the reason for the code turning out the way it is. The How, you don't document - you've written -the code. Comments should be directed to those who will follow after you in changing the code. - -Comments should be written at the same time (or even before) the code is written. -This helps the developer and reviewers understand the work-in-progress code better, -as well as the intentions of the design (for testing and reviewing). -Functions should be commented with a - - Description - - Parameter descriptions - - Return value descriptions - - -Top Level comments and comments for types, fields, events, -and functions should use `///` (three slashes) to be recognised by the -[Cadence Documentation Generator](https://github.com/onflow/cadence-tools/tree/master/docgen). -Regular comments within functions should only use two slashes (`//`) - -## Testing Recommendations - -Summarized below is a list of testing related recommendations -which are noteworthy to mention for a typical smart contract project. - -Popular testing frameworks to use for cadence are listed here: -- Cadence: [Cadence Testing Framework](../../smart-contracts/testing.md) -- Go: [Overflow](https://github.com/bjartek/overflow) - -The same person who writes the code should also write the tests. -They have the clearest understanding of the code paths and edge cases. - -Tests should be **mandatory**, not optional, even if the contract is copied from somewhere else. -There should be thorough emulator unit tests in the public repo. -[See the flow fungible token repo](https://github.com/onflow/flow-ft/tree/master/lib/js/test) -for an example of unit tests in javascript. - - -Every time there is a new Cadence version or emulator version, -the dependencies of the repo should be updated to make sure the tests are all still passing. - -Tests should avoid being monolithic; -Individual test cases should be set up for each part of the contract to test them in isolation. -There are some exceptions, like contracts that have to run through a state machine -to test different cases. Positive and negative cases need to be tested. - -Integration tests should also be written to ensure that your app and/or backend can interact -properly with the smart contracts. - -## Managing Project Keys and Deployments - -Smart contract keys and deployments are very important and need to be treated as such. - -### Private Keys should be stored securely - -Private Keys for the contract and/or admin accounts should not be kept in plain text format anywhere. -Projects should determine a secure solution that works best for them to store their private keys. -We recommend storing them in a secure key store such as google KMS or something similar. - -### Deployments to Testnet or Mainnet should be handled transparently - -As projects become more successful, communities around them grow. -In a trustless ecosystem, that also means more of others building on your contracts. -Before deploying or upgrading a contract, it is important to maintain -clear community communications with sufficient notice, since changes will always bring added risk. -Giving community members time to review and address issues with upgrades -before they happen builds trust and confidence in projects. -Here are a few suggestions for how to manage a deployment or upgrade. - -- Communicate to all stake-holders well in advance - - Share the proposal with the community at least a week in advance (unless it is a critical bug fix) - - Examples of places to share are your project's chat, forum, blog, email list, etc. - - This will allow the community and other stakeholders to have plenty of time - to view the upcoming changes and provide feedback if necessary. - - Share the time of the deployment and the deployment transaction with branch/commit hash information to ensure the transaction itself is correct. - - Coordinate deployment with stakeholders to make sure it is done correctly and on time. - -## Responsibilities to the Community - -Web3 brings tremendous possibilities for engineering applications with trustlessness -and composability in mind, with Cadence and Flow offering unique features to achieve this. -If every project treats their community and the Flow community with respect and care, -the things we can all build together will be very powerful. - -### Projects should have thorough documentation - -Encouraging adoption of project contracts to the broader ecosystem -raises the bar around code providing clear high-level descriptions, -with detailed and useful comments within contracts, transactions, and scripts. -The more that a project can be understood, that it adheres to standards, -and can be built upon with ease, the more likely others will build against it in turn. - -Each project should have a detailed README.md with these sections: - - Explanation of the project itself with links to the app - - Addresses on various networks - - High-level technical description of the contracts with emphasis on important types and functionality - - Architecture diagram (if applicable) - - Include links to tutorials if they are external - - Flow smart contract standards that a project implements - -Additionally, each contract, transaction, and script should have high-level descriptions -at the top of their files. This way, anyone in the community can easily -come in and understand what each one is doing without having to parse confusing code. - -### Projects should engage with and respond to their own Community - -Once a contract is deployed, the work doesn't stop there. -Project communities require ongoing nurturing and support. -As the developer of a public project on a public blockchain, -the owners have an obligation to be helpful and responsive to the community -so that they can encourage composability and third party interactions. - -- Keep issues open in the repo. -- The owner should turn on email notifications for new issue creation in the repo. -- Respond to issues quickly and clean up unimportant ones. -- Consider blog posts to share more details on technical aspects of the project and upcoming changes. - -### Projects should contribute to the greater Flow and Cadence community - -Flow has a vibrant and growing community of contributors around the world. -Through our mutual collaboration we've had numerous community Flow Improvement Proposals -([FLIP](https://github.com/onflow/flow/tree/master/flips)s) shipped. -If you have an interest in a particular improvement for Flow or Cadence, -we host open meetings which you are welcome to join (announced on discord) -and can participate anytime on any of the FLIPs -[already proposed](https://github.com/onflow/flow/pulls?q=is%3Aopen+is%3Apr+label%3AFLIP). - -Responsible project maintainers should contribute to discussions -about important proposals (new cadence features, standard smart contracts, metadata, etc) -and generally be aware about evolving best practices and anti-pattern understandings. -Projects who contribute to these discussions are able to influence them to ensure -that the language/protocol changes are favorable to them -and the rest of the app developers in the ecosystem. -It also helps the owner to promote the project and themselves. - -Resources for Best Practices: - -- [cadence/design-pattern](https://cadence-lang.org/docs/design-patterns) -- [cadence/anti-patterns](https://cadence-lang.org/docs/anti-patterns) -- [cadence/security-best-practices](./security-best-practices.md) - -Composability and extensibility should also be priorities while designing, developing, -and documenting their projects. (Documentation for these topics coming soon) - -If you have any feedback about these guidelines, please create an issue in the onflow/cadence-style-guide repo or make a PR updating the guidelines so we can start a discussion. diff --git a/docs/build/smart-contracts/best-practices/security-best-practices.md b/docs/build/smart-contracts/best-practices/security-best-practices.md deleted file mode 100644 index a1d7eb8b10..0000000000 --- a/docs/build/smart-contracts/best-practices/security-best-practices.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: Cadence Security Best Practices -sidebar_label: Security Best Practices -sidebar_position: 3 -description: Learn essential security practices for writing secure Cadence smart contracts. Understand how to handle references, account storage, capabilities, transactions, and access control safely. -keywords: - - security practices - - Cadence security - - smart contract security - - secure coding - - reference safety - - account storage - - capabilities - - access control - - transaction security - - type safety - - authorization - - secure development - - Flow security - - best practices - - security guidelines ---- - -This is an opinionated list of best practices Cadence developers should follow to write more secure Cadence code. - -Some practices listed below might overlap with advice in the [Cadence Anti-Patterns](https://cadence-lang.org/docs/design-patterns) section, which is a recommended read as well. - -## References - -[References](https://cadence-lang.org/docs/language/references) are ephemeral values and cannot be stored. If persistence is required, store a capability and borrow it when needed. - -References allow freely upcasting and downcasting, e.g. a restricted type can be cast to its unrestricted type which will expose all `access(all)` functions and fields of the type. -So even if your capability uses an interface to restrict its functionality, it can -still be downcasted to expose all other public functionality. - -Therefore, any privileged functionality in a resource or struct that will have a public -capability needs to have entitled accecss, for example `access(Owner)`. -Then, the only way to access that functionality would be through an entitled reference, -like ``. - -## Account Storage - -Don't trust a users' [account storage](https://cadence-lang.org/docs/language/accounts#account-storage). Users have full control over their data and may reorganize it as they see fit. Users may store values in any path, so paths may store values of "unexpected" types. These values may be instances of types in contracts that the user deployed. - -Always [borrow](https://cadence-lang.org/docs/language/capabilities) with the specific type that is expected. Or, check if the value is an instance of the expected type. - -## Authorized Accounts - -Access to an `&Account` gives access to whatever is specified in the account entitlements -list when that account reference is created. -Therefore, [avoid using Account references](https://cadence-lang.org/docs/anti-patterns#avoid-using-authaccount-as-a-function-parameter) as a function parameter or field unless absolutely necessary and only use the minimal set of entitlements required -for the specified functionality so that other account functionality cannot be accessed. - -It is preferable to use capabilities over direct `&Account` references when exposing account data. Using capabilities allows the revocation of access by unlinking and limits the access to a single value with a certain set of functionality. - -## Capabilities - -Don't store anything under the [public capability storage](https://cadence-lang.org/docs/language/capabilities) unless strictly required. Anyone can access your public capability using `Account.capabilities.get`. If something needs to be stored under `/public/`, make sure only read functionality is provided by restricting privileged functions with entitlements. - -When publishing a capability, the capability might already be present at the given `PublicPath`. -In that case, Cadence will panic with a runtime error to not override the already published capability. - -It is a good practice to check if the public capability already exists with `account.capabilities.get().check` before creating it. This function will return `nil` if the capability does not exist. - -If it is necessary to handle the case where borrowing a capability might fail, the `account.check` function can be used to verify that the target exists and has a valid type. - -Ensure capabilities cannot be accessed by unauthorized parties. For example, capabilities should not be accessible through a public field, including public dictionaries or arrays. Exposing a capability in such a way allows anyone to borrow it and perform all actions that the capability allows. - -## Transactions - -Audits of Cadence code should also include [transactions](https://cadence-lang.org/docs/language/transactions), as they may contain arbitrary code, just, like in contracts. In addition, they are given full access to the accounts of the transaction's signers, i.e. the transaction is allowed to manipulate the signers' account storage, contracts, and keys. - -Signing a transaction gives access to the `&Account`, i.e. access to the account's storage, keys, and contracts depending on what entitlements are specified. - -Do not blindly sign a transaction. The transaction could for example change deployed contracts by upgrading them with malicious statements, revoking or adding keys, transferring resources from storage, etc. - -## Types - -Use [restricted types and interfaces](https://cadence-lang.org/docs/language/restricted-types). Always use the most specific type possible, following the principle of least privilege. Types should always be as restrictive as possible, especially for resource types. - -If given a less-specific type, cast to the more specific type that is expected. For example, when implementing the fungible token standard, a user may deposit any fungible token, so the implementation should cast to the expected concrete fungible token type. - -## Access Control - -Declaring a field as [`access(all)`](https://cadence-lang.org/docs/language/access-control) only protects from replacing the field's value, but the value itself can still be mutated if it is mutable. Remember that containers, like dictionaries, and arrays, are mutable. - -Prefer non-public access to a mutable state. That state may also be nested. For example, a child may still be mutated even if its parent exposes it through a field with non-settable access. - -Do not use the `access(all)` modifier on fields and functions unless necessary. Prefer `access(self)`, `acccess(Entitlement)`, or `access(contract)` and `access(account)` when other types in the contract or account need to have access. diff --git a/docs/build/smart-contracts/deploying.md b/docs/build/smart-contracts/deploying.md deleted file mode 100644 index 5674b480fc..0000000000 --- a/docs/build/smart-contracts/deploying.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: Deploying Contracts -sidebar_label: Deploying Contracts -description: Learn how to deploy and update smart contracts on Flow Mainnet and Testnet. Understand account creation, key management, deployment best practices, and network sporks. -sidebar_position: 3 -sidebar_custom_props: - icon: 🥇 -keywords: - - contract deployment - - Flow mainnet - - Flow testnet - - account creation - - key management - - Flow CLI - - smart contracts - - deployment guide - - contract updates - - sporks - - network migration - - testnet faucet - - deployment security - - contract addresses - - Flow deployment ---- - -In order to deploy your smart contracts to the mainnet, you need a funded account. If you want to get started on Testnet, look below for information on how to get started. - - -Make sure you handle your mainnet account keys appropriately. Using a Key Management Service is the best practice. - - -### Creating an Account - -There are two simple methods of creating an account on testnet. **Interactive** and **Manual**, both use the Flow CLI. On mainnet you will have to fund your newly created account, there is no faucet. -Make sure to install the Flow CLI. [Flow CLI](../../tools/flow-cli/accounts/create-accounts.md) has a interactive mode for generating keys. - - -Anyone can deploy and update contracts on mainnet. Audits are encouraged but not mandatory to deploying contracts to mainnet. Take every precauction to reduce issues and protect users. - - -### Create and deploy a mainnet project - -The tool of choice is Flow CLI, there are quickstarts and guides that use Flow CLI, [Getting Started](../getting-started/flow-cli) - -- It is highly encouraged to test your contracts, transactions and scripts on Testnet, have strong smart contract test coverage and follow any additional guidelines set out here: [Smart Contract Testing Guidelines](./testing.md). -- Follow the Flow CLI instructions to [Create a Project](../../tools/flow-cli/index.md). You have the Flow CLI installed and ran `flow init` in your project folder and generating a `flow.json` file -- Mainnet account: You completed the mainnet account setup, (see above) and have your key pair and mainnet address ready. -- [Deploy your project](../../tools/flow-cli/deployment/deploy-project-contracts.md), notice that your account now has contracts deployed on mainnet. -- [Deploy a contract](../../tools/flow-cli/accounts/account-add-contract.md) to mainnet. You can deploy contracts individually using the `account-add-contract` command. - - -All your contract deployment addresses are stored in `flow.json`. Mainnet, Testnet and local (emulator) are stored as well. - - -### Deploy updated contracts on mainnet - -Contracts can be updated and retain the contract address. You can use the [Flow CLI contract update command](../../tools/flow-cli/accounts/account-update-contract.md) to re-deploy an updated version of your contract: - - -If you see `Error Code: 1103`, your new account does not have enough funds to complete the transaction. Make sure you have enough FLOW and your account is set up correctly, check [Flowdiver](https://flowdiver.io/) to verify. - - -Once all your contracts are deployed, you can visit [flow-view-source](https://flow-view-source.com/) or run the [Flow CLI get account command](../../tools/flow-cli/accounts/get-accounts.md) to confirm the deployment. - -### Sporks - -Currently, **historical event data is not migrated between sporks,** so you'll need to design your application with this in mind. We recognize the usefulness of historical event data and plan on adding a means of accessing it in the near future. Past spork transactional data is available, [See Previous Spork Access Node Info](../../networks/node-ops/node-operation/past-upgrades) - -More Information on [Sporks](../../networks/node-ops/node-operation/spork) - -### Testnet - -The Flow test network, known as Flow Testnet, exists to help developers test their software and smart contracts against a live network. It's also used as a means of releasing and testing new protocol and smart contract features before they are integrated into Flow's main network (Mainnet). - -When the Flow protocol is updated or a new version of Cadence is released, those updates will always be made available on the [Flow Emulator](../../tools/emulator) _before_ they're integrated into Flow Testnet or Flow Mainnet. - -## Getting Started on Testnet - -If you need to create a flow.json file to store information about accounts and contracts use the `flow init` command to create a project - -To create accounts and generate keys, make sure to install [Flow CLI](../../tools/flow-cli/install). Flow CLI provides convenient functions to simplifies interacting with the blockchain. - - -### Creating an Account - -There is a simple Flow CLI command to run to create an account. `flow accounts create` command will create a new account and generate a key pair then add the account to your flow.json. The command will try and You can also use the [Testnet Faucet](https://faucet.flow.com/fund-account) to create and fund an account. - -More information about [Flow CLI](../../tools/flow-cli/accounts/create-accounts) and creating accounts. - -### Creating and deploying a Project - -Flow CLI can be used to create a Cadence project and stay organized, [Flow CLI: Create a project](../../tools/flow-cli). This will make deployment much easiler and help with the iterative development process. - -After you have a project created and want to deploy your Cadence; contracts, transactions and scripts. -`flow accounts add-contract --signer --network testnet` will deploy your contract to testnet. -More information on how to use Flow CLI to [deploy](../../tools/flow-cli/deployment/deploy-project-contracts.md). - -Make sure Flow project was initialized in the previous step and the `flow.json` is present. - -### Making Use of Core Contracts - -Flow Testnet comes with some useful contracts already deployed, called **core contracts.** More information and import addresses for the [core contracts](../../build/core-contracts/index.md). - -Once your accounts are set up and you're ready to develop, you can look over [some code examples from the Flow Go SDK](https://github.com/onflow/flow-go-sdk/tree/master/examples). - -### Breaking Changes - -The Flow blockchain is improved continuously and thus version updates to Cadence, Flow node software, and the Flow SDKs will contain important updates as well as breaking changes. - -You should anticipate future updates and join the community ([Forum](https://forum.flow.com/) or [Discord](https://discord.com/invite/J6fFnh2xx6)) to stay tuned on important announcements. Notices and guidelines for changes will be provided as early as possible. - -### Testnet Sporking - -"Sporking" (soft forking) is the process of upgrading the Flow network node software and migrating the chain state from one version to another. - -Currently, **historical event data is not migrated between sporks.** You'll need to design your application with this in mind. We recognize the usefulness of historical event data and plan on adding a means of accessing it in the near future. Only one previous spork data is available through old Access Node. - - -Flow Testnet is explicitly for experimentation and testing and should not be used to exchange "real value" (e.g. developing a fiat money on/off-ramp for your testnet application). - diff --git a/docs/build/smart-contracts/overview.md b/docs/build/smart-contracts/overview.md deleted file mode 100644 index 9f81713542..0000000000 --- a/docs/build/smart-contracts/overview.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: Smart Contracts on Flow -sidebar_label: Smart Contracts on Flow -sidebar_position: 2 -sidebar_custom_props: - icon: 🛠️ -description: Learn about smart contract development on Flow blockchain. Understand data storage, standards implementation, and best practices for building decentralized applications using Cadence. -keywords: - - smart contracts - - Flow blockchain - - Cadence - - dApp development - - NFT standards - - fungible tokens - - contract storage - - IPFS storage - - blockchain data - - Flow standards - - contract interfaces - - development tools - - Flow CLI - - Flow emulator - - decentralized apps ---- - -At its core, a decentralized application is defined by the [smart contracts](https://en.wikipedia.org/wiki/Smart_contract) it uses on the blockchain. Rather than relying on centralized application servers and databases, apps model their core application logic using smart contracts, often referred to as the "on-chain" code. - -It is therefore helpful to develop a clear model for your app that takes into account the data and logic that will exist in your smart contracts. In particular, it is important to differentiate between the parts of your app that must live on chain and those that should live off chain. - -## How to Write Smart Contracts on Flow - -Smart contracts on the Flow blockchain are implemented in [Cadence](https://github.com/onflow/cadence), a resource-oriented programming language specifically designed for smart contract development. - -### Onboard to Cadence - -To get started with Cadence, we recommended covering the introductory tutorials available in the [Flow Playground](https://play.flow.com/), a simple web IDE designed for learning Cadence. - -### Configure Your Local Environment - -To build confidently, you will want to set up the appropriate local environment and have an adequate test suite to ensure your smart contracts operate as intended. To do this, familiarize yourself with the following tools: - -- [Flow CLI](../../tools/flow-cli/index.md): A utility to directly interact with the chain and manage accounts and contracts. -- [Flow Emulator](../../tools/emulator/index.md): A lightweight server that simulates the Flow blockchain (strongly recommended during development). -- [Flow Dev Wallet](https://github.com/onflow/fcl-dev-wallet/): A utility to simulate user wallets in development. -- [Visual Studio Code Extension](../../tools/vscode-extension/index.md): An IDE integration for developing smart contracts. - -## Storing Data on Flow - -All apps will store important data on the blockchain, and some more than others -- especially NFT apps. You'll want to consider the following when storing data on the Flow blockchain. - -### What does your data need to represent? - -Permanence is a key property of blockchains; users trust that the data they store will continue to exist for years to come, and this is a defining characteristic of assets like NFTs. Therefore, well-designed digital assets store the information necessary to retain their value without external dependencies. - -### Storage Limits & Fees - -However, there are practical constraints to storing data on a blockchain. Developer and user accounts must retain a small amount of FLOW tokens, known as the storage fee, for bytes of data stored in their accounts. The minimum storage fee will grant each account a minimum storage amount. If an account holds assets that demand more bytes of storage, the account will need to retain more FLOW tokens to increase the storage amount according to Flow's [fee schedule](../basics/fees.md#storage). A more compact data model can keep storage needs down. \ - \ -Furthermore, a single Flow transaction has a size limit of 4MB, which limits the rate at which large amounts of data can be transferred to the blockchain. - -Lastly, a blockchain is not a content delivery network and therefore cannot serve media assets, such as videos, at the speeds expected by modern applications. - -For these reasons, it usually isn't practical to store large media assets such as videos and high-definition images on the Flow blockchain. Instead, consider using an external storage solution. - -### External Storage Networks - -Decentralized storage networks such as IPFS allow you to store large digital assets off chain, but without relying on centralized servers. Rather than saving an entire asset to the Flow blockchain, you can save the content hash (known as a CID on IPFS) on the blockchain and then store the source file off-chain. This way, users can verify that the media file matches the digital asset. - -IPFS files can be uploaded via a pinning service such as Pinata; see their [NFT tutorial](https://medium.com/pinata/how-to-create-nfts-like-nba-top-shot-with-flow-and-ipfs-701296944bf) for an example of how to use Pinata with Flow. - -It's worth noting that IPFS files are served through [gateways](https://docs.ipfs.io/concepts/ipfs-gateway/), many of which leverage caching to provide fast response times. Cloudflare provides a [public IPFS Gateway](https://developers.cloudflare.com/distributed-web/ipfs-gateway), and Pinata also supports [dedicated gateways with custom domains](https://medium.com/pinata/announcing-dedicated-ipfs-gateways-60f599949ce). - -## Using Existing Standards - -The Flow blockchain has existing smart contract standards for both fungible and non-fungible tokens that you should implement when building your contracts. - -### Non-Fungible Tokens (NFTs) - -All NFTs on the Flow blockchain implement the [NonFungibleToken](../../build/core-contracts/08-non-fungible-token.md) interface, allowing them to be compatible with wallets, marketplaces and other cross-app experiences. - -See the [NFT Guide](../guides/nft.md) for a guide on how to create a basic NFT contract -that conforms to the standard. - -- [Non-Fungible Token (NFT) contract interface](../../build/core-contracts/08-non-fungible-token.md) - -### NFT Sales and Trading - -Flow has a standard contract to facilitate both the direct sales and peer-to-peer trading of NFTs. The NFT storefront contract is useful for apps that want to provide an NFT marketplace experience. - -- [NFT Storefront contract](https://github.com/onflow/nft-storefront) - -### Fungible Tokens - -Fungible tokens (i.e. coins, currencies) on the Flow blockchain, including the default cryptocurrency token FLOW, implement the [FungibleToken](../../build/core-contracts/02-fungible-token.md) interface. - -See the [FT Guide](../guides/fungible-token.md) for a guide on how to create a basic fungible token -contract that conforms to the standard. - -- [Fungible Token contract interface](../../build/core-contracts/02-fungible-token.md) diff --git a/docs/build/tools/_category_.yml b/docs/build/tools/_category_.yml new file mode 100644 index 0000000000..1f080dc26b --- /dev/null +++ b/docs/build/tools/_category_.yml @@ -0,0 +1,3 @@ +label: Tools & SDKs +position: 4 +collapsed: true diff --git a/docs/tools/clients/_category_.yml b/docs/build/tools/clients/_category_.yml similarity index 100% rename from docs/tools/clients/_category_.yml rename to docs/build/tools/clients/_category_.yml diff --git a/docs/build/tools/clients/fcl-js/authentication.md b/docs/build/tools/clients/fcl-js/authentication.md new file mode 100644 index 0000000000..4dc53f3811 --- /dev/null +++ b/docs/build/tools/clients/fcl-js/authentication.md @@ -0,0 +1,57 @@ +# Authentication + +Authentication in Flow Client Library (FCL) is closely tied to the concept of `currentUser`. In fact, `fcl.authenticate` and `fcl.unauthenticate` are simply aliases for `fcl.currentUser.authenticate()` and `fcl.currentUser.unauthenticate()`, respectively. So, let’s take a closer look at `currentUser`. + +As an onchain app developer who uses FCL, the primary authentication functionalities revolve around how to: + +- Determine the `currentUser` and whether they are logged in. +- Log a user in. +- Log a user out. + +Due to the way FCL works, to log in and sign up are essentially the same process. + +# Retrieve information about the current user + +FCL provides two ways to get information about the current user: + +1. **A promise-based method** that returns a snapshot of the user’s data. +2. **A subscription-based method** that triggers a callback function with the latest user information whenever it changes. + +### Snapshot of the current user + +```javascript +import * as fcl from '@onflow/fcl'; + +const currentUser = await fcl.currentUser.snapshot(); +console.log('The Current User:', currentUser); +``` + +### Subscribe to the Current User + +```javascript +import * as fcl from '@onflow/fcl'; + +// Returns an unsubscribe function +const unsubscribe = fcl.currentUser.subscribe((currentUser) => { + console.log('The Current User:', currentUser); +}); +``` + +# Authenticate and unauthenticate + +The TL;DR: Call `fcl.authenticate()` to log in and `fcl.unauthenticate()` to log out. + +On Flow mainnet, no additional configuration is needed, because your app’s users will go through the authentication process and can use any FCL-compatible wallet provider. + +During development, you’ll likely want to configure your app to use [`@onflow/dev-wallet`]. The [Quick Start] guide will walk you through how to set it up. + +We also recommend that you use the [FCL Discovery Service] to help users discover and connect to FCL-compatible wallets. + +Whether you're new to building onchain, or an established veteran, we’re here to help. If you run into any issues, reach out to us on [Discord] — we’re happy to assist! + + + +[`@onflow/dev-wallet`]: https://github.com/onflow/fcl-dev-wallet +[Quick Start]: ../../../../blockchain-development-tutorials/cadence/getting-started/index.md +[FCL Discovery Service]: discovery.md +[Discord]: https://discord.gg/flow \ No newline at end of file diff --git a/docs/tools/clients/fcl-js/configure-fcl.md b/docs/build/tools/clients/fcl-js/configure-fcl.md similarity index 70% rename from docs/tools/clients/fcl-js/configure-fcl.md rename to docs/build/tools/clients/fcl-js/configure-fcl.md index 033c057853..2c426d2b43 100644 --- a/docs/tools/clients/fcl-js/configure-fcl.md +++ b/docs/build/tools/clients/fcl-js/configure-fcl.md @@ -4,11 +4,12 @@ title: How to Configure FCL ## Configuration -FCL provides a mechanism to configure various aspects of its behavior. The key principle is that when switching between different Flow Blockchain environments (e.g., Local Emulator → Testnet → Mainnet), the only required change should be your FCL configuration. +Flow Client Library (FCL) provides a mechanism to configure various aspects of its behavior. The key principle is that when you switch between different Flow Blockchain environments (for example, Local Emulator → Testnet → Mainnet), the only required change should be your FCL configuration. -## Setting Configuration Values +## Set configuration values + +Values only need to be set once. We recommend that you do this once and as early in the life cycle as possible. -Values only need to be set once. We recommend doing this once and as early in the life cycle as possible. To set a configuration value, the `put` method on the `config` instance needs to be called, the `put` method returns the `config` instance so they can be chained. ```javascript @@ -20,9 +21,15 @@ fcl .put('baz', 'buz'); // configures "baz" to be "buz" ``` -## Getting Configuration Values +:::info + +For advanced use cases that require scoped configuration, isolated client instances, or multi-tenancy support, see the [`createFlowClient` reference documentation]. + +::: + +## Get configuration values -The `config` instance has an asynchronous `get` method. You can also pass it a fallback value incase the configuration state does not include what you are wanting. +The `config` instance has an asynchronous `get` method. You can also pass it a fallback value in case the configuration state does not include what you want. ```javascript import * as fcl from '@onflow/fcl'; @@ -42,13 +49,13 @@ async function addStuff() { addStuff().then((d) => console.log(d)); // 13 (5 + 7 + 1) ``` -## Common Configuration Keys +## Common configuration keys -- `accessNode.api` -- Api URL for the Flow Blockchain Access Node you want to be communicating with. -- `app.detail.title` - **(INTRODUCED `@onflow/fcl@0.0.68`)** Your applications title, can be requested by wallets and other services. Used by WalletConnect plugin & Wallet Discovery service. -- `app.detail.icon` - **(INTRODUCED `@onflow/fcl@0.0.68`)** Url for your applications icon, can be requested by wallets and other services. Used by WalletConnect plugin & Wallet Discovery service. -- `app.detail.description` - **(INTRODUCED `@onflow/fcl@1.11.0`)** Your applications description, can be requested by wallets and other services. Used by WalletConnect plugin & Wallet Discovery service. -- `app.detail.url` - **(INTRODUCED `@onflow/fcl@1.11.0`)** Your applications url, can be requested by wallets and other services. Used by WalletConnect plugin & Wallet Discovery service. +- `accessNode.api` -- API URL for the Flow Blockchain Access Node you want to communicate with. +- `app.detail.title` - **(INTRODUCED `@onflow/fcl@0.0.68`)** Your applications title, can be requested by wallets and other services. Used by WalletConnect plugin and Wallet Discovery service. +- `app.detail.icon` - **(INTRODUCED `@onflow/fcl@0.0.68`)** URL for your applications icon, can be requested by wallets and other services. Used by WalletConnect plugin and Wallet Discovery service. +- `app.detail.description` - **(INTRODUCED `@onflow/fcl@1.11.0`)** Your applications description, can be requested by wallets and other services. Used by WalletConnect plugin and Wallet Discovery service. +- `app.detail.url` - **(INTRODUCED `@onflow/fcl@1.11.0`)** Your applications URL, can be requested by wallets and other services. Used by WalletConnect plugin and Wallet Discovery service. - `challenge.handshake` -- **(DEPRECATED `@onflow/fcl@0.0.68`)** Points FCL at the Wallet or Wallet Discovery mechanism. - `discovery.wallet` -- **(INTRODUCED `@onflow/fcl@0.0.68`)** Points FCL at the Wallet or Wallet Discovery mechanism. - `discovery.wallet.method` -- Describes which service strategy a wallet should use: `IFRAME/RPC`, `POP/RPC`, `TAB/RPC`, `HTTP/POST`, `EXT/RPC` @@ -56,14 +63,14 @@ addStuff().then((d) => console.log(d)); // 13 (5 + 7 + 1) - `fcl.limit` -- Specifies fallback compute limit if not provided in transaction. Provided as integer. - `flow.network` (recommended) -- **(INTRODUCED `@onflow/fcl@1.0.0`)** Used in conjunction with stored interactions and provides FCLCryptoContract address for `testnet` and `mainnet`. Possible values: `local`, `testnet`, `mainnet`. - `service.OpenID.scopes` - **(INTRODUCED `@onflow/fcl@0.0.68`)** Open ID Connect claims for Wallets and OpenID services. -- `walletconnect.projectId` -- **(INTRODUCED `@onflow/fcl@1.11.0`)** Your app's WalletConnect project ID. See [WalletConnect Cloud](https://cloud.walletconnect.com/sign-in) to obtain a project ID for your application. +- `walletconnect.projectId` -- **(INTRODUCED `@onflow/fcl@1.11.0`)** Your app's WalletConnect project ID. See [WalletConnect Cloud] to obtain a project ID for your application. - `walletconnect.disableNotifications` -- **(INTRODUCED `@onflow/fcl@1.13.0`)** Flag to disable pending WalletConnect request notifications within the application's UI. Default is `false`. -## Using Contracts in Scripts and Transactions +## Use contracts in scripts and transactions -### Address Replacement +### Address replacement -Configuration keys that start with `0x` will be replaced in FCL scripts and transactions, this allows you to write your script or transaction Cadence code once and not have to change it when you point your application at a difference instance of the Flow Blockchain. +Configuration keys that start with `0x` will be replaced in FCL scripts and transactions. This allows you to write your script or transaction Cadence code once and not have to change it when you point your application at a difference instance of the Flow Blockchain. ```javascript import * as fcl from '@onflow/fcl'; @@ -113,9 +120,9 @@ fcl .put('0xFlowToken', '0x7e60df042a9c0868'); ``` -### Using `flow.json` +### Use `flow.json` -A simpler way to import contracts in scripts and transactions is to use the `config.load` method to ingest your contracts from your `flow.json` file. This keeps the import syntax unified across tools and lets FCL figure out which address to use for what network based on the network provided in config. To use `config.load` you must first import your `flow.json` file and then pass it to `config.load` as a parameter. +A simpler way to import contracts in scripts and transactions is to use the `config.load` method to ingest your contracts from your `flow.json` file. This keeps the import syntax unified across tools and lets FCL figure out which address to use for what network based on the network provided in the config. To use `config.load` you must first import your `flow.json` file and then pass it to `config.load` as a parameter. ```javascript import { config } from '@onflow/fcl'; @@ -144,6 +151,16 @@ Then in your scripts and transactions, all you have to do is: import "HelloWorld" ``` -FCL will automatically replace the contract name with the address for the network you are using. +FCL will automatically replace the contract name with the address for the network you use. + +:::info + +Never put private keys in your `flow.json`. Instead, use the [key/location syntax] to separate your keys into a separate git ignored file. + +::: + + -> Note: never put private keys in your `flow.json`. You should use the [key/location syntax](../../flow-cli/flow.json/security.md) to separate your keys into a separate git ignored file. +[`createFlowClient` reference documentation]: ./packages-docs/fcl/createFlowClient.md +[WalletConnect Cloud]: https://cloud.walletconnect.com/sign-in +[key/location syntax]: ../../flow-cli/flow.json/security.md \ No newline at end of file diff --git a/docs/tools/clients/fcl-js/cross-vm/ethereum-provider.mdx b/docs/build/tools/clients/fcl-js/cross-vm/ethereum-provider.mdx similarity index 100% rename from docs/tools/clients/fcl-js/cross-vm/ethereum-provider.mdx rename to docs/build/tools/clients/fcl-js/cross-vm/ethereum-provider.mdx diff --git a/docs/build/tools/clients/fcl-js/cross-vm/index.md b/docs/build/tools/clients/fcl-js/cross-vm/index.md new file mode 100644 index 0000000000..12dff94c33 --- /dev/null +++ b/docs/build/tools/clients/fcl-js/cross-vm/index.md @@ -0,0 +1,49 @@ +--- +title: Cross VM Packages +description: FCL packages for cross-VM (Flow + EVM) applications. +--- + +# FCL Cross-VM Packages + +These packages allow you to leverage Flow’s Cadence-Owned Account (COA) within Ethereum tooling (for example, Wagmi, RainbowKit). They provide a unified approach for cross-VM apps on Flow and EVM, which lets you perform EVM-like operations will Cadence accounts. + +For background and motivation, see the [FCL Ethereum Provider for Cross-VM Apps FLIP #316]. + +| Package | Purpose | +|-----------------------------------------------|-------------------------------------------------------------------------------------------------| +| [@onflow/fcl-ethereum-provider] | Provides an EIP-1193-compliant Ethereum provider backed by an FCL-authenticated COA. | +| [@onflow/fcl-wagmi-adapter] | Integrates Flow-based COAs with Wagmi, and exposes them as Ethereum accounts in your dApp. | +| [@onflow/fcl-rainbowkit-adapter]| Allows a Flow-based wallet option in your RainbowKit wallet selection modal. | + +## `@onflow/fcl-ethereum-provider` + +- **Description**: A drop-in EIP-1193 provider that authenticates users via [Flow Client Library (FCL)] and lets them sign transactions and messages with their COA. +- **Use Cases**: + - Integrate Flow EVM with any generic EVM library or framework. + - Direct control over JSON-RPC calls (for example, `provider.request({ method: 'eth_sendTransaction' })`). +- **Link to Docs**: [Read the @onflow/fcl-ethereum-provider Reference »] + +## `@onflow/fcl-wagmi-adapter` + +- **Description**: A Wagmi connector that uses `@onflow/fcl-ethereum-provider` under the hood so you can sign in with your COA through standard Wagmi flows. +- **Use Cases**: + - Add Flow-based COAs to a current Wagmi-powered dApp as if they were Ethereum wallets. +- **Link to Docs**: [Read the @onflow/fcl-wagmi-adapter Reference »] + +## `@onflow/fcl-rainbowkit-adapter` + +- **Description**: A RainbowKit adapter that surfaces a Flow-based wallet in the wallet selection modal, wheich makes it easy to sign transactions via COAs in a RainbowKit environment. +- **Use Cases**: + - Offer Flow-based wallets (such as Flow Wallet) alongside popular Ethereum wallets in RainbowKit. +- **Link to Docs**: [Read the @onflow/fcl-rainbowkit-adapter Reference »] + + + +[FCL Ethereum Provider for Cross-VM Apps FLIP #316]: https://github.com/onflow/flips/blob/c0fe9b71a9afb85fe70a69cf7c0870b5d327e679/application/20241223-fcl-ethereum-provider.md +[@onflow/fcl-ethereum-provider]: #onflowfcl-ethereum-provider +[@onflow/fcl-wagmi-adapter]: #onflowfcl-wagmi-adapter +[@onflow/fcl-rainbowkit-adapter]: #onflowfcl-rainbowkit-adapter +[Flow Client Library (FCL)]: https://developers.flow.com/ +[Read the @onflow/fcl-ethereum-provider Reference »]: ethereum-provider.mdx +[Read the @onflow/fcl-wagmi-adapter Reference »]: wagmi-adapter.mdx +[Read the @onflow/fcl-rainbowkit-adapter Reference »]: rainbowkit-adapter.mdx \ No newline at end of file diff --git a/docs/tools/clients/fcl-js/cross-vm/rainbowkit-adapter.mdx b/docs/build/tools/clients/fcl-js/cross-vm/rainbowkit-adapter.mdx similarity index 71% rename from docs/tools/clients/fcl-js/cross-vm/rainbowkit-adapter.mdx rename to docs/build/tools/clients/fcl-js/cross-vm/rainbowkit-adapter.mdx index 193efa58af..d1f7c5737a 100644 --- a/docs/tools/clients/fcl-js/cross-vm/rainbowkit-adapter.mdx +++ b/docs/build/tools/clients/fcl-js/cross-vm/rainbowkit-adapter.mdx @@ -26,7 +26,7 @@ Below is a typical usage example that shows how to set up a **RainbowKit** confi ```ts import * as fcl from '@onflow/fcl' -import { createFclConnector, flowWallet } from '@onflow/fcl-rainbowkit-adapter' +import { createFclConnector, flowWallet, useIsCadenceWalletConnected } from '@onflow/fcl-rainbowkit-adapter' import { connectorsForWallets } from '@rainbow-me/rainbowkit' import { flowTestnet } from 'wagmi/chains' import { createConfig, http } from 'wagmi' @@ -60,6 +60,21 @@ export const config = createConfig({ [flowTestnet.id]: http(), } }); + +// In your React component +function MyApp() { + const isCadenceConnected = useIsCadenceWalletConnected(config) + + return ( +
+ {isCadenceConnected ? ( +

Cadence wallet is connected!

+ ) : ( +

Please connect your Cadence wallet

+ )} +
+ ) +} ``` ## API @@ -73,7 +88,15 @@ export const config = createConfig({ ### `createFclConnector(config?: CreateFclConnectorOptions): Connector` -- A lower-level helper to build your own FCL-based EIP-1193 connectors for RainbowKit if you don’t want the preconfigured `flowWallet`. +- A lower-level helper to build your own FCL-based EIP-1193 connectors for RainbowKit if you don't want the preconfigured `flowWallet`. - **Parameters** - `config?: CreateFclConnectorOptions` – typical Wagmi + FCL config object (i.e., chain ID, network URL, FCL services, etc.). -- **Returns**: A valid Wagmi `Connector` for EVM interactions via FCL. \ No newline at end of file +- **Returns**: A valid Wagmi `Connector` for EVM interactions via FCL. + +### `useIsCadenceWalletConnected(config: Config): boolean` + +A React hook that monitors the connection status of both FCL (Cadence) and Wagmi accounts to determine whether a Cadence-aware wallet is connected. + +- **Parameters** + - `config: Config` – The Wagmi configuration object +- **Returns**: `boolean` – `true` when both Cadence-aware wallet is connected, `false` if no wallet, or an EVM-only wallet is connected. \ No newline at end of file diff --git a/docs/tools/clients/fcl-js/cross-vm/wagmi-adapter.mdx b/docs/build/tools/clients/fcl-js/cross-vm/wagmi-adapter.mdx similarity index 100% rename from docs/tools/clients/fcl-js/cross-vm/wagmi-adapter.mdx rename to docs/build/tools/clients/fcl-js/cross-vm/wagmi-adapter.mdx diff --git a/docs/build/tools/clients/fcl-js/discovery.md b/docs/build/tools/clients/fcl-js/discovery.md new file mode 100644 index 0000000000..c590364930 --- /dev/null +++ b/docs/build/tools/clients/fcl-js/discovery.md @@ -0,0 +1,289 @@ +--- +title: Wallet Discovery +--- + +## Wallet Discovery + +It's a challenge to know all the wallets available to users on a blockchain. Flow Client Library's (FCL) Discovery mechanism relieves much of the burden of Flow compatible wallet integration and lets developers focus on building their dApp and providing as many options as possible to their users. + +There are two ways an app can use Discovery: + +1. The **UI version** which can be configured for display via iFrame, Popup, or Tab. +2. The **API version** which allows you to access authentication services directly in your code via `fcl.discovery.authn` method which we'll describe below. + +## UI version + +When a user authenticates via FCL with Discovery UI, they receive a list of services they can use to login. + +![FCL Default Discovery UI](./images/discovery.png) + +This method is the simplest way to integrate Discovery and its wallets and services into your app. All you have to do is configure `discovery.wallet` with the host endpoint for testnet or mainnet. + +:::info + +Opt-in wallets, like Ledger and Dapper Wallet, require you to explicitly state you'd like to use them. For more information on how to include opt-in wallets, [see these docs]. + +A [Dapper Wallet] developer account is required. To turn on Dapper Wallet inside FCL, you need to [follow this guide]. + +::: + +```javascript +import { config } from '@onflow/fcl'; + +config({ + 'accessNode.api': 'https://rest-testnet.onflow.org', + 'discovery.wallet': 'https://fcl-discovery.onflow.org/testnet/authn', +}); +``` + +Any time you call `fcl.authenticate` the user will be presented with that screen. + +To change the default view from iFrame to popup or tab set `discovery.wallet.method` to `POP/RPC` (opens as a popup) or `TAB/RPC` (opens in a new tab). For more info about service methods, see [here]. + +### Branding Discovery UI + +As of version 0.0.79-alpha.4, dApps can now display an app title and app icon in the Discovery UI when you a few values in their FCL app config. This branding provides users with messaging that has clear intent before they authenticate to add a layer of trust. + +All you have to do is set `app.detail.icon` and `app.detail.title` like this: + +```javascript +import { config } from '@onflow/fcl'; + +config({ + 'app.detail.icon': 'https://placekitten.com/g/200/200', + 'app.detail.title': 'Kitten Dapp', +}); +``` + +:::info + +If these configuration options aren't set, dApps that use the Discovery API will still display a default icon and "Unknown App" as the title when they attempt to authorize a user who is not logged in. We highly recommended that you set these values accurately before you go live. + +## API version + +If you want more control over your authentication UI, the Discovery API is also simple to use as it exposes Discovery directly in your code via `fcl`. + +Setup still requires configuration of the Discovery endpoint, but when you use the API, it is set via `discovery.authn.endpoint` as shown below. + +```javascript +import { config } from '@onflow/fcl'; + +config({ + 'accessNode.api': 'https://rest-testnet.onflow.org', + 'discovery.authn.endpoint': + 'https://fcl-discovery.onflow.org/api/testnet/authn', +}); +``` + +You can access services in your Dapp from `fcl.discovery`: + +```javascript +import * as fcl from '@onflow/fcl'; + +fcl.discovery.authn.subscribe(callback); + +// OR + +fcl.discovery.authn.snapshot(); +``` + +To authenticate with a service (for example, when a user click's "login"), pass the selected service to the `fcl.authenticate` method described in [the API reference]: + +```jsx +fcl.authenticate({ service }); +``` + +A simple React component may end up looking like this: + +```jsx +import './config'; +import { useState, useEffect } from 'react'; +import * as fcl from '@onflow/fcl'; + +function Component() { + const [services, setServices] = useState([]); + useEffect( + () => fcl.discovery.authn.subscribe((res) => setServices(res.results)), + [], + ); + + return ( +
+ {services.map((service) => ( + + ))} +
+ ); +} +``` + +Helpful fields for your UI can be found in the `provider` object inside of the service. Fields include the following: + +```json +{ + ..., + "provider": { + "address": "0xf086a545ce3c552d", + "name": "Blocto", + "icon": "/images/blocto.png", + "description": "Your entrance to the blockchain world.", + "color": "#afd8f7", + "supportEmail": "support@blocto.app", + "authn_endpoint": "https://flow-wallet-testnet.blocto.app/authn", + "website": "https://blocto.portto.io" + } +} +``` + +## Network configuration + +### Discovery UI URLs + +| Environment | Example | +| ----------- | ------------------------------------------------ | +| Mainnet | `https://fcl-discovery.onflow.org/authn` | +| Testnet | `https://fcl-discovery.onflow.org/testnet/authn` | +| Local | `https://fcl-discovery.onflow.org/local/authn` | + +### Discovery API endpoints + +| Environment | Example | +| ----------- | ---------------------------------------------------- | +| Mainnet | `https://fcl-discovery.onflow.org/api/authn` | +| Testnet | `https://fcl-discovery.onflow.org/api/testnet/authn` | +| Local | `https://fcl-discovery.onflow.org/api/local/authn` | + +:::info + +Local will return [Dev Wallet] on emulator for local development with the default port of 8701. If you'd like to override the default port, add `?port=0000` and set the port to whatever you'd like to override it to. + +::: + +## Other configuration + +:::info + +Configuration works across both UI and API versions of Discovery. + +::: + +### Include opt-in wallets + +**Start in FCL v0.0.78-alpha.10** + +Opt-in wallets are those that don't have support for authentication, authorization, and user signature services. Or, support only a limited set of transactions. + +You can include opt-in wallets with either **wallet UIDs** (recommended) or service account addresses: + +**Use wallet UIDs (recommended):** + +```javascript +import * as fcl from '@onflow/fcl'; + +fcl.config({ + 'discovery.wallet': 'https://fcl-discovery.onflow.org/testnet/authn', + 'discovery.authn.endpoint': + 'https://fcl-discovery.onflow.org/api/testnet/authn', + 'discovery.authn.include': ['dapper-wallet', 'ledger'], // Wallet UIDs +}); +``` + +**Use service Aacount addresses:** + +```javascript +import * as fcl from '@onflow/fcl'; + +fcl.config({ + 'discovery.wallet': 'https://fcl-discovery.onflow.org/testnet/authn', + 'discovery.authn.endpoint': + 'https://fcl-discovery.onflow.org/api/testnet/authn', + 'discovery.authn.include': ['0x82ec283f88a62e65', '0x9d2e44203cb13051'], // Testnet addresses +}); +``` + +**Opt-In Wallet Identifiers** + +| Wallet | Wallet UID | Mainnet Address | Testnet Address | +| ------------- | --------------- | ------------------ | ------------------ | +| Dapper Wallet | `dapper-wallet` | 0xead892083b3e2c6c | 0x82ec283f88a62e65 | +| Ledger | `ledger` | 0xe5cd26afebe62781 | 0x9d2e44203cb13051 | + +To learn more about other possible configurations, check out the [Discovery Github Repo]. + +### Exclude wallets + +To exclude wallets from FCL Discovery, you can use the `discovery.authn.exclude` configuration option. You can specify wallets with either **wallet UIDs** (recommended) or service account addresses: + +**Use wallet UIDs (recommended):** + +```javascript +import * as fcl from '@onflow/fcl'; + +fcl.config({ + 'discovery.wallet': 'https://fcl-discovery.onflow.org/testnet/authn', + 'discovery.authn.endpoint': + 'https://fcl-discovery.onflow.org/api/testnet/authn', + 'discovery.authn.exclude': ['nufi'], // Wallet UIDs to exclude +}); +``` + +**Use service account addresses:** + +```javascript +import * as fcl from '@onflow/fcl'; + +fcl.config({ + 'discovery.wallet': 'https://fcl-discovery.onflow.org/testnet/authn', + 'discovery.authn.endpoint': + 'https://fcl-discovery.onflow.org/api/testnet/authn', + 'discovery.authn.exclude': ['0x123', '0x456'], // Service account addresses to exclude +}); +``` + +**Available wallet UIDs** + +You can use any of the following wallet identifiers with `discovery.authn.include` or `discovery.authn.exclude`: + +| Wallet | UID | Mainnet Address | Testnet Address | Type | +| ------------- | --------------- | ------------------ | ------------------ | ------- | +| Flow Wallet | `flow-wallet` | 0x33f75ff0b830dcec | 0x33f75ff0b830dcec | Default | +| NuFi | `nufi` | 0x95b85a9ef4daabb1 | - | Default | +| Blocto | `blocto` | 0x55ad22f01ef568a1 | 0x55ad22f01ef568a1 | Default | +| Dapper Wallet | `dapper-wallet` | 0xead892083b3e2c6c | 0x82ec283f88a62e65 | Opt-in | +| Ledger | `ledger` | 0xe5cd26afebe62781 | 0x9d2e44203cb13051 | Opt-in | + +:::info + +Default wallets appear in Discovery by default. Opt-in wallets must be explicitly included with `discovery.authn.include`. You can use either the wallet UID or the service account address to filter. + +For the most up-to-date list of available wallets, see the [fcl-discovery wallet data] in the official repository. + +::: + +### WalletConnect configuration + +To configure WalletConnect, add a WalletConnect project ID to the FCL config: + +```javascript +import * as fcl from '@onflow/fcl'; + +fcl.config({ + 'walletconnect.projectId': 'YOUR_WALLETCONNECT_PROJECT_ID', +}); +``` + + + +[see these docs]: ./packages-docs/fcl/index.md#configuration +[Dapper Wallet]: https://meetdapper.com/developers +[follow this guide]: https://docs.meetdapper.com/quickstart +[here]: https://github.com/onflow/fcl-js/blob/9bce741d3b32fde18b07084b62ea15f9bbdb85bc/packages/fcl/src/wallet-provider-spec/draft-v3.md +[the API reference]: ./packages-docs/fcl/authenticate.md +[Dev Wallet]: https://github.com/onflow/fcl-dev-wallet +[Discovery Github Repo]: https://github.com/onflow/fcl-discovery +[fcl-discovery wallet data]: https://github.com/onflow/fcl-discovery/tree/master/data/wallets \ No newline at end of file diff --git a/docs/tools/clients/fcl-js/images/discovery.png b/docs/build/tools/clients/fcl-js/images/discovery.png similarity index 100% rename from docs/tools/clients/fcl-js/images/discovery.png rename to docs/build/tools/clients/fcl-js/images/discovery.png diff --git a/docs/tools/clients/fcl-js/images/wc-discovery.png b/docs/build/tools/clients/fcl-js/images/wc-discovery.png similarity index 100% rename from docs/tools/clients/fcl-js/images/wc-discovery.png rename to docs/build/tools/clients/fcl-js/images/wc-discovery.png diff --git a/docs/build/tools/clients/fcl-js/index.md b/docs/build/tools/clients/fcl-js/index.md new file mode 100644 index 0000000000..acd1ebcb1b --- /dev/null +++ b/docs/build/tools/clients/fcl-js/index.md @@ -0,0 +1,257 @@ +--- +sidebar_position: 3 +--- + +# Flow Client Library (FCL) + +:::info + +If you want to build a frontend, use the [React SDK]. If you're familiar with Solidity and the EVM world, the [React SDK] is to wagmi as FCL is to viem. + +::: + +## What is FCL? + +The **Flow Client Library (FCL) JS** is a package designed to facilitate interactions between apps, wallets, and the Flow blockchain. It provides a standardized way for applications to connect with users and their wallets, **eliminating the need for custom integrations**. + +### Key Features: + +- **Universal Wallet Support** Works seamlessly with all FCL-compatible wallets, which makes authentication simple. +- **Secure Authentication** Standardized authentication flow ensures a smooth user experience. +- **Blockchain Interactions** Allows querying, mutating, and interacting with smart contracts on Flow. +- **Full-Featured Utilities** Offers built-in functions to streamline blockchain development. +- **Flexible Environment** Can run in both browser and server environments, though wallet interactions are browser-only. + +FCL was created to make building Flow-connected applications **easy, secure, and scalable** by defining **standardized communication patterns** between wallets, applications, and users. + +For iOS, we also offer [FCL Swift]. + +--- + +## Get started + +### Requirements + +- Node version `v12.0.0 or higher`. + +### Installation + +To use the FCL JS in your application, install with **yarn** or **npm** + +```shell +npm i -S @onflow/fcl +``` + +```shell +yarn add @onflow/fcl +``` + +#### Import +**ES6** + +```js +import * as fcl from '@onflow/fcl'; +``` + +**Node.js** + +```js +const fcl = require('@onflow/fcl'); +``` + +--- + +## FCL for dApps + +#### Wallet interactions + +- _Wallet Discovery_ and _Sign-up/Login_: Onboard users with ease. Never worry about how to support multiple wallets. + Authenticate users with any [FCL compatible wallet]. + +```js +// in the browser +import * as fcl from '@onflow/fcl'; + +fcl.config({ + 'discovery.wallet': 'https://fcl-discovery.onflow.org/testnet/authn', // Endpoint set to Testnet +}); + +fcl.authenticate(); +``` + +:::info + +For advanced configuration patterns including scoped clients and multi-tenancy, see the [`createFlowClient` reference documentation]. + +![FCL Default Discovery UI](images/discovery.png) + +A [Dapper Wallet] developer account is required. + +- _Interact with smart contracts_: Authorize transactions via the user's chosen wallet. +- _Prove ownership of a wallet address_: Sign and verify user signed data. + +::: + +#### Blockchain interactions + +- _Query the chain_: Send arbitrary Cadence scripts to the chain and receive back decoded values + +```js +import * as fcl from '@onflow/fcl'; + +const result = await fcl.query({ + cadence: ` + access(all) + fun main(a: Int, b: Int, addr: Address): Int { + log(addr) + return a + b + } + `, + args: (arg, t) => [ + arg(7, t.Int), // a: Int + arg(6, t.Int), // b: Int + arg('0xba1132bc08f82fe2', t.Address), // addr: Address + ], +}); +console.log(result); // 13 +``` + +- _Mutate the chain_: Send arbitrary transactions with your own signatures or via a user's wallet to perform state changes on chain. + +```js +import * as fcl from '@onflow/fcl'; +// in the browser, FCL will automatically connect to the user's wallet to request signatures to run the transaction +const txId = await fcl.mutate({ + cadence: ` + import Profile from 0xba1132bc08f82fe2 + + transaction(name: String) { + prepare(account: AuthAccount) { + account.borrow<&{Profile.Owner}>(from: Profile.privatePath)!.setName(name) + } + } + `, + args: (arg, t) => [arg('myName', t.String)], +}); +``` + +#### Utilities + +- Get account details from any Flow address +- Get the latest block +- Transaction status polling +- Event polling +- Custom authorization functions + +## Typescript support + +FCL JS supports TypeScript. If you need to import specific types, you can do so via the [@onflow/typedefs] package. + +```typescript +import { CurrentUser } from '@onflow/typedefs'; + +const newUser: CurrentUser = { + addr: null, + cid: null, + expiresAt: null, + f_type: 'User', + f_vsn: '1.0.0', + loggedIn: null, + services: [], +}; +``` + +For all type definitions available, see [this file] + +## Next Steps + +- See the [Flow App Quick Start]. +- See the full [API Reference] for all FCL functionality. +- Learn Flow's smart contract language to build any script or transactions: [Cadence]. +- Explore all of Flow [docs and tools]. + +--- + +## FCL for wallet providers + +Wallet providers on Flow have the flexibility to build their user interactions and UI through a variety of ways: + +- Front channel communication via Iframe, pop-up, tab, or extension. +- Back channel communication via HTTP. + +FCL is agnostic to the communication channel and be configured to create both custodial and non-custodial wallets. This allows users to interact with wallet providers without the need to download an app or extension. + +The communication channels involve responding to a set of pre-defined FCL messages to deliver the requested information to the dApp. To implement a FCL compatible wallet on Flow is as simple as filling in the responses with the appropriate data when FCL requests them. If you use any of the front-channel communication methods, FCL also provides a set of [wallet utilities] to simplify this process. + +### Current wallet providers + +- [Flow Wallet] +- [NuFi Wallet] +- [Blocto] +- [Ledger] (limited transaction support) +- [Dapper Wallet] + +### Wallet discovery + +It can be difficult to get users to discover new wallets on a chain. To solve this, we created a [wallet discovery service] that can be configured and accessed through FCL to display all available Flow wallet providers to the user. This means: + +- dApps can display and support all FCL compatible wallets that launch on Flow without the need to change any code. +- Users don't need to sign up for new wallets - they can carry over their current one to any dApp that uses FCL for authentication and authorization. + +The discovery feature can be used via API allowing you to customize your own UI or you can use the default UI without any additional configuration. + +:::info + +To get your wallet added to the discovery service, make a PR in [fcl-discovery]. + +::: + +### Build a FCL compatible wallet + +- Read the [wallet guide] to understand the implementation details. +- Review the architecture of the [FCL dev wallet] for an overview. +- If you want to build a non-custodial wallet, see the [Account API] and the [FLIP] on derivation paths and key generation. + +--- + +## 🛠 Want to use the Flow SDK directly? + +If you prefer to interact with Flow at a **lower level** without FCL, you can use the [Flow JavaScript SDK] directly. The SDK provides raw access to Flow's API to send transactions, execute scripts, and manage accounts. + +FCL is built **on top of the Flow SDK**, which makes it easier to handle authentication, wallet interactions, and dApp connectivity. Choose the approach that best fits your use case. + +## Support + +- Notice a problem or want to request a feature? [Add an issue]. +- Join the Flow community on [Discord] to keep up to date and to talk to the team. +- Read the [Contributing Guide] to learn how to contribute to the project. + + + +[React SDK]: ../../react-sdk/index.mdx +[FCL Swift]: https://github.com/Outblock/fcl-swift +[FCL compatible wallet]: #current-wallet-providers +[`createFlowClient` reference documentation]: ./packages-docs/fcl/createFlowClient.md +[Dapper Wallet]: https://meetdapper.com/developers +[@onflow/typedefs]: https://github.com/onflow/fcl-js/tree/master/packages/typedefs +[this file]: https://github.com/onflow/fcl-js/blob/master/packages/typedefs/src/index.ts +[Flow App Quick Start]: ../../../../blockchain-development-tutorials/cadence/getting-started/index.md +[API Reference]: ./packages-docs/fcl/index.md +[Cadence]: https://cadence-lang.org +[docs and tools]: https://developers.flow.com +[wallet utilities]: https://github.com/onflow/fcl-js/blob/master/packages/fcl-core/src/wallet-utils/index.js +[Flow Wallet]: https://wallet.flow.com/ +[NuFi Wallet]: https://nu.fi/ +[Blocto]: https://blocto.portto.io/en/ +[Ledger]: https://ledger.com +[Dapper Wallet]: https://www.meetdapper.com/ +[wallet discovery service]: https://github.com/onflow/fcl-discovery +[fcl-discovery]: https://github.com/onflow/fcl-discovery +[wallet guide]: https://github.com/onflow/fcl-js/blob/master/packages/fcl-core/src/wallet-provider-spec/draft-v4.md +[FCL dev wallet]: https://github.com/onflow/fcl-dev-wallet +[Account API]: https://github.com/onflow/flow-account-api +[FLIP]: https://github.com/onflow/flow/pull/727 +[Flow JavaScript SDK]: ./packages-docs/sdk/index.md +[Add an issue]: https://github.com/onflow/fcl-js/issues +[Discord]: https://discord.gg/flow +[Contributing Guide]: https://github.com/onflow/fcl-js/blob/master/CONTRIBUTING.md \ No newline at end of file diff --git a/docs/build/tools/clients/fcl-js/installation.mdx b/docs/build/tools/clients/fcl-js/installation.mdx new file mode 100644 index 0000000000..657241d9a1 --- /dev/null +++ b/docs/build/tools/clients/fcl-js/installation.mdx @@ -0,0 +1,35 @@ +# Installation + +This chapter explains the installation of the Flow CLient Library (FCL) JS library in your system. However, before we move to the installation, let's verify the prerequisite first. + +## Prerequisite +- Node.js version v12.0.0 or higher. + +FCL JS depends on Node.js version v12.0.0 or higher. You can check your currently-installed version with the below command: + +```javascript +node --version +``` + +If Node.js is not installed on your system, you can visit [Node.js Download](https://nodejs.org/en/download/) to download and install it. + + +Install FCL JS with **npm** or **yarn** + +```shell +npm i -S @onflow/fcl +``` + +```shell +yarn add @onflow/fcl +``` +#### Importing + +**ES6** +```js +import * as fcl from "@onflow/fcl"; +``` +**Node.js** +```js +const fcl = require("@onflow/fcl"); +``` diff --git a/docs/tools/clients/fcl-js/interaction-templates.mdx b/docs/build/tools/clients/fcl-js/interaction-templates.mdx similarity index 79% rename from docs/tools/clients/fcl-js/interaction-templates.mdx rename to docs/build/tools/clients/fcl-js/interaction-templates.mdx index c628a3fcb6..d3c2437ce0 100644 --- a/docs/tools/clients/fcl-js/interaction-templates.mdx +++ b/docs/build/tools/clients/fcl-js/interaction-templates.mdx @@ -12,23 +12,23 @@ title: Interaction Templates Interaction Templates establish a format for metadata that exists about an interaction. Interaction Templates can include: -- Human readable, internationalized messages about the interaction -- The Cadence code to carry out the interaction -- Information about arguments such as internationalized human readable messages and what the arguments act upon -- Contract dependencies the Interaction engages with, pinned to a version of them and their dependency tree +- Human readable, internationalized messages about the interaction. +- The Cadence code to carry out the interaction. +- Information about arguments such as internationalized human readable messages and what the arguments act upon. +- Contract dependencies the Interaction engages with, pinned to a version of them and their dependency tree. -Applications and Wallets can use Interaction Templates and it's interaction metadata. +Applications and Wallets can use Interaction Templates and its interaction metadata. -For example Applications and Wallets can extract the internationalized human readable messaging from an Interaction Template to display to their users prior to execution of the interaction. +For example, Applications and Wallets can extract the internationalized human readable messaging from an Interaction Template to display to their users prior to execution of the interaction. ## For Applications -FCL `mutate` and `query` can accept an Interaction Template. FCL `mutate` and `query` will use the Interaction Template to: +Flow Client Library (FCL) `mutate` and `query` can accept an Interaction Template. FCL `mutate` and `query` will use the Interaction Template to: -- Extract the Cadence code to carry out the interaction -- Extract dependency configuration for the interaction (eg: Information about contract import addresses) +- Extract the Cadence code to carry out the interaction. +- Extract dependency configuration for the interaction (for example, Information about contract import addresses) -Here is an example of using `mutate` with an Interaction Template: +Here is an example of how to use `mutate` with an Interaction Template: ```javascript import * as fcl from "@onflow/fcl" import myTransactionTemplate from "./my-transaction-template.template.json" @@ -63,11 +63,11 @@ const nftInfo = await fcl.query({ }) ``` -FCL will resolve the template from the remote location before using it to execute its underlying transaction or script. +FCL will resolve the template from the remote location before it uses it to execute its underlying transaction or script. -> 💡 By requesting an Interaction Template from an external location, applications have a mechanism to always retrieve the most up to date way of accomplishing an interaction. +> 💡 When apps use an Interaction Template from an external location, they have a mechanism to always retrieve the most up to date way of accomplishing an interaction. -By default FCL supports resolving Interaction Templates over http/https, but FCL can also be configured with various other ways to resolve Interaction Templates: +By default, FCL supports resolving Interaction Templates over http or https, but FCL can also be configured with various other ways to resolve Interaction Templates: ```javascript import * as fcl from "@onflow/fcl" @@ -85,11 +85,11 @@ const txId = await fcl.mutate({ ## For Wallets Wallets can use Interaction Templates to: -- Display internationalized human readable information about a transaction to their users during signing -- Verify the dependencies of an Interaction Template have not changed since when the Interaction Template was created -- Using Interaction Template Audits, gain confidence in the correctness and safety of an Interaction Template and it's underlying transaction +- Display internationalized human readable information about a transaction to their users during signing. +- Verify the dependencies of an Interaction Template have not changed since when the Interaction Template was created. +- With Interaction Template Audits, gain confidence in the correctness and safety of an Interaction Template and it's underlying transaction. -When recieving a transaction to sign, wallets can query for an Interaction Template that corresponds to it. +When wallets receive a transaction to sign, they can query for an Interaction Template that corresponds to it. Flow operates an "Interaction Template Discovery Service" which wallets can use to query for Interaction Templates. Anyone can run an "Interaction Template Discovery Service" and wallets can choose to query from any of them. @@ -118,9 +118,9 @@ const interactionTemplate = await fetch( > ❗️ Not all transactions will have a corresponding Interaction Template. Wallets are encouraged to always support signing transactions that do not have a corresponding Interaction Template, or if they fail to discover one. -Once a wallet has a corresponding Interaction Template for a given transaction, they may also may wish to verify that the transaction it represents is safe to sign, and that the Interaction Template is accurate for that transaction. +When a wallet has a corresponding Interaction Template for a given transaction, they may also may wish to verify that the transaction it represents is safe to sign, and that the Interaction Template is accurate for that transaction. -To do so, wallets can rely on themselves, along with external Interaction Template Auditors to gain confidence in the Interaction Template and it's underlying transaction. Interaction Template Auditors are entities that audit Interaction Templates for correctness and safety. +To do so, wallets can rely on themselves, along with external Interaction Template Auditors to gain confidence in the Interaction Template and its underlying transaction. Interaction Template Auditors are entities that audit Interaction Templates for correctness and safety. > 💡 Anyone can be an Interaction Template Auditor. Wallets can choose auditors they trust, if any. @@ -184,7 +184,7 @@ const hasDependencyTreeChanged = await fcl.InteractionTemplateUtils If the dependency tree has changed, wallets may choose to disregard the Interaction Template (and it's audits). -Once the Interaction Template has been sufficiently audited by auditors the wallet trusts, and it's dependency tree determined unchanged since the interaction was created and audited against, then the wallet can use the Interaction Template with greater confidence in it's correctness and safety. +After auditors that the wallet trusts sufficiently audits the Interaction Template, and it's dependency tree determined unchanged since the interaction was created and audited against, then the wallet can use the Interaction Template with greater confidence in its correctness and safety. The wallet may then decide to render human readable information about the transaction such as: - Internationalized 'title' and 'description' of the transaction diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/account.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/account.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/account.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/account.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/arg.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/arg.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/arg.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/arg.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/args.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/args.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/args.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/args.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/atBlockHeight.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/atBlockHeight.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/atBlockHeight.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/atBlockHeight.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/atBlockId.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/atBlockId.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/atBlockId.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/atBlockId.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/authenticate.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/authenticate.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/authenticate.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/authenticate.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/authorization.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/authorization.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/authorization.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/authorization.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/authorizations.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/authorizations.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/authorizations.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/authorizations.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/authz.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/authz.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/authz.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/authz.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/block.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/block.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/block.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/block.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/build.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/build.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/build.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/build.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/cadence.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/cadence.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/cadence.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/cadence.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/cdc.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/cdc.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/cdc.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/cdc.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/config.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/config.md similarity index 75% rename from docs/tools/clients/fcl-js/packages-docs/fcl/config.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/config.md index 04a3f90892..21fe3831ab 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/config.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/config.md @@ -43,7 +43,18 @@ Record ## Returns ```typescript -{ put: typeof put; get: typeof get; all: typeof all; first: typeof first; update: typeof update; delete: typeof _delete; where: typeof where; subscribe: typeof subscribe; overload: typeof overload; load: typeof load; } +{ + put: typeof put; + get: typeof get; + all: typeof all; + first: typeof first; + update: typeof update; + delete: typeof _delete; + where: typeof where; + subscribe: typeof subscribe; + overload: typeof overload; + load: typeof load; +} ``` diff --git a/docs/build/tools/clients/fcl-js/packages-docs/fcl/createFlowClient.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/createFlowClient.md new file mode 100644 index 0000000000..730ad575bd --- /dev/null +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/createFlowClient.md @@ -0,0 +1,166 @@ +--- +title: "createFlowClient" +description: "createFlowClient function documentation." +--- + + + +# createFlowClient + +Creates a Flow client instance with scoped configuration. + +This function decouples FCL functions from the global state and constructs a new SDK client +instance bound to a custom context. This allows for better modularity and supports multiple +FCL instances in the same application, each with their own isolated configuration and state. + +Benefits of scoped configuration: +- **Isolation**: Each client has its own configuration, storage, and state +- **Multi-tenancy**: Connect to different Flow networks simultaneously +- **Type Safety**: Configuration is validated at compile time via TypeScript +- **Testing**: Easy to create isolated client instances for testing + +## Import + +You can import the entire package and access the function: + +```typescript +import * as fcl from "@onflow/fcl" + +fcl.createFlowClient(params) +``` + +Or import directly the specific function: + +```typescript +import { createFlowClient } from "@onflow/fcl" + +createFlowClient(params) +``` + +## Usage + +```typescript +// Multiple isolated clients for different networks +import { createFlowClient } from "@onflow/fcl" + +const mainnetClient = createFlowClient({ + accessNodeUrl: "https://rest-mainnet.onflow.org", + flowNetwork: "mainnet", + appDetailTitle: "My App (Mainnet)", +}) + +const testnetClient = createFlowClient({ + accessNodeUrl: "https://rest-testnet.onflow.org", + flowNetwork: "testnet", + appDetailTitle: "My App (Testnet)", +}) + +// Query both networks simultaneously +const [mainnetBlock, testnetBlock] = await Promise.all([ + mainnetClient.query({ + cadence: `access(all) fun main(): UInt64 { return getCurrentBlock().height }`, + }), + testnetClient.query({ + cadence: `access(all) fun main(): UInt64 { return getCurrentBlock().height }`, + }), +]) +``` + +## Parameters + +### `params` + + +- Type: +```typescript +export interface FlowClientConfig { + accessNodeUrl: string + flowNetwork?: string + flowJson?: any + discoveryWallet?: string + discoveryWalletMethod?: string + discoveryAuthnEndpoint?: string + discoveryAuthnInclude?: string[] + discoveryAuthnExclude?: string[] + walletconnectProjectId?: string + walletconnectDisableNotifications?: boolean + storage?: StorageProvider + appDetailTitle?: string + appDetailIcon?: string + appDetailDescription?: string + appDetailUrl?: string + serviceOpenIdScopes?: string[] + transport?: SdkTransport + computeLimit?: number + customResolver?: any + customDecoders?: any +} +``` +- Description: Configuration object for the Flow client + + +## Returns + +```typescript +{ + send: (args?: false | InteractionBuilderFn | (false | InteractionBuilderFn)[], opts?: any) => Promise; + subscribe: ({ + topic, args, onData, onError +}: SubscribeParams, opts?: { + node?: string; + transport?: SdkTransport; +}) => Subscription; + subscribeRaw: ({ + topic, args, onData, onError +}: SubscribeRawParams, opts?: { + node?: string; + transport?: SdkTransport; +}) => { + unsubscribe: () => void; +}; + account: (address: string, { + height, id, isSealed +}?: AccountQueryOptions, opts?: object) => Promise; + block: ({ + sealed, id, height +}?: BlockQueryOptions, opts?: object) => Promise; + resolve: (ix: Interaction) => Promise; + decode: (response: any) => Promise; + currentUser: CurrentUserServiceApi; + mutate: (opts?: MutateOptions) => Promise; + query: (opts?: QueryOptions) => Promise; + queryRaw: (opts?: QueryOptions) => Promise; + verifyUserSignatures: (message: string, compSigs: CompositeSignature[], opts?: VerifySignaturesScriptOptions) => Promise; + getChainId: (opts?: GetChainIdOptions) => Promise; + tx: { + (transactionId: string, opts?: { + pollRate?: number; + txNotFoundTimeout?: number; +}): { + snapshot: () => Promise; + subscribe: (onData: (txStatus: TransactionStatus) => void, onError?: (err: Error) => void) => () => void; + onceFinalized: () => Promise; + onceExecuted: () => Promise; + onceSealed: () => Promise; +}; + isUnknown: (ix: Interaction) => boolean; + isPending: (tx: TransactionStatus) => boolean; + isFinalized: (tx: TransactionStatus) => boolean; + isExecuted: (tx: TransactionStatus) => boolean; + isSealed: (tx: TransactionStatus) => boolean; + isExpired: (tx: TransactionStatus) => boolean; +}; + events: (filterOrType?: string | EventFilter) => { + subscribe: (onData: (event: Event) => void, onError?: (error: Error) => void) => () => void; +}; + authenticate: (opts?: AuthenticationOptions) => Promise; + unauthenticate: () => void; + signUserMessage: (msg: string) => Promise; + serialize: (args: (false | InteractionBuilderFn)[] | Interaction, opts?: SerializeOptions) => Promise; +} +``` + + +A Flow client object with methods for interacting with the Flow blockchain + +--- \ No newline at end of file diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/createSignableVoucher.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/createSignableVoucher.md similarity index 82% rename from docs/tools/clients/fcl-js/packages-docs/fcl/createSignableVoucher.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/createSignableVoucher.md index 19d76dced3..db26af0365 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/createSignableVoucher.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/createSignableVoucher.md @@ -75,7 +75,25 @@ console.log(voucher.authorizers); // List of authorizer addresses ## Returns ```typescript -{ cadence: string; refBlock: string; computeLimit: number; arguments: any[]; proposalKey: { address: string; keyId: string | number; sequenceNum: number; } | { address?: undefined; keyId?: undefined; sequenceNum?: undefined; }; payer: string; authorizers: string[]; payloadSigs: { address: string; keyId: string | number; sig: string; }[]; envelopeSigs: { address: string; keyId: string | number; sig: string; }[]; } +{ + cadence: string; + refBlock: string; + computeLimit: number; + arguments: any[]; + proposalKey: { + address: string; + keyId: string | number; + sequenceNum: number; +} | { + address?: undefined; + keyId?: undefined; + sequenceNum?: undefined; +}; + payer: string; + authorizers: string[]; + payloadSigs: any[]; + envelopeSigs: any[]; +} ``` diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/currentUser.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/currentUser.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/currentUser.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/currentUser.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/decode.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/decode.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/decode.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/decode.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/display.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/display.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/display.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/display.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/events.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/events.md similarity index 89% rename from docs/tools/clients/fcl-js/packages-docs/fcl/events.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/events.md index f11efa53bc..7dc9e0f450 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/events.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/events.md @@ -3,7 +3,7 @@ title: "events" description: "events function documentation." --- - + # events @@ -90,7 +90,11 @@ If an EventFilter object is provided, it can contain multiple event types and ot ## Returns -`void; }` +```typescript +{ + subscribe: (onData: (event: Event) => void, onError?: (error: Error) => void) => () => void; +} +``` An object containing a subscribe method diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/getAccount.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getAccount.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/getAccount.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/getAccount.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/getBlock.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getBlock.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/getBlock.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/getBlock.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/getBlockHeader.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getBlockHeader.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/getBlockHeader.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/getBlockHeader.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/getCollection.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getCollection.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/getCollection.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/getCollection.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/getEvents.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getEvents.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/getEvents.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/getEvents.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/getEventsAtBlockHeightRange.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getEventsAtBlockHeightRange.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/getEventsAtBlockHeightRange.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/getEventsAtBlockHeightRange.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/getEventsAtBlockIds.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getEventsAtBlockIds.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/getEventsAtBlockIds.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/getEventsAtBlockIds.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/getNetworkParameters.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getNetworkParameters.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/getNetworkParameters.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/getNetworkParameters.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/getNodeVersionInfo.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getNodeVersionInfo.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/getNodeVersionInfo.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/getNodeVersionInfo.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/getTransaction.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getTransaction.md similarity index 85% rename from docs/tools/clients/fcl-js/packages-docs/fcl/getTransaction.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/getTransaction.md index eade4a8f8b..e5dee5ac0c 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/getTransaction.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getTransaction.md @@ -3,7 +3,7 @@ title: "getTransaction" description: "getTransaction function documentation." --- - + # getTransaction diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/getTransactionStatus.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/getTransactionStatus.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/getTransactionStatus.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/getTransactionStatus.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/index.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/index.md similarity index 97% rename from docs/tools/clients/fcl-js/packages-docs/fcl/index.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/index.md index 46bd9fb598..e8abf586a4 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/index.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/index.md @@ -240,7 +240,7 @@ This section contains documentation for all of the functions and namespaces in t - [cadence](./cadence.md) - Creates a template function - [cdc](./cdc.md) - Creates a template function - [config](./config.md) - Sets the config -- [createFcl](./createFcl.md) - Creates a configured FCL (Flow Client Library) instance for web applications.... +- [createFlowClient](./createFlowClient.md) - Creates a Flow client instance with scoped configuration. This function... - [createSignableVoucher](./createSignableVoucher.md) - Creates a signable voucher object from an interaction for signing purposes. A... - [currentUser](./currentUser.md) - The main current user service for managing user authentication and authorization... - [decode](./decode.md) - Decodes the response from 'fcl.send()' into the appropriate JSON representation... @@ -249,7 +249,6 @@ This section contains documentation for all of the functions and namespaces in t - [getAccount](./getAccount.md) - A builder function that returns the interaction to get an account by address.... - [getBlock](./getBlock.md) - A builder function that returns the interaction to get the latest block. Use... - [getBlockHeader](./getBlockHeader.md) - A builder function that returns the interaction to get a block header. A block... -- [getChainId](./getChainId.md) - Gets the chain ID if its set, otherwise gets the chain ID from the access node - [getCollection](./getCollection.md) - A builder function that returns a collection containing a list of transaction... - [getEvents](./getEvents.md) - A builder function that returns the interaction to get events. Events are... - [getEventsAtBlockHeightRange](./getEventsAtBlockHeightRange.md) - A builder function that returns all instances of a particular event (by name)... @@ -284,7 +283,7 @@ This section contains documentation for all of the functions and namespaces in t - [subscribe](./subscribe.md) - Subscribe to real-time data from the Flow blockchain and automatically decode... - [subscribeEvents](./subscribeEvents.md) - Subscribe to events with the given filter and parameters. Creates a subscription... - [subscribeRaw](./subscribeRaw.md) - Subscribe to a topic without decoding the data. This function creates a raw... -- [transaction](./transaction.md) - A template builder to use a Cadence transaction for an interaction. FCL "mutate"... +- [transaction](./transaction.md) - Creates a transaction monitor that provides methods for tracking and subscribing... - [tx](./tx.md) - Creates a transaction monitor that provides methods for tracking and subscribing... - [unauthenticate](./unauthenticate.md) - Logs out the current user and sets the values on the current user object to... - [validator](./validator.md) - A builder function that adds a validator to a transaction. Validators are... diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/invariant.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/invariant.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/invariant.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/invariant.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/isBad.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/isBad.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/isBad.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/isBad.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/isOk.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/isOk.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/isOk.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/isOk.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/limit.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/limit.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/limit.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/limit.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/logIn.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/logIn.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/logIn.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/logIn.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/mutate.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/mutate.md similarity index 81% rename from docs/tools/clients/fcl-js/packages-docs/fcl/mutate.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/mutate.md index cc6b828978..3654da3a53 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/mutate.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/mutate.md @@ -1,6 +1,6 @@ --- -title: "mutate" -description: "mutate function documentation." +title: 'mutate' +description: 'mutate function documentation.' --- @@ -21,12 +21,13 @@ Cadence code that are replaced with actual addresses at execution time. It also for standardized transaction execution patterns. The mutate function accepts a configuration object with the following structure: + ```typescript { cadence?: string, // The Cadence transaction code to execute (required if template not provided) args?: Function, // Function that returns an array of arguments for the transaction template?: any, // Interaction Template object or URL for standardized transactions -limit?: number, // Compute (gas) limit for the transaction execution +limit?: number, // Compute units limit for the transaction execution authz?: AccountAuthorization, // Authorization function for all signatory roles (proposer, payer, authorizer) proposer?: AccountAuthorization, // Specific authorization function for the proposer role payer?: AccountAuthorization, // Specific authorization function for the payer role @@ -39,34 +40,34 @@ authorizations?: AccountAuthorization[] // Array of authorization functions for You can import the entire package and access the function: ```typescript -import * as fcl from "@onflow/fcl" +import * as fcl from '@onflow/fcl'; -fcl.mutate(opts) +fcl.mutate(opts); ``` Or import directly the specific function: ```typescript -import { mutate } from "@onflow/fcl" +import { mutate } from '@onflow/fcl'; -mutate(opts) +mutate(opts); ``` ## Usage ```typescript // Basic transaction submission -import * as fcl from "@onflow/fcl" +import * as fcl from '@onflow/fcl'; // Configure FCL first fcl.config({ - "accessNode.api": "https://rest-testnet.onflow.org", - "discovery.wallet": "https://fcl-discovery.onflow.org/testnet/authn", - "flow.network": "testnet" -}) + 'accessNode.api': 'https://rest-testnet.onflow.org', + 'discovery.wallet': 'https://fcl-discovery.onflow.org/testnet/authn', + 'flow.network': 'testnet', +}); // Authenticate user -await fcl.authenticate() +await fcl.authenticate(); // Submit a basic transaction const txId = await fcl.mutate({ @@ -78,31 +79,26 @@ const txId = await fcl.mutate({ } } `, - args: (arg, t) => [ - arg("Hello Flow!", t.String) - ], - limit: 50 -}) + args: (arg, t) => [arg('Hello Flow!', t.String)], + limit: 50, +}); -console.log("Transaction submitted:", txId) +console.log('Transaction submitted:', txId); ``` ## Parameters -### `opts` - +### `opts` - Type: `any` - Description: Transaction configuration options - ## Returns ```typescript -(opts?: MutateOptions) => Promise +(opts?: MutateOptions) => Promise; ``` - Promise that resolves to the transaction ID (txId) when the transaction is submitted ---- \ No newline at end of file +--- diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/nodeVersionInfo.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/nodeVersionInfo.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/nodeVersionInfo.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/nodeVersionInfo.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/param.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/param.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/param.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/param.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/params.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/params.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/params.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/params.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/payer.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/payer.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/payer.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/payer.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/ping.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/ping.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/ping.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/ping.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/pipe.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/pipe.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/pipe.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/pipe.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/pluginRegistry.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/pluginRegistry.md similarity index 93% rename from docs/tools/clients/fcl-js/packages-docs/fcl/pluginRegistry.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/pluginRegistry.md index b443597b4b..8f3a09dcc4 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/pluginRegistry.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/pluginRegistry.md @@ -46,7 +46,10 @@ pluginRegistry.add({ ## Returns ```typescript -Readonly<{ add: (plugins: any) => void; getPlugins: () => Map; }> +Readonly<{ + add: (plugins: any) => void; + getPlugins: () => Map; +}> ``` diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/proposer.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/proposer.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/proposer.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/proposer.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/query.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/query.md similarity index 87% rename from docs/tools/clients/fcl-js/packages-docs/fcl/query.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/query.md index 94034bcf70..a3b92778ca 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/query.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/query.md @@ -3,7 +3,7 @@ title: "query" description: "query function documentation." --- - + # query diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/queryRaw.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/queryRaw.md similarity index 86% rename from docs/tools/clients/fcl-js/packages-docs/fcl/queryRaw.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/queryRaw.md index 2cf607ae84..20516afcfc 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/queryRaw.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/queryRaw.md @@ -3,7 +3,7 @@ title: "queryRaw" description: "queryRaw function documentation." --- - + # queryRaw diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/reauthenticate.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/reauthenticate.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/reauthenticate.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/reauthenticate.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/ref.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/ref.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/ref.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/ref.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/sansPrefix.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/sansPrefix.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/sansPrefix.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/sansPrefix.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/script.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/script.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/script.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/script.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/send.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/send.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/send.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/send.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/serialize.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/serialize.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/serialize.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/serialize.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/signUp.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/signUp.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/signUp.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/signUp.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/subscribe.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/subscribe.md similarity index 97% rename from docs/tools/clients/fcl-js/packages-docs/fcl/subscribe.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/subscribe.md index 11385c8ef1..c73acd0993 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/subscribe.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/subscribe.md @@ -85,7 +85,10 @@ SubscribeParams - Type: ```typescript -{ node?: string; transport?: SdkTransport; } +{ + node?: string; + transport?: SdkTransport; +} ``` - Description: Additional options for the subscription diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/subscribeEvents.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/subscribeEvents.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/subscribeEvents.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/subscribeEvents.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/subscribeRaw.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/subscribeRaw.md similarity index 96% rename from docs/tools/clients/fcl-js/packages-docs/fcl/subscribeRaw.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/subscribeRaw.md index f2ed470bbe..3954184f70 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/subscribeRaw.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/subscribeRaw.md @@ -87,7 +87,10 @@ SubscribeRawParams - Type: ```typescript -{ node?: string; transport?: SdkTransport; } +{ + node?: string; + transport?: SdkTransport; +} ``` - Description: Additional options for the subscription @@ -99,7 +102,11 @@ SubscribeRawParams ## Returns -`void; }` +```typescript +{ + unsubscribe: () => void; +} +``` A subscription object with an unsubscribe method diff --git a/docs/build/tools/clients/fcl-js/packages-docs/fcl/transaction.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/transaction.md new file mode 100644 index 0000000000..693e9df68c --- /dev/null +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/transaction.md @@ -0,0 +1,134 @@ +--- +title: "transaction" +description: "transaction function documentation." +--- + + + +# transaction + +Creates a transaction monitor that provides methods for tracking and subscribing to +transaction status updates on the Flow blockchain. This function returns an object with methods +to get snapshots, subscribe to status changes, and wait for specific transaction states. + +## Import + +You can import the entire package and access the function: + +```typescript +import * as fcl from "@onflow/fcl" + +fcl.transaction(transactionId, opts) +``` + +Or import directly the specific function: + +```typescript +import { transaction } from "@onflow/fcl" + +transaction(transactionId, opts) +``` + +## Usage + +```typescript +// Basic transaction monitoring +import * as fcl from "@onflow/fcl" + +const txId = await fcl.mutate({ + cadence: ` + transaction { + execute { log("Hello, World!") } + } + ` +}) + +// Get current status +const status = await fcl.tx(txId).snapshot() +console.log("Current status:", status.status) + +// Subscribe to all status changes +const unsubscribe = fcl.tx(txId).subscribe((status) => { + console.log("Status update:", status.status) + if (status.status === fcl.transaction.isSealed) { + console.log("Transaction sealed!") + console.log("Events:", status.events) + } +}) +// Clean up subscription when done +setTimeout(() => unsubscribe(), 60000) + +// Wait for specific transaction states +try { + // Wait for finalization (consensus reached) + const finalizedStatus = await fcl.tx(txId).onceFinalized() + console.log("Transaction finalized") + + // Wait for execution (transaction executed) + const executedStatus = await fcl.tx(txId).onceExecuted() + console.log("Transaction executed") + + // Wait for sealing (transaction sealed in block) + const sealedStatus = await fcl.tx(txId).onceSealed() + console.log("Transaction sealed:", sealedStatus.events) +} catch (error) { + console.error("Transaction failed:", error.message) +} + +// Handle transaction errors +fcl.tx(txId).subscribe( + (status) => { + if (status.statusCode === 1) { + console.error("Transaction error:", status.errorMessage) + } + }, + (error) => { + console.error("Subscription error:", error) + } +) +``` + +## Parameters + +### `transactionId` + + +- Type: `string` +- Description: The 64-character hex transaction ID to monitor. Must be a valid +Flow transaction hash (64 bytes represented as hex string). + +### `opts` (optional) + + +- Type: +```typescript +{ + pollRate?: number; + txNotFoundTimeout?: number; +} +``` +- Description: Optional configuration parameters + +#### Properties: + +- **`pollRate`** - Polling rate in milliseconds when using legacy polling fallback +- **`txNotFoundTimeout`** - Timeout in milliseconds for ignoring transaction +not found errors during initial transaction propagation (do not modify unless you know what you are doing) + + +## Returns + +```typescript +{ + snapshot: () => Promise; + subscribe: (onData: (txStatus: TransactionStatus) => void, onError?: (err: Error) => void) => () => void; + onceFinalized: () => Promise; + onceExecuted: () => Promise; + onceSealed: () => Promise; +} +``` + + +Transaction monitor object with methods for tracking transaction status + +--- \ No newline at end of file diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/tx.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/tx.md similarity index 82% rename from docs/tools/clients/fcl-js/packages-docs/fcl/tx.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/tx.md index 97e965db6f..a9e4607444 100644 --- a/docs/tools/clients/fcl-js/packages-docs/fcl/tx.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/fcl/tx.md @@ -3,7 +3,7 @@ title: "tx" description: "tx function documentation." --- - + # tx @@ -102,7 +102,10 @@ Flow transaction hash (64 bytes represented as hex string). - Type: ```typescript -{ pollRate?: number; txNotFoundTimeout?: number; } +{ + pollRate?: number; + txNotFoundTimeout?: number; +} ``` - Description: Optional configuration parameters @@ -115,7 +118,15 @@ not found errors during initial transaction propagation (do not modify unless yo ## Returns -[`Promise`](../types#transactionstatus) +```typescript +{ + snapshot: () => Promise; + subscribe: (onData: (txStatus: TransactionStatus) => void, onError?: (err: Error) => void) => () => void; + onceFinalized: () => Promise; + onceExecuted: () => Promise; + onceSealed: () => Promise; +} +``` Transaction monitor object with methods for tracking transaction status diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/unauthenticate.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/unauthenticate.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/unauthenticate.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/unauthenticate.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/validator.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/validator.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/validator.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/validator.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/verifyUserSignatures.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/verifyUserSignatures.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/verifyUserSignatures.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/verifyUserSignatures.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/voucherIntercept.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/voucherIntercept.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/voucherIntercept.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/voucherIntercept.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/voucherToTxId.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/voucherToTxId.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/voucherToTxId.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/voucherToTxId.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/why.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/why.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/why.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/why.md diff --git a/docs/tools/clients/fcl-js/packages-docs/fcl/withPrefix.md b/docs/build/tools/clients/fcl-js/packages-docs/fcl/withPrefix.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/fcl/withPrefix.md rename to docs/build/tools/clients/fcl-js/packages-docs/fcl/withPrefix.md diff --git a/docs/tools/clients/fcl-js/packages-docs/index.md b/docs/build/tools/clients/fcl-js/packages-docs/index.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/index.md rename to docs/build/tools/clients/fcl-js/packages-docs/index.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/account.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/account.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/account.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/account.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/arg.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/arg.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/arg.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/arg.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/args.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/args.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/args.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/args.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/atBlockHeight.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/atBlockHeight.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/atBlockHeight.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/atBlockHeight.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/atBlockId.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/atBlockId.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/atBlockId.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/atBlockId.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/atLatestBlock.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/atLatestBlock.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/atLatestBlock.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/atLatestBlock.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/authorization.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/authorization.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/authorization.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/authorization.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/authorizations.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/authorizations.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/authorizations.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/authorizations.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/block.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/block.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/block.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/block.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/build.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/build.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/build.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/build.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/cadence.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/cadence.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/cadence.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/cadence.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/cdc.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/cdc.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/cdc.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/cdc.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/config.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/config.md similarity index 75% rename from docs/tools/clients/fcl-js/packages-docs/sdk/config.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/config.md index 72e51da6e7..bd60e74342 100644 --- a/docs/tools/clients/fcl-js/packages-docs/sdk/config.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/sdk/config.md @@ -43,7 +43,18 @@ Record ## Returns ```typescript -{ put: typeof put; get: typeof get; all: typeof all; first: typeof first; update: typeof update; delete: typeof _delete; where: typeof where; subscribe: typeof subscribe; overload: typeof overload; load: typeof load; } +{ + put: typeof put; + get: typeof get; + all: typeof all; + first: typeof first; + update: typeof update; + delete: typeof _delete; + where: typeof where; + subscribe: typeof subscribe; + overload: typeof overload; + load: typeof load; +} ``` diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/createSdkClient.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/createSdkClient.md similarity index 63% rename from docs/tools/clients/fcl-js/packages-docs/sdk/createSdkClient.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/createSdkClient.md index bf82099e8a..ec046a97e1 100644 --- a/docs/tools/clients/fcl-js/packages-docs/sdk/createSdkClient.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/sdk/createSdkClient.md @@ -63,7 +63,33 @@ export interface SdkClientOptions { ## Returns -`Promise` +```typescript +{ + send: (args?: false | InteractionBuilderFn | (false | InteractionBuilderFn)[], opts?: any) => Promise; + subscribe: ({ + topic, args, onData, onError +}: SubscribeParams, opts?: { + node?: string; + transport?: SdkTransport; +}) => Subscription; + subscribeRaw: ({ + topic, args, onData, onError +}: SubscribeRawParams, opts?: { + node?: string; + transport?: SdkTransport; +}) => { + unsubscribe: () => void; +}; + account: (address: string, { + height, id, isSealed +}?: AccountQueryOptions, opts?: object) => Promise; + block: ({ + sealed, id, height +}?: BlockQueryOptions, opts?: object) => Promise; + resolve: (ix: Interaction) => Promise; + decode: (response: any) => Promise; +} +``` A client object with methods to interact with the Flow blockchain. diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/createSignableVoucher.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/createSignableVoucher.md similarity index 82% rename from docs/tools/clients/fcl-js/packages-docs/sdk/createSignableVoucher.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/createSignableVoucher.md index 54bb58e35e..0a31a4b9bd 100644 --- a/docs/tools/clients/fcl-js/packages-docs/sdk/createSignableVoucher.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/sdk/createSignableVoucher.md @@ -75,7 +75,25 @@ console.log(voucher.authorizers); // List of authorizer addresses ## Returns ```typescript -{ cadence: string; refBlock: string; computeLimit: number; arguments: any[]; proposalKey: { address: string; keyId: string | number; sequenceNum: number; } | { address?: undefined; keyId?: undefined; sequenceNum?: undefined; }; payer: string; authorizers: string[]; payloadSigs: { address: string; keyId: string | number; sig: string; }[]; envelopeSigs: { address: string; keyId: string | number; sig: string; }[]; } +{ + cadence: string; + refBlock: string; + computeLimit: number; + arguments: any[]; + proposalKey: { + address: string; + keyId: string | number; + sequenceNum: number; +} | { + address?: undefined; + keyId?: undefined; + sequenceNum?: undefined; +}; + payer: string; + authorizers: string[]; + payloadSigs: any[]; + envelopeSigs: any[]; +} ``` diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/decode.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/decode.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/decode.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/decode.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/destroy.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/destroy.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/destroy.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/destroy.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/encodeMessageFromSignable.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/encodeMessageFromSignable.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/encodeMessageFromSignable.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/encodeMessageFromSignable.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/encodeTransactionEnvelope.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/encodeTransactionEnvelope.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/encodeTransactionEnvelope.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/encodeTransactionEnvelope.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/encodeTransactionPayload.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/encodeTransactionPayload.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/encodeTransactionPayload.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/encodeTransactionPayload.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/encodeTxIdFromVoucher.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/encodeTxIdFromVoucher.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/encodeTxIdFromVoucher.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/encodeTxIdFromVoucher.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/get.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/get.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/get.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/get.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/getAccount.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getAccount.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/getAccount.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/getAccount.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/getBlock.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getBlock.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/getBlock.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/getBlock.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/getBlockHeader.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getBlockHeader.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/getBlockHeader.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/getBlockHeader.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/getCollection.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getCollection.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/getCollection.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/getCollection.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/getEvents.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getEvents.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/getEvents.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/getEvents.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/getEventsAtBlockHeightRange.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getEventsAtBlockHeightRange.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/getEventsAtBlockHeightRange.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/getEventsAtBlockHeightRange.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/getEventsAtBlockIds.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getEventsAtBlockIds.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/getEventsAtBlockIds.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/getEventsAtBlockIds.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/getNetworkParameters.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getNetworkParameters.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/getNetworkParameters.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/getNetworkParameters.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/getNodeVersionInfo.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getNodeVersionInfo.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/getNodeVersionInfo.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/getNodeVersionInfo.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/getTransaction.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getTransaction.md similarity index 86% rename from docs/tools/clients/fcl-js/packages-docs/sdk/getTransaction.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/getTransaction.md index 120f440b19..39aab83f82 100644 --- a/docs/tools/clients/fcl-js/packages-docs/sdk/getTransaction.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getTransaction.md @@ -3,7 +3,7 @@ title: "getTransaction" description: "getTransaction function documentation." --- - + # getTransaction diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/getTransactionStatus.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/getTransactionStatus.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/getTransactionStatus.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/getTransactionStatus.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/index.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/index.md similarity index 89% rename from docs/tools/clients/fcl-js/packages-docs/sdk/index.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/index.md index a91ed49f93..5474a3b367 100644 --- a/docs/tools/clients/fcl-js/packages-docs/sdk/index.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/sdk/index.md @@ -1,6 +1,6 @@ --- -title: "@onflow/sdk" -description: "Low-level JavaScript/TypeScript SDK for interacting with the Flow blockchain." +title: '@onflow/sdk' +description: 'Low-level JavaScript/TypeScript SDK for interacting with the Flow blockchain.' --- @@ -34,13 +34,13 @@ yarn add @onflow/sdk You can import the entire package: ```typescript -import * as sdk from "@onflow/sdk" +import * as sdk from '@onflow/sdk'; ``` Or import specific functions: ```typescript -import { functionName } from "@onflow/sdk" +import { functionName } from '@onflow/sdk'; ``` ## Connect @@ -50,11 +50,11 @@ By default, the library uses HTTP to communicate with the access nodes and it mu Example: ```typescript -import { config } from "@onflow/fcl" +import { config } from '@onflow/fcl'; config({ - "accessNode.api": "https://rest-testnet.onflow.org" -}) + 'accessNode.api': 'https://rest-testnet.onflow.org', +}); ``` ## Querying the Flow Network @@ -95,7 +95,7 @@ A proposal key contains three fields: A transaction is only valid if its declared sequence number matches the current on-chain sequence number for that key. The sequence number increments by one after the transaction is executed. -**Payer** is the account that pays the fees for the transaction. A transaction must specify exactly one payer. The payer is only responsible for paying the network and gas fees; the transaction is not authorized to access resources or code stored in the payer account. +**Payer** is the account that pays the fees for the transaction. A transaction must specify exactly one payer. The payer is only responsible for paying the network and compute unit (gas) fees; the transaction is not authorized to access resources or code stored in the payer account. **Authorizers** are accounts that authorize a transaction to read and mutate their resources. A transaction can specify zero or more authorizers, depending on how many accounts the transaction needs to access. @@ -109,14 +109,17 @@ transaction { } ``` -**Gas limit** is the limit on the amount of computation a transaction requires, and it will abort if it exceeds its gas limit. -Cadence uses metering to measure the number of operations per transaction. You can read more about it in the [Cadence documentation](https://cadence-lang.org/docs). +**Compute Limit** is the limit on the amount of computation a transaction requires, and it will abort if it exceeds its compute unit limit. Cadence uses metering to measure the number of operations per transaction. You can read more about it in the [Cadence documentation](https://cadence-lang.org/docs). -The gas limit depends on the complexity of the transaction script. Until dedicated gas estimation tooling exists, it's best to use the emulator to test complex transactions and determine a safe limit. +The compute limit depends on the complexity of the transaction script. Until dedicated estimation tooling exists, it's best to use the emulator to test complex transactions and determine a safe limit. -**Reference block** specifies an expiration window (measured in blocks) during which a transaction is considered valid by the network. -A transaction will be rejected if it is submitted past its expiry block. Flow calculates transaction expiry using the _reference block_ field on a transaction. -A transaction expires after `600` blocks are committed on top of the reference block, which takes about 10 minutes at average Mainnet block rates. +Keep in mind that Flow is **very** efficient, so transaction fees are generally low. A limit resulting in max charges of `.001` Flow is sufficient to cover even complex transactions. + +- Flow token transfer: 19 CU. + - Single NFT Transfer: 26 CU. + - EVM Token transfer 28 CU. + +**Reference block** specifies an expiration window (measured in blocks) during which a transaction is considered valid by the network. A transaction will be rejected if it is submitted past its expiry block. Flow calculates transaction expiry using the _reference block_ field on a transaction. A transaction expires after `600` blocks are committed on top of the reference block, which takes about 8 minutes at average Mainnet block rates. ## API Reference @@ -200,4 +203,4 @@ This section contains documentation for all of the functions and namespaces in t - [voucherToTxId](./voucherToTxId.md) - Converts a voucher object to a transaction ID. This function computes the... - [why](./why.md) - Returns the reason for an interaction failure. ---- \ No newline at end of file +--- diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/initInteraction.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/initInteraction.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/initInteraction.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/initInteraction.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/interaction.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/interaction.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/interaction.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/interaction.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/isBad.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/isBad.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/isBad.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/isBad.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/isOk.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/isOk.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/isOk.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/isOk.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/limit.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/limit.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/limit.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/limit.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/nodeVersionInfo.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/nodeVersionInfo.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/nodeVersionInfo.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/nodeVersionInfo.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/param.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/param.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/param.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/param.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/params.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/params.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/params.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/params.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/payer.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/payer.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/payer.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/payer.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/ping.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/ping.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/ping.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/ping.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/pipe.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/pipe.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/pipe.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/pipe.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/proposer.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/proposer.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/proposer.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/proposer.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/put.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/put.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/put.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/put.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/ref.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/ref.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/ref.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/ref.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/resolve.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/resolve.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/resolve.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/resolve.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/resolveAccounts.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveAccounts.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/resolveAccounts.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveAccounts.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/resolveArguments.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveArguments.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/resolveArguments.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveArguments.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/resolveCadence.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveCadence.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/resolveCadence.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveCadence.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/resolveFinalNormalization.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveFinalNormalization.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/resolveFinalNormalization.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveFinalNormalization.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/resolveProposerSequenceNumber.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveProposerSequenceNumber.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/resolveProposerSequenceNumber.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveProposerSequenceNumber.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/resolveRefBlockId.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveRefBlockId.md similarity index 97% rename from docs/tools/clients/fcl-js/packages-docs/sdk/resolveRefBlockId.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveRefBlockId.md index ca7cce8509..ccd9282263 100644 --- a/docs/tools/clients/fcl-js/packages-docs/sdk/resolveRefBlockId.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveRefBlockId.md @@ -35,7 +35,9 @@ resolveRefBlockId(opts) - Type: ```typescript -{ [key: string]: any; } +{ + [key: string]: any; +} ``` - Description: Optional configuration parameters diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/resolveSignatures.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveSignatures.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/resolveSignatures.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveSignatures.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/resolveValidators.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveValidators.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/resolveValidators.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveValidators.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/resolveVoucherIntercept.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveVoucherIntercept.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/resolveVoucherIntercept.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/resolveVoucherIntercept.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/response.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/response.md similarity index 74% rename from docs/tools/clients/fcl-js/packages-docs/sdk/response.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/response.md index fd63839bfd..2fb2bd36dc 100644 --- a/docs/tools/clients/fcl-js/packages-docs/sdk/response.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/sdk/response.md @@ -46,7 +46,26 @@ console.log(defaultResponse.block); // null ## Returns ```typescript -{ tag: any; transaction: any; transactionStatus: any; transactionId: any; encodedData: any; events: any; event: any; accountStatusEvent: any; account: any; block: any; blockHeader: any; blockDigest: any; latestBlock: any; collection: any; networkParameters: any; streamConnection: any; heartbeat: any; nodeVersionInfo: any; } +{ + tag: any; + transaction: any; + transactionStatus: any; + transactionId: any; + encodedData: any; + events: any; + event: any; + accountStatusEvent: any; + account: any; + block: any; + blockHeader: any; + blockDigest: any; + latestBlock: any; + collection: any; + networkParameters: any; + streamConnection: any; + heartbeat: any; + nodeVersionInfo: any; +} ``` diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/script.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/script.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/script.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/script.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/send.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/send.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/send.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/send.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/subscribe.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/subscribe.md similarity index 83% rename from docs/tools/clients/fcl-js/packages-docs/sdk/subscribe.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/subscribe.md index b39b2589c9..546e0fc00a 100644 --- a/docs/tools/clients/fcl-js/packages-docs/sdk/subscribe.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/sdk/subscribe.md @@ -74,18 +74,24 @@ blockSubscription.unsubscribe(); ### `subscribeParams` +- Type: `SubscribeParams` -- Type: -```typescript -SubscribeParams -``` +#### Properties: + +- **`topic`** - Type: `T` - The topic to subscribe to. +- **`args`** - Type: `SubscriptionArgs` - The arguments for the subscription. +- **`onData`** - Type: `(data: SubscriptionData) => void` - The callback to call when data is received. +- **`onError`** - Type: `(error: Error) => void` - The callback to call when a fatal error occurs. ### `opts` (optional) - Type: ```typescript -{ node?: string; transport?: SdkTransport; } +{ + node?: string; + transport?: SdkTransport; +} ``` - Description: Additional options for the subscription diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/subscribeEvents.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/subscribeEvents.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/subscribeEvents.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/subscribeEvents.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/subscribeRaw.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/subscribeRaw.md similarity index 83% rename from docs/tools/clients/fcl-js/packages-docs/sdk/subscribeRaw.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/subscribeRaw.md index 61e9f69b93..5a30aee4f2 100644 --- a/docs/tools/clients/fcl-js/packages-docs/sdk/subscribeRaw.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/sdk/subscribeRaw.md @@ -76,18 +76,24 @@ rawSubscription.unsubscribe(); ### `subscribeRawParams` +- Type: `SubscribeRawParams` -- Type: -```typescript -SubscribeRawParams -``` +#### Properties: + +- **`topic`** - Type: `T` - The topic to subscribe to. +- **`args`** - Type: `SubscriptionArgs` - The arguments for the subscription. +- **`onData`** - Type: `(data: RawSubscriptionData) => void` - The callback to call when data is received. +- **`onError`** - Type: `(error: Error) => void` - The callback to call when a fatal error occurs. ### `opts` (optional) - Type: ```typescript -{ node?: string; transport?: SdkTransport; } +{ + node?: string; + transport?: SdkTransport; +} ``` - Description: Additional options for the subscription @@ -99,7 +105,11 @@ SubscribeRawParams ## Returns -`void; }` +```typescript +{ + unsubscribe: () => void; +} +``` A subscription object with an unsubscribe method diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/testUtils.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/testUtils.md similarity index 94% rename from docs/tools/clients/fcl-js/packages-docs/sdk/testUtils.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/testUtils.md index ef25508b69..1c8e14b845 100644 --- a/docs/tools/clients/fcl-js/packages-docs/sdk/testUtils.md +++ b/docs/build/tools/clients/fcl-js/packages-docs/sdk/testUtils.md @@ -141,7 +141,22 @@ interface IAuthzResolveOpts { #### Returns ```typescript -Partial; kind: InteractionResolverKind.ACCOUNT; addr: string; keyId: string | number; sequenceNum: number; signature: string; signingFunction: any; role: { proposer: boolean; authorizer: boolean; payer: boolean; param?: boolean; }; authorization: any; } +Partial; + kind: InteractionResolverKind.ACCOUNT; + addr: string; + keyId: string | number; + sequenceNum: number; + signature: string; + extensionData?: string; + signingFunction: any; + role: { + proposer: boolean; + authorizer: boolean; + payer: boolean; + param?: boolean; +}; + authorization: any; +} ``` ### authzResolveMany diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/transaction.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/transaction.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/transaction.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/transaction.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/update.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/update.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/update.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/update.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/validator.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/validator.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/validator.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/validator.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/voucherIntercept.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/voucherIntercept.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/voucherIntercept.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/voucherIntercept.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/voucherToTxId.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/voucherToTxId.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/voucherToTxId.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/voucherToTxId.md diff --git a/docs/tools/clients/fcl-js/packages-docs/sdk/why.md b/docs/build/tools/clients/fcl-js/packages-docs/sdk/why.md similarity index 100% rename from docs/tools/clients/fcl-js/packages-docs/sdk/why.md rename to docs/build/tools/clients/fcl-js/packages-docs/sdk/why.md diff --git a/docs/build/tools/clients/fcl-js/packages-docs/types/index.md b/docs/build/tools/clients/fcl-js/packages-docs/types/index.md new file mode 100644 index 0000000000..bcf9a40217 --- /dev/null +++ b/docs/build/tools/clients/fcl-js/packages-docs/types/index.md @@ -0,0 +1,685 @@ +--- +title: Type Definitions +description: Type definitions for the Flow Client Library (FCL) packages. +--- + + + +# Type Definitions + +Documentation for core types used throughout the Flow Client Library (FCL). + +## Interfaces + +### Account + +```typescript +import { type Account } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ----------- | ------------------------ | ------------------------------------------------------- | +| `address` | `string` | The address of the account | +| `balance` | `number` | The FLOW balance of the account in 10^8 | +| `code` | `number` | The code of any Cadence contracts stored in the account | +| `contracts` | `Record` | Any contracts deployed to this account | +| `keys` | `AccountKey[]` | The keys associated with the account | + +### AccountKey + +```typescript +import { type AccountKey } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ---------------- | -------------------- | --------------------------------------------------- | +| `index` | `number` | The index of the key in the account | +| `publicKey` | `string` | The public key of the account key | +| `signAlgo` | `SignatureAlgorithm` | The signature algorithm used by the key | +| `signAlgoString` | `string` | The signature algorithm used by the key as a string | +| `hashAlgo` | `HashAlgorithm` | The hashing algorithm used by the key | +| `hashAlgoString` | `string` | The hashing algorithm used by the key as a string | +| `sequenceNumber` | `number` | The sequence number of the key | +| `weight` | `number` | The weight of the key | +| `revoked` | `boolean` | Whether or not the key has been revoked | + +### AccountStatusEvent + +```typescript +import { type AccountStatusEvent } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ---------------- | -------- | -------------------------------------------------------------- | +| `accountAddress` | `string` | The address of the account which the event is associated with. | + +### Block + +```typescript +import { type Block } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ---------------------- | ----------------------- | --------------------------------------------------------- | +| `id` | `string` | The id of the block | +| `parentId` | `string` | The id of the parent block | +| `height` | `number` | The height of the block | +| `timestamp` | `string` | Time related fields | +| `parentVoterSignature` | `string` | The parent voter signature of the block | +| `collectionGuarantees` | `CollectionGuarantee[]` | Contains the ids of collections included in the block | +| `blockSeals` | `BlockSeal[]` | The details of which nodes executed and sealed the blocks | + +### BlockDigest + +```typescript +import { type BlockDigest } from '@onflow/fcl'; +``` + +BlockDigest holds lightweight block information which includes only block id, block height and block timestamp. + +**Properties:** + +| Name | Type | Description | +| ----------- | -------- | ----------------------- | +| `id` | `string` | The id of the block | +| `height` | `number` | The height of the block | +| `timestamp` | `string` | Timestamp of the block | + +### BlockHeader + +```typescript +import { type BlockHeader } from '@onflow/fcl'; +``` + +Header contains all meta-data for a block, as well as a hash representing +the combined payload of the entire block. It is what consensus nodes agree +on after validating the contents against the payload hash. + +**Properties:** + +| Name | Type | Description | +| ---------------------- | -------- | --------------------------------------- | +| `id` | `string` | The id of the block | +| `parentId` | `string` | The id of the parent block | +| `height` | `number` | The height of the block | +| `timestamp` | `string` | The timestamp of the block | +| `parentVoterSignature` | `string` | The parent voter signature of the block | + +### BlockHeartbeat + +```typescript +import { type BlockHeartbeat } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ------------- | -------- | -------------------------- | +| `blockId` | `string` | The ID of the block | +| `blockHeight` | `number` | The height of the block | +| `timestamp` | `string` | The timestamp of the block | + +### BlockSeal + +```typescript +import { type BlockSeal } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| -------------------- | -------- | ------------------------------------- | +| `blockId` | `string` | The id of the block | +| `executionReceiptId` | `string` | The execution receipt id of the block | + +### CollectionGuarantee + +```typescript +import { type CollectionGuarantee } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| -------------- | ---------- | --------------------------- | +| `collectionId` | `string` | The id of the block | +| `signerIds` | `string[]` | The signer ids of the block | + +### CompositeSignature + +```typescript +import { type CompositeSignature } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| --------------- | -------- | -------------------------------------------------------------------------- | +| `f_type` | `string` | A type identifier used internally by FCL | +| `f_vsn` | `string` | FCL protocol version | +| `addr` | `string` | Flow Address (sans prefix) | +| `keyId` | `number` | Key ID | +| `signature` | `string` | Signature as a hex string | +| `extensionData` | `string` | Optional signature extension data for alternative schemes (e.g., WebAuthn) | + +### CurrentUser + +```typescript +import { type CurrentUser } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ----------- | ----------- | -------------------------------------------------------------------------------------------- | +| `addr` | `string` | The public address of the current user | +| `cid` | `string` | A wallet specified content identifier for user metadata | +| `expiresAt` | `number` | A wallet specified time-frame for a valid session | +| `f_type` | `string` | A type identifier used internally by FCL | +| `f_vsn` | `string` | FCL protocol version | +| `loggedIn` | `boolean` | Whether or not the current user is logged in | +| `services` | `Service[]` | A list of trusted services that express ways of interacting with the current user's identity | + +### Event + +```typescript +import { type Event } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ------------------ | -------- | ------------------------------------------------------------------------------------------------- | +| `blockId` | `string` | ID of the block that contains the event. | +| `blockHeight` | `number` | Height of the block that contains the event. | +| `blockTimestamp` | `string` | The timestamp of when the block was sealed in a DateString format. eg. '2021-06-25T13:42:04.227Z' | +| `type` | `string` | A string containing the event name. | +| `transactionId` | `string` | Can be used to query transaction information, eg. via a Flow block explorer. | +| `transactionIndex` | `number` | Used to prevent replay attacks. | +| `eventIndex` | `number` | Used to prevent replay attacks. | +| `data` | `any` | The data emitted from the event. | + +### EventFilter + +```typescript +import { type EventFilter } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ------------------- | ---------- | ------------------------------------------------------------------- | +| `eventTypes` | `string[]` | The event types to listen for | +| `addresses` | `string[]` | The addresses to listen for | +| `contracts` | `string[]` | The contracts to listen for | +| `startBlockId` | `string` | The block ID to start listening for events | +| `startHeight` | `number` | The block height to start listening for events | +| `heartbeatInterval` | `number` | The interval in milliseconds to send a heartbeat to the Access Node | + +### Interaction + +```typescript +import { type Interaction } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | +| `tag` | `InteractionTag` | The type of interaction | +| `assigns` | `Record` | Assigned values for the interaction | +| `status` | `InteractionStatus` | The status of the interaction | +| `reason` | `string` | Reason for the current status | +| `accounts` | `Record` | Accounts involved in the interaction | +| `params` | `Record` | Parameters for the interaction | +| `arguments` | `Record` | Arguments for the interaction | +| `message` | `{ cadence: string; refBlock: string; computeLimit: number; proposer: string; payer: string; authorizations: string[]; params: Record[]; arguments: string[]; }` | Message details for the interaction | +| `proposer` | `string` | The proposer of the transaction | +| `authorizations` | `string[]` | The authorizations for the transaction | +| `payer` | `string[]` | The payer(s) of the transaction | +| `events` | `{ eventType: string; start: string \| number; end: string \| number; blockIds: string[]; }` | Event-related information | +| `transaction` | `{ id: string; }` | Transaction-related information | +| `block` | `{ id: string; height: string \| number; isSealed: boolean; }` | Block-related information | +| `account` | `{ addr: string; }` | Account-related information | +| `collection` | `{ id: string; }` | Collection-related information | +| `subscribeEvents` | `{ eventTypes: string[]; addresses: string[]; contracts: string[]; startBlockId: string; startHeight: number; heartbeatInterval: number; }` | Event subscription information | + +### InteractionAccount + +```typescript +import { type InteractionAccount } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ----------------- | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------- | +| `kind` | `InteractionResolverKind.ACCOUNT` | The kind of interaction resolver | +| `tempId` | `string` | Temporary identifier for the account | +| `addr` | `string` | The address of the account | +| `keyId` | `string \| number` | The key ID used for signing | +| `sequenceNum` | `number` | The sequence number for the account key | +| `signature` | `string` | The signature for the account | +| `extensionData` | `string` | Optional extension data for alternative signature schemes (e.g., WebAuthn) | +| `signingFunction` | `any` | Function used for signing | +| `resolve` | `any` | Resolver function for the account | +| `role` | `{ proposer: boolean; authorizer: boolean; payer: boolean; param?: boolean; }` | Role of the account in the transaction | +| `authorization` | `any` | Authorization details for the account | + +### Key + +```typescript +import { type Key } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ---------------- | -------- | ------------------------------------------------------------------------- | +| `sequenceNumber` | `number` | Sequence number of key used by the proposer of this transaction | +| `keyId` | `number` | The ID of the key in the account used by the proposer of this transaction | +| `address` | `string` | The address of the proposer of this transaction | + +### NodeVersionInfo + +```typescript +import { type NodeVersionInfo } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ---------------------- | -------- | ---------------------------------------- | +| `semver` | `string` | The semver version of the node. | +| `commit` | `string` | The commit hash of the node. | +| `sporkId` | `string` | The spork id of the node. | +| `protocolVersion` | `number` | The protocol version of the node. | +| `sporkRootBlockHeight` | `number` | The spork root block height of the node. | +| `nodeRootBlockHeight` | `number` | The node root block height of the node. | + +### Provider + +```typescript +import { type Provider } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ------------------ | --------- | ---------------------------------------------------------------------------- | +| `address` | `string` | The blockchain address of the Wallet provider. | +| `name` | `string` | The name of the Wallet provider. | +| `icon` | `string` | The icon of the Wallet provider (may be a URL or a data URI). | +| `description` | `string` | A brief description of the Wallet provider. | +| `color` | `string` | The preferred color to represent the Wallet provider (e.g., for UI styling). | +| `supportEmail` | `string` | The support email address of the Wallet provider. | +| `website` | `string` | The website URL of the Wallet provider. | +| `is_installed` | `boolean` | Indicates whether the Wallet provider is installed (if applicable). | +| `requires_install` | `boolean` | Indicates whether the Wallet provider requires installation (if applicable). | +| `install_link` | `string` | The install link for the Wallet provider. | + +### Service + +```typescript +import { type Service } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ---------- | ------------------------ | ---------------------------------------- | +| `f_type` | `string` | A type identifier used internally by FCL | +| `f_vsn` | `string` | FCL protocol version | +| `type` | `string` | Service type | +| `method` | `string` | Service method | +| `uid` | `string` | Service uid | +| `endpoint` | `string` | Service endpoint | +| `provider` | `Provider` | Service provider object | +| `params` | `Record` | Service parameters | +| `data` | `Record` | Service data | +| `headers` | `Record` | Service headers | + +### Signature + +```typescript +import { type Signature } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ---------------- | -------- | ------------------------------------------------------------ | +| `sequenceNumber` | `string` | Sequence number of the key used to perform this signature. | +| `keyId` | `number` | ID of the key in the account used to perform this signature. | +| `signature` | `string` | The signature represented as a hex string. | + +### StreamConnection + +```typescript +import { type StreamConnection } from '@onflow/fcl'; +``` + +### Transaction + +```typescript +import { type Transaction } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| -------------------- | ------------- | -------------------------------------------------------------------------- | +| `script` | `string` | The Cadence code used to execute this transaction. | +| `args` | `string[]` | The JSON-CDC encoded arguments passed in to the transaction. | +| `referenceBlockId` | `string` | The reference block id for this transaction. | +| `computeLimit` | `number` | The compute unit limit for the transaction. | +| `proposalKey` | `Key` | The key used by the proposer of this transaction. | +| `sequenceNumber` | `string` | Sequence number of the key used by the proposer of this transaction. | +| `keyId` | `number` | The ID of the key in the account used by the proposer of this transaction. | +| `address` | `string` | The address of the proposer of this transaction. | +| `payer` | `string` | Address of the payer of the transaction. | +| `proposer` | `string` | Address of the proposer of this transaction. | +| `authorizers` | `string[]` | Array of addresses of authorizers of this transaction. | +| `payloadSignatures` | `Signature[]` | The payload signatures for the transaction. | +| `envelopeSignatures` | `Signature[]` | The envelope signatures for the transaction. | + +### TransactionStatus + +```typescript +import { type TransactionStatus } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| -------------- | ---------------------------- | ------------------------------------------------------------------------------ | +| `blockId` | `string` | The ID of the Block the transaction is included in. | +| `status` | `TransactionExecutionStatus` | The execution status of the transaction | +| `statusString` | `string` | The status as as descriptive text (e.g. "FINALIZED"). | +| `statusCode` | `0 \| 1` | The result of the transaction, if executed (i.e. 0 for success, 1 for failure) | +| `errorMessage` | `string` | The error message of the transaction. | +| `events` | `Event[]` | The events for this result. | + +## Types + +### EventStream + +```typescript +import { type EventStream } from '@onflow/fcl'; +``` + +**Properties:** + +| Name | Type | Description | +| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `on` | `{ (channel: C, listener: (data: { events: Event[]; heartbeat: BlockHeartbeat; }[C]) => void): EventStream; (event: "close", listener: () => void): EventStream; (event: "error", listener: (err: any) => void): EventStream; }` | | +| `off` | `{ (event: C, listener: (data: { events: Event[]; heartbeat: BlockHeartbeat; }[C]) => void): EventStream; (event: "close", listener: () => void): EventStream; (event: "error", listener: (err: any) => void): EventStream; }` | | +| `close` | `() => void` | | + +### RawSubscriptionData + +```typescript +import { type RawSubscriptionData } from '@onflow/fcl'; +``` + +Raw data returned by a subscription, which will vary depending on the topic and is not decoded + +### SdkTransport + +```typescript +import { type SdkTransport } from '@onflow/fcl'; +``` + +Transport interface for the Flow SDK that provides methods for sending interactions and subscribing to data + +**Properties:** + +| Name | Type | Description | +| ----------- | ------------- | ---------------------------------------------------------------- | +| `send` | `SendFn` | Function to send an interaction to the Flow blockchain | +| `subscribe` | `SubscribeFn` | Function to subscribe to real-time data from the Flow blockchain | + +### Subscription + +```typescript +import { type Subscription } from '@onflow/fcl'; +``` + +A subscription object that allows managing the subscription lifecycle + +**Properties:** + +| Name | Type | Description | +| ------------- | ------------ | --------------------------------------------- | +| `unsubscribe` | `() => void` | Function to unsubscribe from the subscription | + +### SubscriptionArgs + +```typescript +import { type SubscriptionArgs } from '@onflow/fcl'; +``` + +Arguments for a subscription, which will vary depending on the topic + +### SubscriptionData + +```typescript +import { type SubscriptionData } from '@onflow/fcl'; +``` + +The data returned by a subscription, which will vary depending on the topic + +## Enums + +### FvmErrorCode + +```typescript +import { FvmErrorCode } from '@onflow/fcl'; +``` + +Error codes defined by the Flow Virtual Machine (FVM) for various types of errors that can occur during transaction execution + +**Members:** + +| Name | Value | +| ------------------------------------------------- | ----- | +| `UNKNOWN_ERROR` | -1 | +| `TX_VALIDATION_ERROR` | 1000 | +| `INVALID_TX_BYTE_SIZE_ERROR` | 1001 | +| `INVALID_REFERENCE_BLOCK_ERROR` | 1002 | +| `EXPIRED_TRANSACTION_ERROR` | 1003 | +| `INVALID_SCRIPT_ERROR` | 1004 | +| `INVALID_GAS_LIMIT_ERROR` | 1005 | +| `INVALID_PROPOSAL_SIGNATURE_ERROR` | 1006 | +| `INVALID_PROPOSAL_SEQ_NUMBER_ERROR` | 1007 | +| `INVALID_PAYLOAD_SIGNATURE_ERROR` | 1008 | +| `INVALID_ENVELOPE_SIGNATURE_ERROR` | 1009 | +| `FVM_INTERNAL_ERROR` | 1050 | +| `VALUE_ERROR` | 1051 | +| `INVALID_ARGUMENT_ERROR` | 1052 | +| `INVALID_ADDRESS_ERROR` | 1053 | +| `INVALID_LOCATION_ERROR` | 1054 | +| `ACCOUNT_AUTHORIZATION_ERROR` | 1055 | +| `OPERATION_AUTHORIZATION_ERROR` | 1056 | +| `OPERATION_NOT_SUPPORTED_ERROR` | 1057 | +| `BLOCK_HEIGHT_OUT_OF_RANGE_ERROR` | 1058 | +| `EXECUTION_ERROR` | 1100 | +| `CADENCE_RUNTIME_ERROR` | 1101 | +| `ENCODING_UNSUPPORTED_VALUE` | 1102 | +| `STORAGE_CAPACITY_EXCEEDED` | 1103 | +| `GAS_LIMIT_EXCEEDED_ERROR` | 1104 | +| `EVENT_LIMIT_EXCEEDED_ERROR` | 1105 | +| `LEDGER_INTERACTION_LIMIT_EXCEEDED_ERROR` | 1106 | +| `STATE_KEY_SIZE_LIMIT_ERROR` | 1107 | +| `STATE_VALUE_SIZE_LIMIT_ERROR` | 1108 | +| `TRANSACTION_FEE_DEDUCTION_FAILED_ERROR` | 1109 | +| `COMPUTATION_LIMIT_EXCEEDED_ERROR` | 1110 | +| `MEMORY_LIMIT_EXCEEDED_ERROR` | 1111 | +| `COULD_NOT_DECODE_EXECUTION_PARAMETER_FROM_STATE` | 1112 | +| `SCRIPT_EXECUTION_TIMED_OUT_ERROR` | 1113 | +| `SCRIPT_EXECUTION_CANCELLED_ERROR` | 1114 | +| `EVENT_ENCODING_ERROR` | 1115 | +| `INVALID_INTERNAL_STATE_ACCESS_ERROR` | 1116 | +| `INSUFFICIENT_PAYER_BALANCE` | 1118 | +| `ACCOUNT_ERROR` | 1200 | +| `ACCOUNT_NOT_FOUND_ERROR` | 1201 | +| `ACCOUNT_PUBLIC_KEY_NOT_FOUND_ERROR` | 1202 | +| `ACCOUNT_ALREADY_EXISTS_ERROR` | 1203 | +| `FROZEN_ACCOUNT_ERROR` | 1204 | +| `ACCOUNT_STORAGE_NOT_INITIALIZED_ERROR` | 1205 | +| `ACCOUNT_PUBLIC_KEY_LIMIT_ERROR` | 1206 | +| `CONTRACT_ERROR` | 1250 | +| `CONTRACT_NOT_FOUND_ERROR` | 1251 | +| `CONTRACT_NAMES_NOT_FOUND_ERROR` | 1252 | +| `EVM_EXECUTION_ERROR` | 1300 | + +### HashAlgorithm + +```typescript +import { HashAlgorithm } from '@onflow/fcl'; +``` + +**Members:** + +| Name | Value | +| ----------------------- | ----- | +| `SHA2_256` | 1 | +| `SHA2_384` | 2 | +| `SHA3_256` | 3 | +| `SHA3_384` | 4 | +| `KMAC128_BLS_BLS12_381` | 5 | + +### InteractionResolverKind + +```typescript +import { InteractionResolverKind } from '@onflow/fcl'; +``` + +Represents different kinds of interaction resolvers + +**Members:** + +| Name | Value | +| ---------- | ---------- | +| `ARGUMENT` | "ARGUMENT" | +| `ACCOUNT` | "ACCOUNT" | + +### InteractionStatus + +```typescript +import { InteractionStatus } from '@onflow/fcl'; +``` + +Status of an interaction with the Flow blockchain + +**Members:** + +| Name | Value | +| ----- | ----- | +| `BAD` | "BAD" | +| `OK` | "OK" | + +### InteractionTag + +```typescript +import { InteractionTag } from '@onflow/fcl'; +``` + +Represents different types of interactions with the Flow blockchain + +**Members:** + +| Name | Value | +| ------------------------ | ------------------------ | +| `UNKNOWN` | "UNKNOWN" | +| `SCRIPT` | "SCRIPT" | +| `TRANSACTION` | "TRANSACTION" | +| `GET_TRANSACTION_STATUS` | "GET_TRANSACTION_STATUS" | +| `GET_ACCOUNT` | "GET_ACCOUNT" | +| `GET_EVENTS` | "GET_EVENTS" | +| `PING` | "PING" | +| `GET_TRANSACTION` | "GET_TRANSACTION" | +| `GET_BLOCK` | "GET_BLOCK" | +| `GET_BLOCK_HEADER` | "GET_BLOCK_HEADER" | +| `GET_COLLECTION` | "GET_COLLECTION" | +| `GET_NETWORK_PARAMETERS` | "GET_NETWORK_PARAMETERS" | +| `SUBSCRIBE_EVENTS` | "SUBSCRIBE_EVENTS" | +| `GET_NODE_VERSION_INFO` | "GET_NODE_VERSION_INFO" | + +### SignatureAlgorithm + +```typescript +import { SignatureAlgorithm } from '@onflow/fcl'; +``` + +**Members:** + +| Name | Value | +| ----------------- | ----- | +| `ECDSA_P256` | 1 | +| `ECDSA_secp256k1` | 2 | +| `BLS_BLS12_381` | 3 | + +### SubscriptionTopic + +```typescript +import { SubscriptionTopic } from '@onflow/fcl'; +``` + +Represents different topics that can be subscribed to for real-time data from the Flow blockchain + +**Members:** + +| Name | Value | +| ---------------------- | ---------------------- | +| `BLOCKS` | "blocks" | +| `BLOCK_HEADERS` | "block_headers" | +| `BLOCK_DIGESTS` | "block_digests" | +| `ACCOUNT_STATUSES` | "account_statuses" | +| `TRANSACTION_STATUSES` | "transaction_statuses" | +| `EVENTS` | "events" | + +### TransactionExecutionStatus + +```typescript +import { TransactionExecutionStatus } from '@onflow/fcl'; +``` + +The execution status of the transaction. + +**Members:** + +| Name | Value | +| ----------- | ----- | +| `UNKNOWN` | 0 | +| `PENDING` | 1 | +| `FINALIZED` | 2 | +| `EXECUTED` | 3 | +| `SEALED` | 4 | +| `EXPIRED` | 5 | + +### TransactionRole + +```typescript +import { TransactionRole } from '@onflow/fcl'; +``` + +Represents different roles in a transaction + +**Members:** + +| Name | Value | +| ------------ | ------------ | +| `AUTHORIZER` | "authorizer" | +| `PAYER` | "payer" | +| `PROPOSER` | "proposer" | + +--- diff --git a/docs/tools/clients/fcl-js/proving-authentication.mdx b/docs/build/tools/clients/fcl-js/proving-authentication.mdx similarity index 83% rename from docs/tools/clients/fcl-js/proving-authentication.mdx rename to docs/build/tools/clients/fcl-js/proving-authentication.mdx index c9a799e84a..3562f4b6cb 100644 --- a/docs/tools/clients/fcl-js/proving-authentication.mdx +++ b/docs/build/tools/clients/fcl-js/proving-authentication.mdx @@ -5,14 +5,14 @@ title: Proving Ownership of a Flow Account ## Proving Ownership of a Flow Account A common desire that application developers have is to be able to prove that a -user controls an on-chain account. Proving ownership of an on-chain account is a +user controls an onchain account. Proving ownership of an onchain account is a way to authenticate a user with an application backend. Fortunately, -FCL provides a way to achieve this. +Flow Client Library (FCL) provides a way to achieve this. During user authentication, some FCL compatible wallets will choose to support the FCL `account-proof` service. If a wallet chooses to support this service, and the user approves the signing of message data, they will return `account-proof` data -and a signature(s) that can be used to prove a user controls an on-chain account. +and a signature(s) that can be used to prove a user controls an onchain account. We'll walk through how you, an application developer, can use the `account-proof` service to authenticate a user. @@ -20,7 +20,7 @@ authenticate a user. > Are you an FCL Wallet Developer? Check out the wallet provider specific docs > [here](https://github.com/onflow/fcl-js/blob/master/packages/fcl-core/src/wallet-provider-spec/provable-authn.md) -### Authenticating a user using `account-proof` +### Authenticate a user with `account-proof` In order to authenticate your users via a wallet provider's account-proof service, your application needs to configure FCL by setting `fcl.accountProof.resolver` and providing two pieces of information. @@ -59,11 +59,11 @@ config({ Here is the suggested order of operations of how your application might use the `account-proof` service: -- A user would like to authenticate via your application client using FCL. The process is triggered +- A user would like to authenticate via your application client with FCL. The process is triggered by a call to `fcl.authenticate()`. If `fcl.accountProof.resolver` is configured, FCL will attempt to retrieve the account proof data (`nonce`) and trigger your server to start a new account proof authentication process. -- Your application server generates a **minimum 32-byte random nonce** using a local source of entropy and +- Your application server generates a **minimum 32-byte random nonce** with a local source of entropy and sends it to the client. The server saves the challenge for future look-ups. - If FCL successfully retrieves the `account-proof` data, it continues the authentication process over a secure channel with the wallet. FCL includes the `appIdentifier` and `nonce` as part of the `FCL:VIEW:READY:RESPONSE` or HTTP POST request body. The `appIdentifier` @@ -111,15 +111,15 @@ The data within the `account-proof` service will look like this: has expired, reject the authentication request, otherwise continue. - The server determines whether the `CompositeSignature` in the `account-proof` data structure contains valid signatures for the nonce - and on-chain accounts (more details in the section below on how this is done). + and onchain accounts (more details in the section below on how this is done). - If the verification is successful, delete the `nonce` or mark it as expired, - the application account defined by the on-chain address is successfully + the application account defined by the onchain address is successfully logged in. Otherwise the authentication fails and the `nonce` is not deleted. **Verification** Your application can verify the signature against the data from `account-proof` -data using FCL's provided utility: +data with FCL's provided utility: ```js @@ -139,28 +139,28 @@ import { AppUtils } from "@onflow/fcl" ## Implementation considerations: -- The authentication assumes the Flow address is the identifier of the user's application account. - If an existing user doesn't have a Flow address in their profile, or if they decide to authenticate using - a Flow address different than the one saved in their profile, the user's account won't be found and the - process would consider a new user creating an account. It is useful for your application to consider - other authentication methods that allow an existing user to update the Flow address in their profile so +- The authentication assumes the Flow address is user's application account identifier. + If a current user doesn't have a Flow address in their profile, or if they decide to authenticate with + a Flow address different than the one saved in their profile, the system won't find the user's account and the + process considers a new user creating an account. It is useful for your application to consider + other authentication methods that allow a current user to update the Flow address in their profile so they are able to use FCL authentication. -- In the `account-proof` flow as described in this document, - the backend doesn't know the user's account address at the moment of generating a nonce. +- In the `account-proof` flow as this document describes, + the backend doesn't know the user's account address at the moment it generates a nonce. This results in the nonces not being tied to particular Flow addresses. The backend should enforce an expiry window for each nonce to avoid the pool of valid nonces from growing indefinitely. - Your application is encouraged to implement further mitigations against malicious attempts and + We encourage your application to implement further mitigations against malicious attempts and maintain a scalable authentication process. - FCL `account-proof` provides functionality to prove a user is in control of a Flow address. All other aspects of authentication, authorization and session management - are up to the application. There are many resources available for setting up secure user + are up to the application. There are many resources available to set up secure user authentication systems. Application developers should carefully consider what's best for their use case and follow industry best practices. -- It is important to use a secure source of entropy to generate the random nonces. The source should insure - nonces are not predictable by looking at previously generated nonces. Moreover, backend should use its own - local source and not rely on a publicly available source. Using a nonce of at least 32-bytes insures - it is extremely unlikely to have a nonce collision. -- The origin / `appIdentifier` is a tuple ⟨scheme, host, port⟩ computed per RFC 6454 (i.e. the value returned +- It is important to use a secure source of entropy to generate the random nonces. The source should look at + previously generated nonces to make sure that future nonces aren't predictible. Moreover, backend should use its own + local source and not rely on a publicly available source. Use a nonce of at least 32-bytes to try and prevent a + nonce collision. +- The origin / `appIdentifier` is a tuple ⟨scheme, host, port⟩ computed per RFC 6454 (that is, the value returned by window.location.origin in conforming user agents). Wallets will embed this origin into the RLP-encoded payload which is cryptographically signed. The resulting signature serves as an attestation that the authentication request originated from the specified application origin (which is known through verification with supporting Browser APIs) diff --git a/docs/tools/clients/fcl-js/scripts.md b/docs/build/tools/clients/fcl-js/scripts.md similarity index 57% rename from docs/tools/clients/fcl-js/scripts.md rename to docs/build/tools/clients/fcl-js/scripts.md index dbfbccc393..d5c4a2992f 100644 --- a/docs/tools/clients/fcl-js/scripts.md +++ b/docs/build/tools/clients/fcl-js/scripts.md @@ -6,9 +6,9 @@ They always need to contain a `access(all) fun main()` function as an entry poin `fcl.query` is a function that sends Cadence scripts to the chain and receives back decoded responses. -The `cadence` key inside the object sent to the `query` function is a [JavaScript Tagged Template Literal](https://styled-components.com/docs/advanced#tagged-template-literals) that we can pass Cadence code into. +The `cadence` key inside the object sent to the `query` function is a [JavaScript Tagged Template Literal] that we can pass Cadence code into. -### Sending Your First Script +### Send your first script The following example demonstrates how to send a script to the Flow blockchain. This script adds two numbers and returns the result. @@ -26,13 +26,13 @@ const response = await fcl.query({ console.log(response) // 3 ``` -### A More Complex Script +### A more complex script -[Resources](https://cadence-lang.org/docs/language/resources) and [Structs](https://cadence-lang.org/docs/language/composite-types#structures) are complex data types that are fairly common place in Cadence. +[Resources] and [Structs] are complex data types that are fairly common place in Cadence. In the following code snippet, our script defines a struct called `Point`, it then returns a list of them. -The closest thing to a Structure in JavaScript is an object. In this case when we decode this response, we would be expecting to get back an array of objects, where the objects have an `x` and `y` value. +The closest thing to a Structure in JavaScript is an object. In this case when we decode this response, we would expect to get back an array of objects, where the objects have an `x` and `y` value. ```javascript import * as fcl from "@onflow/fcl" @@ -58,16 +58,15 @@ const response = await fcl.query({ console.log(response) // [{x:1, y:1}, {x:2, y:2}] ``` -### Transforming Data with Custom Decoders +### Transform data with custom decoders -In our app, we probably have a way of representing these Cadence values internally. In the above example it might be a `Point` class. +In our app, we probably have a way to represent these Cadence values internally. In the above example it might be a `Point` class. -FCL enables us to provide custom decoders that we can use to transform the data we receive from the Flow blockchain at the edge, before anything else in our dapp gets a chance to look at it. +FCL allows us to provide custom decoders that we can use to transform the data we receive from the Flow blockchain at the edge, before anything else in our dApp gets a chance to look at it. -We add these custom decoders by [Configuring FCL](./configure-fcl.md). -This lets us set it once when our dapp starts up and use our normalized data through out the rest of our dapp. +To add these custom decoders, we [configure FCL]. This lets us set it once when our dApp starts up and use our normalized data through out the rest of our dapp. -In the below example we will use the concept of a `Point` again, but this time, we will add a custom decoder, that enables `fcl.decode` to transform it into a custom JavaScript `Point` class. +In the below example, we will use the concept of a `Point` again, but this time, we will add a custom decoder, that allows `fcl.decode` to transform it into a custom JavaScript `Point` class. ```javascript import * as fcl from "@onflow/fcl" @@ -103,4 +102,12 @@ const response = await fcl.query({ console.log(response) // [Point{x:1, y:1}, Point{x:2, y:2}] ``` -To learn more about `query`, check out the [API documentation](./packages-docs/fcl/query.md). +To learn more about `query`, check out the [API documentation]. + + + +[JavaScript Tagged Template Literal]: https://styled-components.com/docs/advanced#tagged-template-literals +[Resources]: https://cadence-lang.org/docs/language/resources +[Structs]: https://cadence-lang.org/docs/language/composite-types#structures +[configure FCL]: ./configure-fcl.md +[API documentation]: ./packages-docs/fcl/query.md \ No newline at end of file diff --git a/docs/build/tools/clients/fcl-js/transactions.md b/docs/build/tools/clients/fcl-js/transactions.md new file mode 100644 index 0000000000..7d454fae09 --- /dev/null +++ b/docs/build/tools/clients/fcl-js/transactions.md @@ -0,0 +1,151 @@ +# Transactions + +Transactions let you send Cadence code to the Flow blockchain that permanently alters its state. + +We assume you have read the [Scripts Documentation]: ./scripts.md before this, as transactions are sort of scripts with more required things. + +While `query` is used to send scripts to the chain, `mutate` is used to build and send transactions. Just like [scripts], `fcl.mutate` is a [JavaScript Tagged Template Literal] that we can pass Cadence code into. + +Unlike scripts, they require a little more information, things like a proposer, authorizations and a payer, which may be a little confusing and overwhelming. + +## Send your first transaction + +There is a lot to unpack in the following code snippet. It sends a transaction to the Flow blockchain. For the transaction, the current user authorizes it as both the `proposer` and the `payer`. + +Something that is unique to Flow is the one who pays for the transaction doesn't always need to be the one who performs the transaction. Proposers and Payers are special kinds of authorizations that are always required for a transaction. +- The `proposer` acts similar to the `nonce` in Ethereum transactions, and helps prevent repeat attacks. +- The `payer` is who will be paying for the transaction. +If these are not set, Flow Client Library (FCL) defaults to the current user for all roles. + +`fcl.mutate` will return a `transactionId`. We can pass the response directly to `fcl.tx` and then use the `onceExecuted` method which resolves a promise when a transaction result is available. + +```javascript +import * as fcl from '@onflow/fcl'; + +const transactionId = await fcl.mutate({ + cadence: ` + transaction { + execute { + log("Hello from execute") + } + } + `, + proposer: fcl.currentUser, + payer: fcl.currentUser, + limit: 50, +}); + +const transaction = await fcl.tx(transactionId).onceExecuted(); +console.log(transaction); // The transactions status and events after being executed +``` + +## Authorize a transaction + +The below code snippet is the same as the above one, except for one extremely important difference. Our Cadence code this time has a prepare statement, and we use the `fcl.currentUser` when constructing our transaction. + +The `prepare` statement's arguments directly map to the order of the authorizations in the `authorizations` array. Four authorizations means four `&Account`s as arguments passed to `prepare`. In this case though there is only one, and it is the `currentUser`. + +These authorizations are important as you can only access or modify an account's storage if you have that account's authorization. + +```javascript +import * as fcl from '@onflow/fcl'; + +const transactionId = await fcl.mutate({ + cadence: ` + transaction { + prepare(acct: &Account) { + log("Hello from prepare") + } + execute { + log("Hello from execute") + } + } + `, + proposer: fcl.currentUser, + payer: fcl.currentUser, + authorizations: [fcl.currentUser], + limit: 50, +}); + +const transaction = await fcl.tx(transactionId).onceExecuted(); +console.log(transaction); // The transactions status and events after being executed +``` + +To learn more about `mutate`, check out the [API documentation]. + +## Query transaction results + +When you query transaction results (for example, via HTTP/REST endpoints like `GET /v1/transaction_results/{id}`), you can provide either: +- A **transaction ID** (256-bit hash as hex string). +- A **scheduled transaction ID** (UInt64 as decimal string). + +The returned result always includes `transaction_id` as the underlying native transaction ID. For scheduled transactions, this will be the system transaction ID that executed the scheduled callback. + +Learn more about [Scheduled Transactions]. + +## Transaction finality + +As of **FCL v1.15.0**, it is now recommended to use use `onceExecuted` in most cases, which leads to a 2.5x reduction in latency when you wait for a transaction result. For example, the following code snippet should be updated from: + +```ts +import * as fcl from '@onflow/fcl'; +const result = await fcl.tx(txId).onceSealed(); +``` + +to: + +```ts +import * as fcl from '@onflow/fcl'; +const result = await fcl.tx(txId).onceExecuted(); +``` + +Developers who manually subscribe to transaction statuses should update their listeners to treat "executed" as the final status (see the [release notes]). For example, the following code snippet should be updated from: + +```ts +import * as fcl from '@onflow/fcl'; +import { TransactionExecutionStatus } from '@onflow/typedefs'; + +fcl.tx(txId).subscribe((txStatus) => { + if (txStatus.status === TransactionExecutionStatus.SEALED) { + console.log('Transaction executed!'); + } +}); +``` + +```ts +import * as fcl from '@onflow/fcl'; +import { TransactionExecutionStatus } from '@onflow/typedefs'; + +fcl.tx(txId).subscribe((txStatus) => { + if ( + // SEALED status is no longer necessary + txStatus.status === TransactionExecutionStatus.EXECUTED + ) { + console.log('Transaction executed!'); + } +}); +``` + +The "executed" status corresponds to soft finality, which indicates that the transaction has been included in a block and a transaction status is available, backed by a cryptographic proof. Only in rare cases should a developer need to wait for "sealed" status in their applications and you can learn more about the different transaction statuses on Flow [here]. + +See the following video for demonstration of how to update your code to wait for "executed" status: + + + + + +[Scripts Documentation]: ./scripts.md +[scripts]: ./scripts.md +[JavaScript Tagged Template Literal]: https://styled-components.com/docs/advanced#tagged-template-literals +[API documentation]: ./packages-docs/fcl/mutate.md +[Scheduled Transactions]: /docs/build/cadence/advanced-concepts/scheduled-transactions.md +[release notes]: https://github.com/onflow/fcl-js/releases/tag/%40onflow%2Ffcl%401.15.0 +[here]: ../../../cadence/basics/transactions.md#transaction-status \ No newline at end of file diff --git a/docs/tools/clients/fcl-js/user-signatures.md b/docs/build/tools/clients/fcl-js/user-signatures.md similarity index 72% rename from docs/tools/clients/fcl-js/user-signatures.md rename to docs/build/tools/clients/fcl-js/user-signatures.md index dfb4c28608..cca3746e56 100644 --- a/docs/tools/clients/fcl-js/user-signatures.md +++ b/docs/build/tools/clients/fcl-js/user-signatures.md @@ -2,29 +2,33 @@ title: Signing and Verifying Arbitrary Data --- -## Signing Arbitrary Data +## Signing and Verifying Arbitrary Data -Cryptographic signatures are a key part of the blockchain. They are used to prove ownership of an address without exposing its private key. While primarily used for signing transactions, cryptographic signatures can also be used to sign arbitrary messages. +Cryptographic signatures are a key part of the blockchain. They prove ownership of an address without exposing its private key. While primarily used to sign transactions, you can also use cryptographic signatures to sign arbitrary messages. -FCL has a feature that lets you send arbitrary data to a configured wallet/service where the user may approve signing it with their private key/s. +FCL has a feature that lets you send arbitrary data to a configured wallet or service. The user may approve signing it with their private keys. -## Verifying User Signatures +## Verify user signatures What makes message signatures more interesting is that we can use Flow blockchain to verify the signatures. Cadence has a built-in function `publicKey.verify` that will verify a signature against a Flow account given the account address. -FCL includes a utility function, `AppUtils.verifyUserSignatures`, for verifying one or more signatures against an account's public key on the Flow blockchain. +FCL includes a utility function, `AppUtils.verifyUserSignatures`, that verifies one or more signatures against an account's public key on the Flow blockchain. You can use both in tandem to prove a user is in control of a private key or keys. -This enables cryptographically-secure login flow using a message-signing-based authentication mechanism with a user’s public address as their identifier. +This allows cryptographically-secure login flow with a message-signing-based authentication mechanism with a user’s public address as their identifier. --- ## `currentUser.signUserMessage()` -A method to use allowing the user to personally sign data via FCL Compatible Wallets/Services. +A method that allows the user to personally sign data via FCL Compatible Wallets or Services. -> :Note: **Requires authentication/configuration with an authorized signing service.** +:::info + +> **Requires authentication/configuration with an authorized signing service.** + +::: ### Arguments @@ -36,7 +40,7 @@ A method to use allowing the user to personally sign data via FCL Compatible Wal | Type | Description | | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `Array` | An Array of [CompositeSignatures](https://github.com/onflow/fcl-js/blob/master/packages/fcl-core/src/wallet-provider-spec/draft-v2.md#compositesignature): {`addr`, `keyId`, `signature`} | +| `Array` | An Array of [CompositeSignatures]: {`addr`, `keyId`, `signature`} | #### Usage @@ -57,11 +61,13 @@ const signMessage = async () => { ## `AppUtils.verifyUserSignatures` -#### Note +:::info ⚠️ `fcl.config.flow.network` or options override is required to use this API. See [FCL Configuration](./configure-fcl.md). -A method allowing applications to cryptographically verify the ownership of a Flow account by verifying a message was signed by a user's private key/s. This is typically used with the response from `currentUser.signUserMessage`. +A method to verify that a user's private keys signed a message, which allows applications to cryptographically verify Flow account ownership. This is typically used with the response from `currentUser.signUserMessage`. + +::: ### Arguments @@ -107,3 +113,8 @@ A method allowing applications to cryptographically verify the ownership of a Fl Use cases include cryptographic login, message validation, verifiable credentials, and others. --- + + + +[FCL Configuration]: ./configure-fcl.md +[CompositeSignatures]: https://github.com/onflow/fcl-js/blob/master/packages/fcl-core/src/wallet-provider-spec/draft-v2.md#compositesignature \ No newline at end of file diff --git a/docs/build/tools/clients/flow-go-sdk/flowkit.md b/docs/build/tools/clients/flow-go-sdk/flowkit.md new file mode 100644 index 0000000000..06e37de775 --- /dev/null +++ b/docs/build/tools/clients/flow-go-sdk/flowkit.md @@ -0,0 +1,477 @@ +--- +title: Flow Project Configuration +description: Learn how to work with Flow project state using the Flowkit Go library +sidebar_position: 3 +keywords: + - Flowkit + - Go SDK + - Flow + - Project State + - Tutorial + - Configuration + - flow.json +--- + +# Flowkit Go Tutorial: Working with Flow Project State + +## Introduction + +**Flowkit** is a Go package for interacting with the Flow blockchain in the context of `flow.json` configuration files. It provides APIs for managing Flow projects, including: + +- Loading and managing project configuration (`flow.json`) +- Resolving import statements in Cadence contracts, scripts, and transactions +- Deploying contracts to different networks (emulator, testnet, mainnet) +- Managing accounts, networks, and deployments +- Executing scripts and building transactions with proper import resolution + +Flowkit is the core package used by the Flow CLI and can be integrated into any Go application that needs to interact with Flow projects. + +## Installation + +### Prerequisites + +- Go 1.25.0 or higher +- A Flow project with a `flow.json` configuration file + +### Install the Package + +Add Flowkit to your Go module: + +```bash +go get github.com/onflow/flowkit/v2 +``` + +This will install Flowkit v2 and all its dependencies. + +### Import in Your Code + +```go +import ( + "github.com/onflow/flowkit/v2" + "github.com/onflow/flowkit/v2/config" + "github.com/onflow/flowkit/v2/project" + "github.com/spf13/afero" +) +``` + +## Loading Project State + +The first step when working with Flowkit is loading your project's state from `flow.json`. + +### Basic Usage + +```go +package main + +import ( + "log" + "github.com/onflow/flowkit/v2" + "github.com/spf13/afero" +) + +func main() { + // Load flow.json from the current directory + state, err := flowkit.Load([]string{"flow.json"}, afero.Afero{Fs: afero.NewOsFs()}) + if err != nil { + log.Fatalf("Failed to load project state: %v", err) + } + + // Now you can work with the project state + log.Println("Project state loaded successfully!") +} +``` + +### Creating a New Project State + +If you need to create a new project from scratch: + +```go +// Initialize an empty state +state, err := flowkit.Init(afero.Afero{Fs: afero.NewOsFs()}) +if err != nil { + log.Fatalf("Failed to initialize state: %v", err) +} +``` + +### Accessing State Components + +The `State` object provides access to all project configuration: + +```go +// Get all contracts +contracts := state.Contracts() + +// Get all networks +networks := state.Networks() + +// Get all accounts +accounts := state.Accounts() + +// Get all deployments +deployments := state.Deployments() + +// Get the underlying config +config := state.Config() +``` + +## Working with Contracts + +Contracts are Cadence smart contracts defined in your project. + +### Getting Contract Information + +```go +// Get a contract by name +contract, err := state.Contracts().ByName("MyContract") +if err != nil { + log.Fatalf("Contract not found: %v", err) +} + +log.Printf("Contract: %s\n", contract.Name) +log.Printf("Location: %s\n", contract.Location) + +// Get all contract names +for _, c := range *state.Contracts() { + log.Printf("Available contract: %s\n", c.Name) +} +``` + +### Getting Deployment Contracts for a Network + +When deploying or executing code, you often need contracts with their target addresses: + +```go +import "github.com/onflow/flowkit/v2/config" + +// Get all contracts configured for deployment on testnet +contracts, err := state.DeploymentContractsByNetwork(config.TestnetNetwork) +if err != nil { + log.Fatalf("Failed to get deployment contracts: %v", err) +} + +// Each contract includes deployment information +for _, contract := range contracts { + log.Printf("Contract: %s\n", contract.Name) + log.Printf(" Location: %s\n", contract.Location()) + log.Printf(" Target Account: %s\n", contract.AccountAddress) + log.Printf(" Account Name: %s\n", contract.AccountName) + log.Printf(" Code Size: %d bytes\n", len(contract.Code())) +} +``` + +## Working with Networks + +Flowkit supports multiple networks including emulator, testnet, and mainnet. + +### Available Networks + +```go +import "github.com/onflow/flowkit/v2/config" + +// Predefined networks +emulator := config.EmulatorNetwork // Local emulator +testnet := config.TestnetNetwork // Flow testnet +mainnet := config.MainnetNetwork // Flow mainnet + +log.Printf("Emulator: %s\n", emulator.Host) +log.Printf("Testnet: %s\n", testnet.Host) +log.Printf("Mainnet: %s\n", mainnet.Host) +``` + +### Getting Networks from State + +```go +// Get all networks defined in flow.json +networks := state.Networks() + +// Get a specific network by name +testnet, err := networks.ByName("testnet") +if err != nil { + log.Fatalf("Network not found: %v", err) +} + +log.Printf("Network: %s\n", testnet.Name) +log.Printf("Host: %s\n", testnet.Host) +``` + +### Adding or Updating Networks + +```go +import "github.com/onflow/flowkit/v2/config" + +// Add a custom network +networks := state.Networks() +networks.AddOrUpdate(config.Network{ + Name: "custom-network", + Host: "localhost:3570", +}) + +// Save the updated configuration +err := state.SaveDefault() +if err != nil { + log.Fatalf("Failed to save state: %v", err) +} +``` + +### Getting Network-Specific Aliases + +Network aliases map contract names/locations to their deployed addresses on specific networks: + +```go +import "github.com/onflow/flowkit/v2/config" + +// Get aliases for testnet +aliases := state.AliasesForNetwork(config.TestnetNetwork) + +// aliases is a map[string]string of location/name -> address +for location, address := range aliases { + log.Printf("%s deployed at %s on testnet\n", location, address) +} +``` + +## Resolving Imports with ImportReplacer + +The `ImportReplacer` resolves import statements in Cadence contracts, scripts, and transactions by replacing relative file paths and contract names with their deployed blockchain addresses. + +### Basic Usage + +When you have a Cadence program with imports like `import "Kibble"`, you need to resolve these to blockchain addresses: + +```go +import "github.com/onflow/flowkit/v2/project" +import "github.com/onflow/flowkit/v2/config" + +// Get contracts for your target network +contracts, err := state.DeploymentContractsByNetwork(config.TestnetNetwork) +if err != nil { + log.Fatal(err) +} + +// Create an import replacer with your project's contracts +importReplacer := project.NewImportReplacer(contracts, nil) + +// Parse your Cadence program +code := []byte(` +import "Kibble" +import "FungibleToken" + +transaction { + prepare(signer: &Account) { + // ... + } +} +`) + +program, err := project.NewProgram(code, nil, "") +if err != nil { + log.Fatalf("Failed to parse program: %v", err) +} + +// Replace imports with deployed addresses +resolvedProgram, err := importReplacer.Replace(program) +if err != nil { + log.Fatalf("Failed to resolve imports: %v", err) +} + +// The resolved program now has addresses instead of file paths +log.Printf("Resolved code:\n%s", string(resolvedProgram.Code())) +``` + +### Integration with Project State + +The most common pattern is to use network-specific aliases from your project state: + +```go +// Load project state and get network-specific contracts and aliases +state, err := flowkit.Load([]string{"flow.json"}, afero.Afero{Fs: afero.NewOsFs()}) +if err != nil { + log.Fatal(err) +} + +// Choose your target network +network := config.TestnetNetwork + +// Get contracts for this network +contracts, err := state.DeploymentContractsByNetwork(network) +if err != nil { + log.Fatal(err) +} + +// Use network-specific aliases for address mapping +importReplacer := project.NewImportReplacer( + contracts, + state.AliasesForNetwork(network), +) + +// Parse and resolve your program +program, err := project.NewProgram(scriptCode, nil, "script.cdc") +if err != nil { + log.Fatalf("Failed to parse program: %v", err) +} +resolvedProgram, err := importReplacer.Replace(program) +if err != nil { + log.Fatalf("Failed to resolve imports: %v", err) +} + +// Use the resolved program for execution +log.Printf("Ready to execute:\n%s", string(resolvedProgram.Code())) +``` + +## Working with Accounts + +Accounts represent Flow blockchain accounts used for signing transactions and deploying contracts. + +### Getting Account Information + +```go +import "github.com/onflow/flow-go-sdk" + +accounts := state.Accounts() + +// Get account by name +account, err := accounts.ByName("emulator-account") +if err != nil { + log.Fatalf("Account not found: %v", err) +} + +log.Printf("Account: %s\n", account.Name) +log.Printf("Address: %s\n", account.Address) + +// Get all account names +names := accounts.Names() +for _, name := range names { + log.Printf("Available account: %s\n", name) +} + +// Get account by address +addr := flow.HexToAddress("0xf8d6e0586b0a20c7") +account, err = accounts.ByAddress(addr) +if err != nil { + log.Fatalf("Account not found by address: %v", err) +} +``` + +### Getting the Emulator Service Account + +```go +// Get the emulator's default service account +serviceAccount, err := state.EmulatorServiceAccount() +if err != nil { + log.Fatalf("Failed to get service account: %v", err) +} + +log.Printf("Service account address: %s\n", serviceAccount.Address) +``` + +## Working with Deployments + +Deployments define which contracts should be deployed to which accounts on specific networks. + +### Getting Deployment Information + +```go +deployments := state.Deployments() + +// Get all deployments for a network +testnetDeployments := deployments.ByNetwork("testnet") + +for _, deployment := range testnetDeployments { + log.Printf("Account: %s\n", deployment.Account) + log.Printf("Network: %s\n", deployment.Network) + log.Printf("Contracts:\n") + + for _, contract := range deployment.Contracts { + log.Printf(" - %s\n", contract.Name) + } +} + +// Get deployment for specific account and network +deployment := deployments.ByAccountAndNetwork("my-account", "testnet") +if deployment != nil { + log.Printf("Found deployment: %d contracts\n", len(deployment.Contracts)) +} +``` + +## Complete Example + +Here's a complete example that ties everything together: + +```go +package main + +import ( + "log" + + "github.com/onflow/flowkit/v2" + "github.com/onflow/flowkit/v2/config" + "github.com/onflow/flowkit/v2/project" + "github.com/spf13/afero" +) + +func main() { + // 1. Load project state + state, err := flowkit.Load([]string{"flow.json"}, afero.Afero{Fs: afero.NewOsFs()}) + if err != nil { + log.Fatalf("Failed to load state: %v", err) + } + + // 2. Choose target network + network := config.TestnetNetwork + log.Printf("Using network: %s\n", network.Name) + + // 3. Get deployment contracts for the network + contracts, err := state.DeploymentContractsByNetwork(network) + if err != nil { + log.Fatalf("Failed to get contracts: %v", err) + } + + log.Printf("Found %d contracts for deployment\n", len(contracts)) + for _, contract := range contracts { + log.Printf(" - %s -> %s\n", contract.Name, contract.AccountAddress) + } + + // 4. Get network aliases + aliases := state.AliasesForNetwork(network) + log.Printf("Network has %d aliases\n", len(aliases)) + + // 5. Create import replacer + importReplacer := project.NewImportReplacer(contracts, aliases) + + // 6. Resolve imports in a script + scriptCode := []byte(` + import "Kibble" + import "FungibleToken" + + access(all) fun main(): String { + return "Hello, Flow!" + } + `) + + program, err := project.NewProgram(scriptCode, nil, "script.cdc") + if err != nil { + log.Fatalf("Failed to parse program: %v", err) + } + resolvedProgram, err := importReplacer.Replace(program) + if err != nil { + log.Fatalf("Failed to resolve imports: %v", err) + } + + log.Printf("Resolved script:\n%s\n", string(resolvedProgram.Code())) + + // 7. Get account for signing + account, err := state.Accounts().ByName("testnet-account") + if err != nil { + log.Fatalf("Failed to get account: %v", err) + } + + log.Printf("Using account: %s (%s)\n", account.Name, account.Address) + + log.Println("Setup complete! Ready to interact with Flow.") +} +``` + +## Conclusion + +Flowkit provides a powerful and flexible API for managing Flow projects in Go. By understanding how to work with project state, contracts, networks, and import resolution, you can build robust applications that interact with the Flow blockchain. + +The import replacer is particularly critical for ensuring your Cadence code works correctly across different networks by automatically resolving contract imports to their deployed addresses. diff --git a/docs/tools/clients/flow-go-sdk/index.md b/docs/build/tools/clients/flow-go-sdk/index.md similarity index 88% rename from docs/tools/clients/flow-go-sdk/index.md rename to docs/build/tools/clients/flow-go-sdk/index.md index f3ffe5d12b..2eea2386f3 100644 --- a/docs/tools/clients/flow-go-sdk/index.md +++ b/docs/build/tools/clients/flow-go-sdk/index.md @@ -78,7 +78,7 @@ var flowClient client.Client // initialize an http emulator client flowClient, err := http.NewClient(http.EmulatorHost) -// initialize a gPRC emulator client +// initialize a gRPC emulator client flowClient, err = grpc.NewClient(grpc.EmulatorHost) ``` @@ -303,7 +303,7 @@ Retrieve events by a given type in a specified block height range or through a l A.{contract address}.{contract name}.{event name} ``` -Please read more about [events in the documentation](../../../build/core-contracts/03-flow-token.md). The exception to this standard are +Please read more about [events in the documentation](../../../cadence/core-contracts/03-flow-token.md). The exception to this standard are core events, and you should read more about them in [this document](https://cadence-lang.org/docs/language/core-events). 📖 **Block height range** expresses the height of the start and end block in the chain. @@ -522,7 +522,7 @@ transaction(greeting: String) { 📖 **Arguments**. A transaction can accept zero or more arguments that are passed into the Cadence script. The arguments on the transaction must match the number and order declared in the Cadence script. Sample script from above accepts a single `String` argument. -📖 **[Proposal key](../../../build/basics/transactions.md#proposal-key)** must be provided to act as a sequence number and prevent reply and other potential attacks. +📖 **[Proposal key](../../../cadence/basics/transactions.md#proposal-key)** must be provided to act as a sequence number and prevent reply and other potential attacks. Each account key maintains a separate transaction sequence counter; the key that lends its sequence number to a transaction is called the proposal key. @@ -532,11 +532,11 @@ A proposal key contains three fields: - Key index - Sequence number -A transaction is only valid if its declared sequence number matches the current on-chain sequence number for that key. The sequence number increments by one after the transaction is executed. +A transaction is only valid if its declared sequence number matches the current onchain sequence number for that key. The sequence number increments by one after the transaction is executed. -📖 **[Payer](../../../build/basics/transactions.md#signer-roles)** is the account that pays the fees for the transaction. A transaction must specify exactly one payer. The payer is only responsible for paying the network and gas fees; the transaction is not authorized to access resources or code stored in the payer account. +📖 **[Payer](../../../cadence/basics/transactions.md#signer-roles)** is the account that pays the fees for the transaction. A transaction must specify exactly one payer. The payer is only responsible for paying the network and compute unit fees; the transaction is not authorized to access resources or code stored in the payer account. -📖 **[Authorizers](../../../build/basics/transactions.md#signer-roles)** are accounts that authorize a transaction to read and mutate their resources. A transaction can specify zero or more authorizers, depending on how many accounts the transaction needs to access. +📖 **[Authorizers](../../../cadence/basics/transactions.md#signer-roles)** are accounts that authorize a transaction to read and mutate their resources. A transaction can specify zero or more authorizers, depending on how many accounts the transaction needs to access. The number of authorizers on the transaction must match the number of &Account parameters declared in the prepare statement of the Cadence script. @@ -550,10 +550,15 @@ transaction { #### Gas Limit -📖 **Gas limit** is the limit on the amount of computation a transaction requires, and it will abort if it exceeds its gas limit. -Cadence uses metering to measure the number of operations per transaction. You can read more about it in the [Cadence documentation](https://cadence-lang.org/docs). +**Compute Limit** is the limit on the amount of computation a transaction requires, and it will abort if it exceeds its compute unit (gas) limit. Cadence uses metering to measure the number of operations per transaction. You can read more about it in the [Cadence documentation](https://cadence-lang.org/docs). -The gas limit depends on the complexity of the transaction script. Until dedicated gas estimation tooling exists, it's best to use the emulator to test complex transactions and determine a safe limit. +The compute limit depends on the complexity of the transaction script. Until dedicated estimation tooling exists, it's best to use the emulator to test complex transactions and determine a safe limit. + +Keep in mind that Flow is **very** efficient, so transaction fees are generally low. A limit resulting in max charges of `.001` Flow is sufficient to cover even complex transactions. + +- Flow token transfer: 19 CU. +- Single NFT Transfer: 26 CU. +- EVM Token transfer 28 CU. #### Reference Block @@ -653,9 +658,9 @@ After you have successfully [built a transaction](#build-the-transaction) the ne [](https://pkg.go.dev/github.com/onflow/flow-go-sdk#Transaction.SignEnvelope) Flow introduces new concepts that allow for more flexibility when creating and signing transactions. -Before trying the examples below, we recommend that you read through the [transaction signature documentation](../../../build/basics/transactions.md. +Before trying the examples below, we recommend that you read through the [transaction signature documentation](../../../cadence/basics/transactions.md. -After you have successfully [built a transaction](#build-the-transaction) the next step in the process is to sign it. Flow transactions have envelope and payload signatures, and you should learn about each in the [signature documentation](../../../build/basics/transactions.md). +After you have successfully [built a transaction](#build-the-transaction) the next step in the process is to sign it. Flow transactions have envelope and payload signatures, and you should learn about each in the [signature documentation](../../../cadence/basics/transactions.md). Quick example of building a transaction: @@ -699,7 +704,7 @@ if err != nil { Flow supports great flexibility when it comes to transaction signing, we can define multiple authorizers (multi-sig transactions) and have different payer account than proposer. We will explore advanced signing scenarios bellow. -### [Single party, single signature](../../../build/basics/transactions.md#single-party-single-signature) +### [Single party, single signature](../../../cadence/basics/transactions.md#single-party-single-signature) - Proposer, payer and authorizer are the same account (`0x01`). - Only the envelope must be signed. @@ -736,7 +741,7 @@ tx := flow.NewTransaction(). err := tx.SignEnvelope(account1.Address, key1.Index, key1Signer) ``` -### [Single party, multiple signatures](../../../build/basics/transactions.md#single-party-multiple-signatures) +### [Single party, multiple signatures](../../../cadence/basics/transactions.md#single-party-multiple-signatures) - Proposer, payer and authorizer are the same account (`0x01`). - Only the envelope must be signed. @@ -779,7 +784,7 @@ err := tx.SignEnvelope(account1.Address, key1.Index, key1Signer) err = tx.SignEnvelope(account1.Address, key2.Index, key2Signer) ``` -### [Multiple parties](../../../build/basics/transactions.md#multiple-parties) +### [Multiple parties](../../../cadence/basics/transactions.md#multiple-parties) - Proposer and authorizer are the same account (`0x01`). - Payer is a separate account (`0x02`). @@ -826,7 +831,7 @@ err := tx.SignPayload(account1.Address, key1.Index, key1Signer) err = tx.SignEnvelope(account2.Address, key3.Index, key3Signer) ``` -### [Multiple parties, two authorizers](../../../build/basics/transactions.md#multiple-parties) +### [Multiple parties, two authorizers](../../../cadence/basics/transactions.md#multiple-parties) - Proposer and authorizer are the same account (`0x01`). - Payer is a separate account (`0x02`). @@ -878,7 +883,7 @@ err := tx.SignPayload(account1.Address, key1.Index, key1Signer) err = tx.SignEnvelope(account2.Address, key3.Index, key3Signer) ``` -### [Multiple parties, multiple signatures](../../../build/basics/transactions.md#multiple-parties) +### [Multiple parties, multiple signatures](../../../cadence/basics/transactions.md#multiple-parties) - Proposer and authorizer are the same account (`0x01`). - Payer is a separate account (`0x02`). @@ -965,7 +970,7 @@ func demo(tx *flow.Transaction) { On Flow, account creation happens inside a transaction. Because the network allows for a many-to-many relationship between public keys and accounts, it's not possible to derive a new account address from a public key offline. -The Flow VM uses a deterministic address generation algorithm to assign account addresses on chain. You can find more details about address generation in the [accounts & keys documentation](../../../build/basics/accounts.md). +The Flow VM uses a deterministic address generation algorithm to assign account addresses on chain. You can find more details about address generation in the [accounts & keys documentation](../../../cadence/basics/accounts.md). #### Public Key @@ -975,7 +980,7 @@ Flow uses ECDSA key pairs to control access to user accounts. Each key pair can Flow represents ECDSA public keys in raw form without additional metadata. Each key is a single byte slice containing a concatenation of its X and Y components in big-endian byte form. -A Flow account can contain zero (not possible to control) or more public keys, referred to as account keys. Read more about [accounts in the documentation](../../../build/basics/accounts.md). +A Flow account can contain zero (not possible to control) or more public keys, referred to as account keys. Read more about [accounts in the documentation](../../../cadence/basics/accounts.md). An account key contains the following data: @@ -1059,7 +1064,7 @@ for _, event := range result.Events { ### Generate Keys -[](../../../build/basics/accounts.md#signature-and-hash-algorithms) +[](../../../cadence/basics/accounts.md#signature-and-hash-algorithms) Flow uses [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) signatures to control access to user accounts. Each key pair can be used in combination with the `SHA2-256` or `SHA3-256` hashing algorithms. @@ -1080,7 +1085,7 @@ encPrivateKey := privateKey.Encode() publicKey := privateKey.PublicKey() ``` -The example above uses an ECDSA key pair on the P-256 (secp256r1) elliptic curve. Flow also supports the secp256k1 curve used by Bitcoin and Ethereum. Read more about [supported algorithms here](../../../build/basics/accounts.md#signature-and-hash-algorithms). +The example above uses an ECDSA key pair on the P-256 (secp256r1) elliptic curve. Flow also supports the secp256k1 curve used by Bitcoin and Ethereum. Read more about [supported algorithms here](../../../cadence/basics/accounts.md#signature-and-hash-algorithms). ### Transferring Flow @@ -1176,3 +1181,61 @@ func main() { } } ``` + +## Stream Events + +[](https://pkg.go.dev/github.com/onflow/flow-go-sdk/client#Client.SubscribeEventsByBlockID) + +Subscribe to and stream events from an Access node using the SDK subscription primitives. The canonical example demonstrates a complete runnable implementation that connects to an access node, subscribes from a reference block, and processes an event stream. + +**[](https://github.com/onflow/flow-go-sdk/blob/master/examples/stream_events/main.go)** + +```go +// Minimal walkthrough (based on examples/stream_events/main.go) +ctx := context.Background() + +// 1) Create a client (SubscribeEvents only supported by Flow Go SDK gRPC client) +flowClient, err := grpc.NewClient(grpc.TestnetHost) +// handle err + +// 2) Obtain a reference block/header to start the subscription from +header, err := flowClient.GetLatestBlockHeader(ctx, true) +// handle err + +// 3) Subscribe for events by block ID (returns data channel, error channel, init error) +dataCh, errCh, initErr := flowClient.SubscribeEventsByBlockID(ctx, header.ID, flow.EventFilter{}) +if initErr != nil { + // handle init error +} + +// 4) Process the stream (select loop) +for { + select { + case <-ctx.Done(): + // graceful shutdown + return + case data, ok := <-dataCh: + if !ok { + // subscription closed; reconnect / exponential back-off + return + } + // data contains block-level payload with Events + for _, ev := range data.Events { + fmt.Printf("Type: %s\n", ev.Type) + fmt.Printf("Values: %v\n", ev.Value) + fmt.Printf("Transaction ID: %s\n", ev.TransactionID) + } + case err := <-errCh: + if err != nil { + // handle streaming error (log, reconnect / exponential back-off) + } + } +} +``` + +Notes & best practices + +- Use `flow.EventFilter` to subscribe only to event types / contracts you need to reduce bandwidth. +- Persist the last processed block ID/height to resume after restarts; resume subscriptions from a checkpoint. +- Treat empty payloads/heartbeats as liveness; implement reconnect and exponential back-off on termination. +- For historical backfills use `GetEventsForBlockIDs` / `GetEventsForBlockRange` instead of live streaming. diff --git a/docs/tools/clients/flow-go-sdk/migration-v0.25.0.md b/docs/build/tools/clients/flow-go-sdk/migration-v0.25.0.md similarity index 100% rename from docs/tools/clients/flow-go-sdk/migration-v0.25.0.md rename to docs/build/tools/clients/flow-go-sdk/migration-v0.25.0.md diff --git a/docs/tools/clients/index.md b/docs/build/tools/clients/index.md similarity index 79% rename from docs/tools/clients/index.md rename to docs/build/tools/clients/index.md index 8e0dfca8c2..25bf192281 100644 --- a/docs/tools/clients/index.md +++ b/docs/build/tools/clients/index.md @@ -10,11 +10,7 @@ keywords: - JavaScript - Go - Python - - Ruby - JVM - - Swift - - .NET - - Rust - PHP - Elixir - HTTP API @@ -33,6 +29,14 @@ keywords: Flow provides a comprehensive suite of client tools and SDKs designed to help developers build applications that interact with the Flow blockchain. These tools support various programming languages and platforms, offering different levels of abstraction and functionality. +> Terminology note +> +> Anywhere an API or SDK accepts a Flow transaction ID, you may also provide a scheduled transaction ID: +> - Transaction ID: 256-bit hash represented as a 64-character hex string +> - Scheduled transaction ID: UInt64 represented as a decimal string +> +> For REST endpoints like `/v1/transactions/{id}` and `/v1/transaction_results/{id}`, the server treats the `id` as a transaction ID if it parses as hex; otherwise, as a scheduled transaction ID if it parses as a decimal UInt64. Both return identical response schemas. See the Protocol docs for details (`docs/protocol/access-onchain-data/index.md`). + ## JavaScript (FCL) [Flow Client Library (FCL)] is the primary JavaScript/TypeScript client for Flow. It provides: @@ -63,16 +67,6 @@ Flow provides a comprehensive suite of client tools and SDKs designed to help de - Event monitoring - Easy integration with Python applications -## Ruby - -[FlowClient] is a Ruby gRPC client that enables: - -- Direct blockchain communication -- Transaction processing -- Account management -- Event handling -- Ruby-native blockchain integration - ## JVM [Flow JVM SDK] supports JVM-compatible languages (Java, Kotlin, Scala) with: @@ -83,36 +77,6 @@ Flow provides a comprehensive suite of client tools and SDKs designed to help de - Event subscription - Cross-platform compatibility -## Swift - -[flow-swift] is designed for iOS development, offering: - -- Native iOS integration -- Wallet connectivity -- Transaction management -- Account handling -- SwiftUI support - -## .NET - -[flow.net] provides .NET developers with: - -- C# and .NET Core support -- Transaction management -- Account handling -- Event monitoring -- Cross-platform compatibility - -## Rust - -[Rust SDK] offers Rust developers: - -- High-performance blockchain interaction -- Type-safe transaction handling -- Account management -- Event subscription -- Memory safety guarantees - ## PHP [PHP SDK] enables PHP developers to: diff --git a/docs/build/tools/emulator/index.md b/docs/build/tools/emulator/index.md new file mode 100644 index 0000000000..d278f1d38d --- /dev/null +++ b/docs/build/tools/emulator/index.md @@ -0,0 +1,236 @@ +--- +title: Flow Emulator +description: Local Flow network for development and testing +sidebar_position: 3 +keywords: + - Flow Emulator + - local development + - testing + - flow emulator --fork + - fork mode + - emulator flags + - mainnet fork + - testnet fork + - fork-height + - fork-host + - gRPC server + - REST API + - snapshots + - persistent storage + - block time + - code coverage + - debugging + - service account + - Flow CLI + - local blockchain + - E2E testing + - off-chain mocking +--- + +The Flow Emulator is a lightweight tool that emulates the behavior of the real Flow network for local development and testing. + +## Installation + +The emulator is included with the [Flow CLI]. Follow the [installation guide] to get started. + +## Quick Start + +First, create a `flow.json` configuration file: + +```bash +flow init --config-only +``` + +Then start the Flow Emulator in fork mode (defaults to mainnet when value omitted): + +```bash +flow emulator --fork +``` + +You'll see output similar to: + +```bash +INFO[0000] ⚙️ Using service account 0xf8d6e0586b0a20c7 serviceAddress=f8d6e0586b0a20c7 ... +INFO[0000] 🌱 Starting Flow Emulator +INFO[0000] 🛠 GRPC server started on 127.0.0.1:3569 +INFO[0000] 📡 HTTP server started on 127.0.0.1:8080 +``` + +This starts a local Flow network with: + +- gRPC server on port `3569` +- REST API on `http://localhost:8888` +- Admin API on port `8080` + +## Available commands + +- `snapshot`: Create/Load/List emulator snapshots. See: [Create Emulator Snapshot] + +## Key flags + +- **Networking** + - `--host `: Host to listen on for gRPC, REST, and Admin (default: all interfaces) + - `--port, -p `: gRPC port (default `3569`) + - `--rest-port `: REST API port (default `8888`) + - `--admin-port `: Admin API port (default `8080`) + - `--debugger-port `: Debug Adapter Protocol port (default `2345`) + - `--grpc-debug`: Turn on gRPC server reflection + - `--rest-debug`: Turn on REST API debug output + +- **State and Persistence** + - `--persist`: Turn on persistent storage (default disabled) + - `--dbpath `: Directory for on-disk state (default `./flowdb`) + - `--sqlite-url `: Use SQLite storage backend + - `--redis-url `: Use Redis storage backend + - `--checkpoint-dir `: Load state from checkpoint directory + - `--state-hash `: Load state from checkpoint state hash + +- **Forking** + - `--fork `: Start the emulator in fork mode using a network from `flow.json`. If provided without a value, defaults to `mainnet`. + - `--fork-host `: Access node to query when you fork Mainnet or Testnet + - `--fork-height `: Starting block height when you fork + +- **Cadence and VM** + - `--block-time, -b `: Time between sealed blocks (for exxample, `1s`, `300ms`) + - `--coverage-reporting`: Turn on code coverage reporting + - `--computation-reporting`: Turn on computation reporting + - `--legacy-upgrade`: Turn on legacy contract upgrade behavior + - `--scheduled-transactions`: Turn on scheduled transactions (default true) + - `--script-compute-limit `: Compute unit limit for scripts (default `100000`) + - `--transaction-max-compute-limit `: Max transaction compute unit limit (default `9999`) + - `--transaction-expiry `: Transaction expiry in blocks (default `10`) + - `--skip-tx-validation`: Skip tx signature and sequence number checks + - `--simple-addresses`: Use sequential addresses starting with `0x01` + - `--storage-limit`: Enforce account storage limit (default true) + - `--storage-per-flow `: MB of storage per 1 FLOW token + - `--token-supply `: Initial FLOW token supply (default `1000000000.0`) + - `--transaction-fees`: Turn on transaction fees + - `--setup-evm`: Deploy EVM contracts (default true) + - `--setup-vm-bridge`: Deploy VM Bridge contracts (default true) + +- **Service Account and Identity** + - `--chain-id `: Address generation chain (default `emulator`) + - `--service-priv-key ` / `--service-pub-key `: Service account keys + - `--service-sig-algo `: Service key signature algo (default `ECDSA_P256`) + - `--service-hash-algo `: Service key hash algo (default `SHA3_256`) + - `--min-account-balance `: Minimum account balance or account creation cost + - `--contracts`: Deploy common contracts on start + - `--contract-removal`: Allow contract removal for development (default true) + - `--init`: Initialize a new account profile + +- **Logging and Output** + - `--verbose, -v`: Verbose logging + - `--log-format `: Logging output format (default `text`) + +- **Snapshots** + - `--snapshot`: Enable snapshots in the emulator + +## Examples + +```bash +# Verbose logs +flow emulator --verbose + +# Custom ports +flow emulator --port 9000 --rest-port 9001 --admin-port 9002 + +# Custom block time (1 second between blocks) +flow emulator --block-time 1s + +# Persist state on disk +flow emulator --persist --dbpath ./flowdb + +# Fork from Mainnet using flow.json +flow emulator --fork + +# Fork from Testnet using flow.json and pin to a height +flow emulator --fork testnet --fork-height 12345678 + +# Fork from Testnet at a specific height +flow emulator --fork-host access.devnet.nodes.onflow.org:9000 --fork-height 12345678 + +# Disable fees and use simple addresses for local testing +flow emulator --transaction-fees=false --simple-addresses + +# Enable code coverage reporting +flow emulator --coverage-reporting + +# Change the gRPC and REST API ports +flow emulator --port 9000 --rest-port 9001 + +# For a complete list of available flags, run: +flow emulator --help +``` + +For the complete and current list of flags, run: + +```bash +flow emulator --help +``` + +## Debugging and Testing + +- **Code Coverage**: Add `--coverage-reporting` flag and visit `http://localhost:8080/emulator/codeCoverage` +- **Computation Profiling**: Add `--computation-profiling` and/or `--computation-reporting` flags to analyze computational costs and identify performance bottlenecks in your Cadence code. See the [Cadence Computation Profiling guide] for detailed instructions. +- **Debugging**: Use `#debugger()` pragma in Cadence code for breakpoints +- **Fork mode note**: When you use `flow emulator --fork`, only Flow chain state is available. External oracles/APIs and cross-chain reads are not live; mock these or run local stub services for E2E. + +### Fork Mode Tutorial + +For a complete guide on using the emulator in fork mode with dapps, E2E tests, and account impersonation, see: [Interactive Testing with Forked Emulator]. + +## Snapshots + +The Flow CLI provides a command to create emulator snapshots, which are points in blockchain history you can later jump to and reset the state to that moment. This can be useful to test where you establish a beginning state, run tests and after revert back to the initial state. + +### Quick snapshot workflow + +```bash +# 1) Start the emulator with snapshots enabled (in a separate terminal) +flow emulator --snapshot + +# 2) Create a snapshot at the current state +flow emulator snapshot create baseline + +# 3) Make changes, run tests, etc. + +# 4) Reset the emulator back to the snapshot +flow emulator snapshot load baseline +``` + +### Create a new snapshot + +Create a new emulator snapshot at the current block with a name of `myInitialState`. + +```shell +flow emulator snapshot create myInitialState +``` + +### Load a current snapshot + +To jump to a previously created snapshot we use the load command in combination with the name. + +```shell +flow emulator snapshot load myInitialState +``` + +### List all snapshots + +To list all the snapshots we previously created and can load to run: + +```shell +flow emulator list +``` + +## Additional resources + +To learn more about how to use the Emulator, have a look at the [public GitHub repository]. + + + +[Flow CLI]: ../flow-cli/index.md +[installation guide]: ../flow-cli/install.md +[Create Emulator Snapshot]: ../flow-cli/utils/snapshot-save.md +[public GitHub repository]: https://github.com/onflow/flow-emulator +[Interactive Testing with Forked Emulator]: ../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md +[Cadence Computation Profiling guide]: ../../cadence/advanced-concepts/computation-profiling.md diff --git a/docs/tools/error-codes.md b/docs/build/tools/error-codes.md similarity index 98% rename from docs/tools/error-codes.md rename to docs/build/tools/error-codes.md index 4fe60f8861..52776f36bc 100644 --- a/docs/tools/error-codes.md +++ b/docs/build/tools/error-codes.md @@ -99,7 +99,7 @@ Example: Example: `[Error Code: 1103] The account with address (xxx) uses 96559611 bytes of storage which is over its capacity (96554500 bytes). Capacity can be increased by adding FLOW tokens to the account.` -For more information refer to [Fees](../build/basics/fees.md#maximum-available-balance) +For more information refer to [Fees](../cadence/basics/fees.md#maximum-available-balance) ### 1105 diff --git a/docs/tools/flow-cli/_template.md b/docs/build/tools/flow-cli/_template.md similarity index 96% rename from docs/tools/flow-cli/_template.md rename to docs/build/tools/flow-cli/_template.md index 8aec04d9b0..14fa6aa095 100644 --- a/docs/tools/flow-cli/_template.md +++ b/docs/build/tools/flow-cli/_template.md @@ -34,7 +34,7 @@ description: -description- - Name: `address` - Valid Input: Flow account address -Flow [account address](../../../build/basics/accounts.md) (prefixed with `0x` or not). +Flow [account address](../../../cadence/basics/accounts.md) (prefixed with `0x` or not). ## Flags diff --git a/docs/tools/flow-cli/accounts/_category_.json b/docs/build/tools/flow-cli/accounts/_category_.json similarity index 100% rename from docs/tools/flow-cli/accounts/_category_.json rename to docs/build/tools/flow-cli/accounts/_category_.json diff --git a/docs/tools/flow-cli/accounts/account-add-contract.md b/docs/build/tools/flow-cli/accounts/account-add-contract.md similarity index 80% rename from docs/tools/flow-cli/accounts/account-add-contract.md rename to docs/build/tools/flow-cli/accounts/account-add-contract.md index a4baf7d27c..eb87eb629b 100644 --- a/docs/tools/flow-cli/accounts/account-add-contract.md +++ b/docs/build/tools/flow-cli/accounts/account-add-contract.md @@ -3,18 +3,18 @@ title: Deploy a Contract sidebar_position: 3 --- -Deploy a new contract to a Flow account using the Flow CLI. +Deploy a new contract to a Flow account with the Flow CLI. ```shell flow accounts add-contract [ ...] [flags] ``` -⚠️ Deprecation notice: using name argument in adding contract command will be deprecated soon. +⚠️ Deprecation notice: we will deprecate the name argument in adding contract command soon. ```shell flow accounts add-contract [ ...] [flags] ``` -## Example Usage +## Example usage ```shell > flow accounts add-contract ./FungibleToken.cdc @@ -36,7 +36,7 @@ Key 0 Public Key 640a5a359bf3536d15192f18d872d57c98a96cb871b92b70cecb0739c2d5c Contracts Deployed: 1 Contract: 'FungibleToken' ``` -**Testnet Example** +**Testnet example** ``` > flow accounts add-contract ./FungibleToken.cdc --signer alice --network testnet @@ -79,10 +79,10 @@ Path to the file containing the contract source code. ### Arguments - Name: `argument` -- Valid inputs: valid [cadence values](https://cadencelang.dev/docs/1.0/json-cadence-spec) - matching argument type in transaction code. +- Valid inputs: valid [cadence values] + that match argument type in transaction code. -Input arguments values matching corresponding types in the source code and passed in the same order. +Input arguments values that match corresponding types in the source code and passed in the same order. Example: ```shell @@ -113,9 +113,9 @@ Specify the name of the account that will be used to sign the transaction. Arguments passed to the Cadence transaction in Cadence JSON format. Cadence JSON format contains `type` and `value` keys and is -[documented here](https://cadencelang.dev/docs/1.0/json-cadence-spec). +[documented here]. -### Include Fields +### Include fields - Flag: `--include` - Valid inputs: `contracts` @@ -129,17 +129,14 @@ Specify fields to include in the result output. Applies only to the text output. - Valid inputs: an IP address or hostname. - Default: `127.0.0.1:3569` (Flow Emulator) -Specify the hostname of the Access API that will be -used to execute the command. This flag overrides -any host defined by the `--network` flag. +Specify the hostname of the Access API that will be used to execute the command. This flag overrides any host defined by the `--network` flag. -### Network Key +### Network key - Flag: `--network-key` - Valid inputs: A valid network public key of the host in hex string format -Specify the network public key of the Access API that will be -used to create a secure GRPC client when executing the command. +Specify the network public key of the Access API that will be used to create a secure GRPC client when you execute the command. ### Network @@ -191,12 +188,17 @@ Specify the log level. Control how much output you want to see during command ex - Default: `flow.json` Specify the path to the `flow.json` configuration file. -You can use the `-f` flag multiple times to merge -several configuration files. -### Version Check +You can use the `-f` flag multiple times to merge several configuration files. + +### Version check - Flag: `--skip-version-check` - Default: `false` Skip version check during start up to speed up process for slow connections. + + + +[cadence values]: https://cadencelang.dev/docs/1.0/json-cadence-spec +[documented here]: https://cadencelang.dev/docs/1.0/json-cadence-spec \ No newline at end of file diff --git a/docs/build/tools/flow-cli/accounts/account-fund.md b/docs/build/tools/flow-cli/accounts/account-fund.md new file mode 100644 index 0000000000..5319fafced --- /dev/null +++ b/docs/build/tools/flow-cli/accounts/account-fund.md @@ -0,0 +1,69 @@ +--- +title: Funding a Testnet Account +description: How to fund a Testnet Flow account from the command line +sidebar_position: 7 +--- + +:::info + +The [Flow Testnet Faucet] allows users to create accounts and receive 1,000 Testnet FLOW tokens for testing and development purposes. You can also fund a current Testnet account without the need to create one through the site, or through the CLI. + +::: + +Fund a valid Testnet Flow Account with the Flow CLI. + +```shell +flow accounts fund [address|name] +``` + +## Example usage + +### Fund by address + +``` +> flow accounts fund 8e94eaa81771313a + +Opening the faucet to fund 0x8e94eaa81771313a on your native browser. + +If there is an issue, please use this link instead: https://testnet-faucet.onflow.org/fund-account?address=8e94eaa81771313a + +``` + +### Fund by account name + +``` +> flow accounts fund testnet-account + +Opening the faucet to fund 0x8e94eaa81771313a on your native browser. + +If there is an issue, please use this link instead: https://testnet-faucet.onflow.org/fund-account?address=8e94eaa81771313a + +``` + +### Interactive prompt + +``` +> flow accounts fund + +? Select account to fund: (Use arrow keys) +❯ testnet-account (0x8e94eaa81771313a) + emulator-account (0x0ae53cb6e3f42a79) + +``` + +## Arguments + +### Address or account name (optional) + +- Name: `address|name` +- Valid Input: Flow Testnet account address or account name from `flow.json` + +You can provide: +- A Flow [account address](../../../cadence/basics/accounts.md) (prefixed with `0x` or not) +- An account name configured in your `flow.json` +- No argument to get an interactive prompt for account selection + + + +[Flow Testnet Faucet]: https://testnet-faucet.onflow.org/ +[account address]: ../../../cadence/basics/accounts.md \ No newline at end of file diff --git a/docs/tools/flow-cli/accounts/account-remove-contract.md b/docs/build/tools/flow-cli/accounts/account-remove-contract.md similarity index 85% rename from docs/tools/flow-cli/accounts/account-remove-contract.md rename to docs/build/tools/flow-cli/accounts/account-remove-contract.md index 82cbc672f1..577c2677c7 100644 --- a/docs/tools/flow-cli/accounts/account-remove-contract.md +++ b/docs/build/tools/flow-cli/accounts/account-remove-contract.md @@ -4,13 +4,13 @@ sidebar_position: 5 --- _This feature is only found in the Emulator. You **cannot** remove a contract on Testnet or Mainnet._ -Remove an existing contract deployed to a Flow account using the Flow CLI. +Remove a contract deployed to a Flow account with the Flow CLI. ```shell flow accounts remove-contract ``` -## Example Usage +## Example usage ```shell > flow accounts remove-contract FungibleToken @@ -31,7 +31,7 @@ Key 0 Public Key 640a5a359bf3536d15192f18d872d57c98a96cb871b92b70cecb0739c2d5c Contracts Deployed: 0 ``` -**Testnet Example** +**Testnet example** ``` > flow accounts remove-contract FungibleToken --signer alice --network testnet @@ -72,7 +72,7 @@ Name of the contract as it is defined in the contract source code. Specify the name of the account that will be used to sign the transaction. -### Include Fields +### Include fields - Flag: `--include` - Valid inputs: `contracts` @@ -86,17 +86,14 @@ Specify fields to include in the result output. Applies only to the text output. - Valid inputs: an IP address or hostname. - Default: `127.0.0.1:3569` (Flow Emulator) -Specify the hostname of the Access API that will be -used to execute the command. This flag overrides -any host defined by the `--network` flag. +Specify the hostname of the Access API that will be used to execute the command. This flag overrides any host defined by the `--network` flag. -### Network Key +### Network key - Flag: `--network-key` - Valid inputs: A valid network public key of the host in hex string format -Specify the network public key of the Access API that will be -used to create a secure GRPC client when executing the command. +Specify the network public key of the Access API that will be used to create a secure GRPC client when executing the command. ### Network @@ -147,9 +144,7 @@ Specify the log level. Control how much output you want to see during command ex - Valid inputs: a path in the current filesystem - Default: `flow.json` -Specify the path to the `flow.json` configuration file. -You can use the `-f` flag multiple times to merge -several configuration files. +Specify the path to the `flow.json` configuration file. You can use the `-f` flag multiple times to merge several configuration files. ### Version Check @@ -157,3 +152,5 @@ several configuration files. - Default: `false` Skip version check during start up to speed up process for slow connections. + + diff --git a/docs/tools/flow-cli/accounts/account-staking-info.md b/docs/build/tools/flow-cli/accounts/account-staking-info.md similarity index 86% rename from docs/tools/flow-cli/accounts/account-staking-info.md rename to docs/build/tools/flow-cli/accounts/account-staking-info.md index 35d62adc7b..783eab74f5 100644 --- a/docs/tools/flow-cli/accounts/account-staking-info.md +++ b/docs/build/tools/flow-cli/accounts/account-staking-info.md @@ -4,13 +4,13 @@ description: How to get staking info sidebar_position: 6 --- -Retrieve staking information for the account on the Flow network using Flow CLI. +Retrieve staking information for the account on the Flow network with Flow CLI. ```shell flow accounts staking-info
``` -## Example Usage +## Example usage ```shell > accounts staking-info 535b975637fb6bee --host access.testnet.nodes.onflow.org:9000 @@ -49,35 +49,31 @@ Account Delegation Info: - Name: `address` - Valid Input: Flow account address. -Flow [account address](../../../build/basics/accounts.md) (prefixed with `0x` or not). +Flow [account address] (prefixed with `0x` or not). ## Flags -### Include Fields +### Include fields - Flag: `--include` - Valid inputs: `contracts` Specify fields to include in the result output. Applies only to the text output. - ### Host - Flag: `--host` - Valid inputs: an IP address or hostname. - Default: `127.0.0.1:3569` (Flow Emulator) -Specify the hostname of the Access API that will be -used to execute the command. This flag overrides -any host defined by the `--network` flag. +Specify the hostname of the Access API that will be used to execute the command. This flag overrides any host defined by the `--network` flag. -### Network Key +### Network key - Flag: `--network-key` - Valid inputs: A valid network public key of the host in hex string format -Specify the network public key of the Access API that will be -used to create a secure GRPC client when executing the command. +Specify the network public key of the Access API that will be used to create a secure GRPC client when you execute the command. ### Network @@ -132,9 +128,13 @@ Specify the path to the `flow.json` configuration file. You can use the `-f` flag multiple times to merge several configuration files. -### Version Check +### Version check - Flag: `--skip-version-check` - Default: `false` Skip version check during start up to speed up process for slow connections. + + + +[account address]: ../../../cadence/basics/accounts.md \ No newline at end of file diff --git a/docs/tools/flow-cli/accounts/account-update-contract.md b/docs/build/tools/flow-cli/accounts/account-update-contract.md similarity index 77% rename from docs/tools/flow-cli/accounts/account-update-contract.md rename to docs/build/tools/flow-cli/accounts/account-update-contract.md index 52276a24b7..b798ea5ccd 100644 --- a/docs/tools/flow-cli/accounts/account-update-contract.md +++ b/docs/build/tools/flow-cli/accounts/account-update-contract.md @@ -3,18 +3,18 @@ title: Update a Contract sidebar_position: 4 --- -Update an existing contract deployed to a Flow account using the Flow CLI. +Update a contract deployed to a Flow account with the Flow CLI. ```shell flow accounts update-contract [ ...] [flags] ``` -⚠️ Deprecation notice: using name argument in update contract command will be deprecated soon. +⚠️ Deprecation notice: We will depreate the name argument in update contract command soon. ```shell flow accounts update-contract [ ...] [flags] ``` -## Example Usage +## Example usage ```shell > flow accounts update-contract ./FungibleToken.cdc @@ -36,7 +36,7 @@ Key 0 Public Key 640a5a359bf3536d15192f18d872d57c98a96cb871b92b70cecb0739c2d5c Contracts Deployed: 1 Contract: 'FungibleToken' ``` -**Testnet Example** +**Testnet example** ``` > flow accounts update-contract ./FungibleToken.cdc --signer alice --network testnet @@ -73,14 +73,13 @@ Name of the contract as it is defined in the contract source code. - Name: `filename` - Valid inputs: Any filename and path valid on the system. -Filename of the file containing contract source code. +Filename of the file that contains contract source code. ### Arguments - Name: `argument` -- Valid inputs: valid [cadence values](https://cadencelang.dev/docs/1.0/json-cadence-spec) - matching argument type in transaction code. +- Valid inputs: valid [cadence values] that match thr argument type in transaction code. -Input arguments values matching corresponding types in the source code and passed in the same order. +Input arguments values that match corresponding types in the source code and passed in the same order. Example: ```shell @@ -108,7 +107,7 @@ Specify the name of the account that will be used to sign the transaction. - Flag: `--show-diff` - Valid inputs: `true`, `false` -Shows a diff to approve before updating between deployed contract and new contract updates. +Shows a diff to approve before you update between deployed contract and new contract updates. ### Arguments JSON @@ -117,8 +116,8 @@ Shows a diff to approve before updating between deployed contract and new contra - Example: `flow accounts update-contract ./tx.cdc '[{"type": "String", "value": "Hello"}]'` Arguments passed to the Cadence transaction in Cadence JSON format. -Cadence JSON format contains `type` and `value` keys and is -[documented here](https://cadencelang.dev/docs/1.0/json-cadence-spec). + +Cadence JSON format contains `type` and `value` keys and is [documented here]. ### Include Fields @@ -133,17 +132,14 @@ Specify fields to include in the result output. Applies only to the text output. - Valid inputs: an IP address or hostname. - Default: `127.0.0.1:3569` (Flow Emulator) -Specify the hostname of the Access API that will be -used to execute the command. This flag overrides -any host defined by the `--network` flag. +Specify the hostname of the Access API that will be used to execute the command. This flag overrides any host defined by the `--network` flag. -### Network Key +### Network key - Flag: `--network-key` - Valid inputs: A valid network public key of the host in hex string format -Specify the network public key of the Access API that will be -used to create a secure GRPC client when executing the command. +Specify the network public key of the Access API that will be used to create a secure GRPC client when you execute the command. ### Network @@ -195,12 +191,17 @@ Specify the log level. Control how much output you want to see during command ex - Default: `flow.json` Specify the path to the `flow.json` configuration file. -You can use the `-f` flag multiple times to merge -several configuration files. + +You can use the `-f` flag multiple times to merge several configuration files. ### Version Check - Flag: `--skip-version-check` - Default: `false` -Skip version check during start up to speed up process for slow connections. \ No newline at end of file +Skip version check during start up to speed up process for slow connections. + + + +[cadence values]: https://cadencelang.dev/docs/1.0/json-cadence-spec +[documented here]: https://cadencelang.dev/docs/1.0/json-cadence-spec \ No newline at end of file diff --git a/docs/tools/flow-cli/accounts/create-accounts.md b/docs/build/tools/flow-cli/accounts/create-accounts.md similarity index 59% rename from docs/tools/flow-cli/accounts/create-accounts.md rename to docs/build/tools/flow-cli/accounts/create-accounts.md index 2a40a737c0..702f704bd7 100644 --- a/docs/tools/flow-cli/accounts/create-accounts.md +++ b/docs/build/tools/flow-cli/accounts/create-accounts.md @@ -4,18 +4,19 @@ description: How to create a Flow account from the command line sidebar_position: 2 --- -The Flow CLI provides a command to submit an account creation -transaction to any Flow Access API. There are two options how to create an account, you can use the -interactive mode which guides you through the process and creates the account for you or by using -the manual process which requires a pre-existing account on the network you chose. +The Flow CLI provides a command to submit an account creation transaction to any Flow Access API. + +There are two options how to create an account: +- Use the interactive mode which guides you through the process and creates the account for you. +- Use the manual process which requires a current account on the network you chose. ## Interactive Mode -Creating the account in interactive mode prompts you for an account name and network selection. -After you enter the required information the account will be created for you and saved to `flow.json`. -If account creation is done on testnet or mainnet the account key will be saved to a separate key file, -which will also be put in `.gitignore`. You can [read more about key security here](../flow.json/security.md). -💡 _Please note that the account creation process can take up to a minute so please be patient._ +When you create the account in interactive mode, the system prompts you for an account name and network selection. + +After you enter the required information, the system creates the account for you and saves it to `flow.json`. If account creation is done on testnet or mainnet the account key is saved to a separate key file, which will also be put in `.gitignore`. You can [read more about key security here]. + +💡 _The account creation process can take up to a minute, so please be patient._ ```shell flow accounts create @@ -31,10 +32,11 @@ Here’s a summary of all the actions that were taken: - Added mike.pkey to .gitignore. ``` -## Manual Mode -Manual mode requires you to have a pre-existing account on the network which you will have to provide as a signer. -That account must be added to `flow.json` for the command to work. You also have to generate a key pair, we -suggest using the `flow keys generate` command, [which you can read more about here](../keys/generate-keys.md). +## Manual mode + +Manual mode requires you to have a current account on the network, which you will have to provide as a signer. You must add that account to `flow.json` for the command to work. + +You also have to generate a key pair, we suggest you use the `flow keys generate` command, [which you can read more about here]. ```shell # Create an account on Flow Testnet @@ -69,15 +71,14 @@ In the above example, the `flow.json` file would look something like this: ## Flags -### Public Key +### Public key - Flag: `--key` - Valid inputs: a hex-encoded public key in raw form. -Specify the public key that will be added to the new account -upon creation. +Specify the public key that the system adds to the new account upon creation. -### Key Weight +### Key weight - Flag: `--key-weight` - Valid inputs: number between 0 and 1000 @@ -85,46 +86,41 @@ upon creation. Specify the weight of the public key being added to the new account. -When opting to use this flag, you must specify a `--key-weight` flag for each public `--key` flag provided. +When you use this flag, you must specify a `--key-weight` flag for each public `--key` flag provided. -### Public Key Signature Algorithm +### Public key signature algorithm - Flag: `--sig-algo` - Valid inputs: `"ECDSA_P256", "ECDSA_secp256k1"` - Default: `"ECDSA_P256"` -Specify the ECDSA signature algorithm for the provided public key. -This option can only be used together with the `--key` flag. +Specify the ECDSA signature algorithm for the provided public key. This option can only be used together with the `--key` flag. Flow supports the secp256k1 and P-256 curves. -### Public Key Hash Algorithm +### Public key hash algorithm - Flag: `--hash-algo` - Valid inputs: `"SHA2_256", "SHA3_256"` - Default: `"SHA3_256"` -Specify the hash algorithm that will be paired with the public key -upon account creation. +Specify the hash algorithm that will be paired with the public key upon account creation. ### Signer - Flag: `--signer` - Valid inputs: the name of an account defined in `flow.json`. -Specify the name of the account that will be used to sign the transaction -and pay the account creation fee. +Specify the name of the account that will be used to sign the transaction and pay the account creation fee. ### Contract - Flag: `--contract` -- Valid inputs: String with format `name:filename`, where `name` is - name of the contract as it is defined in the contract source code - and `filename` is the filename of the contract source code. +- Valid inputs: String with format `name:filename`, where `name` is the name of the contract as it is defined in the contract source code, and `filename` is the filename of the contract source code. Specify one or more contracts to be deployed during account creation. -### Include Fields +### Include fields - Flag: `--include` - Valid inputs: `contracts` @@ -137,17 +133,14 @@ Specify fields to include in the result output. Applies only to the text output. - Valid inputs: an IP address or hostname. - Default: `127.0.0.1:3569` (Flow Emulator) -Specify the hostname of the Access API that will be -used to execute the command. This flag overrides -any host defined by the `--network` flag. +Specify the hostname of the Access API that will be used to execute the command. This flag overrides any host defined by the `--network` flag. -### Network Key +### Network key - Flag: `--network-key` - Valid inputs: A valid network public key of the host in hex string format -Specify the network public key of the Access API that will be -used to create a secure GRPC client when executing the command. +Specify the network public key of the Access API that will be used to create a secure GRPC client when you execute the command. ### Network @@ -180,7 +173,7 @@ Specify the format of the command results. - Short Flag: `-s` - Valid inputs: a path in the current filesystem. -Specify the filename where you want the result to be saved +Specify the filename where you want the result to be saved. ### Log @@ -198,13 +191,16 @@ Specify the log level. Control how much output you want to see during command ex - Valid inputs: a path in the current filesystem. - Default: `flow.json` -Specify the path to the `flow.json` configuration file. -You can use the `-f` flag multiple times to merge -several configuration files. +Specify the path to the `flow.json` configuration file. You can use the `-f` flag multiple times to merge several configuration files. -### Version Check +### Version check - Flag: `--skip-version-check` - Default: `false` -Skip version check during start up to speed up process for slow connections. \ No newline at end of file +Skip version check during start up to speed up process for slow connections. + + + +[read more about key security here]: ../flow.json/security.md +[which you can read more about here]: ../keys/generate-keys.md diff --git a/docs/tools/flow-cli/accounts/get-accounts.md b/docs/build/tools/flow-cli/accounts/get-accounts.md similarity index 78% rename from docs/tools/flow-cli/accounts/get-accounts.md rename to docs/build/tools/flow-cli/accounts/get-accounts.md index b80968c075..42efb6a6a5 100644 --- a/docs/tools/flow-cli/accounts/get-accounts.md +++ b/docs/build/tools/flow-cli/accounts/get-accounts.md @@ -10,13 +10,14 @@ The Flow CLI provides a command to fetch any account by its address from the Flo flow accounts get
``` -## Example Usage +## Example usage ```shell flow accounts get 0xf8d6e0586b0a20c7 ``` ### Example response + ```shell Address 0xf8d6e0586b0a20c7 Balance 99999999999.70000000 @@ -44,12 +45,11 @@ Contract: 'FlowStorageFees' - Name: `address` - Valid Input: Flow account address -Flow [account address](../../../build/basics/accounts.md) (prefixed with `0x` or not). - +Flow [account address] (prefixed with `0x` or not). ## Flags -### Include Fields +### Include fields - Flag: `--include` - Valid inputs: `contracts` @@ -62,17 +62,14 @@ Specify fields to include in the result output. Applies only to the text output. - Valid inputs: an IP address or hostname. - Default: `127.0.0.1:3569` (Flow Emulator) -Specify the hostname of the Access API that will be -used to execute the command. This flag overrides -any host defined by the `--network` flag. +Specify the hostname of the Access API that will be used to execute the command. This flag overrides any host defined by the `--network` flag. -### Network Key +### Network key - Flag: `--network-key` - Valid inputs: A valid network public key of the host in hex string format -Specify the network public key of the Access API that will be -used to create a secure GRPC client when executing the command. +Specify the network public key of the Access API that will be used to create a secure GRPC client when you execute the command. ### Network @@ -105,7 +102,7 @@ Specify the format of the command results. - Short Flag: `-s` - Valid inputs: a path in the current filesystem. -Specify the filename where you want the result to be saved +Specify the filename where you want the result to be saved. ### Log @@ -124,12 +121,16 @@ Specify the log level. Control how much output you want to see during command ex - Default: `flow.json` Specify the path to the `flow.json` configuration file. -You can use the `-f` flag multiple times to merge -several configuration files. -### Version Check +You can use the `-f` flag multiple times to merge several configuration files. + +### Version check - Flag: `--skip-version-check` - Default: `false` -Skip version check during start up to speed up process for slow connections. \ No newline at end of file +Skip version check during start up to speed up process for slow connections. + + + +[account address]: ../../../cadence/basics/accounts.md \ No newline at end of file diff --git a/docs/build/tools/flow-cli/commands.md b/docs/build/tools/flow-cli/commands.md new file mode 100644 index 0000000000..a3442333f1 --- /dev/null +++ b/docs/build/tools/flow-cli/commands.md @@ -0,0 +1,434 @@ +--- +title: Commands Overview +description: Essential Flow CLI commands for project development +sidebar_position: 2 +--- + +Flow CLI provides a set of powerful commands that simplify your development workflow. These "super commands" handle complex tasks automatically, letting you focus on writing your smart contracts while the CLI manages the rest. + +## Project Lifecycle + +### 1. Initialize a Project + +Start a new Flow project with `flow init`: + +```bash +flow init my-project +``` + +This creates: +- `flow.json` - Project configuration +- `cadence/` directory structure +- Example contracts, scripts, and tests +- Emulator account setup + +**Options:** +```bash +# Configuration only (no project structure) +flow init --config-only + +# Global configuration +flow init --global + +# Custom service account +flow init --service-private-key +``` + +📖 **[Learn more about project initialization](./flow.json/initialize-configuration.md)** + +### 2. Generate Project Files + +Create new files with the `flow generate` command: + +```bash +# Generate a new contract +flow generate contract MyToken + +# Generate a new script +flow generate script GetBalance + +# Generate a new transaction +flow generate transaction TransferTokens + +# Generate a new test +flow generate test MyToken +``` + +**Generated Structure:** +``` +cadence/ +├── contracts/ +│ └── MyToken.cdc +├── scripts/ +│ └── GetBalance.cdc +├── transactions/ +│ └── TransferTokens.cdc +└── tests/ + └── MyToken_test.cdc +``` + +📖 **[Learn more about generating Cadence boilerplate](./generate.md)** + +### 3. Run Tests + +Test your contracts with `flow test`: + +```bash +# Run all tests +flow test + +# Run specific test file +flow test cadence/tests/MyToken_test.cdc + +# Run with coverage +flow test --coverage + +# Run with verbose output +flow test --verbose +``` + +📖 **[Learn more about testing](./tests.md)** + +### 4. Deploy Contracts + +Deploy your contracts with `flow project deploy`: + +```bash +# Deploy to emulator +flow project deploy + +# Deploy to testnet +flow project deploy --network=testnet + +# Deploy to mainnet +flow project deploy --network=mainnet + +# Update existing contracts +flow project deploy --update +``` + +📖 **[Learn more about project deployment](./deployment/deploy-project-contracts.md)** + +## Configuration Management + +### Add Configuration Items + +Use `flow config add` to manage your project configuration: + +```bash +# Add an account +flow config add account --name my-account --address 0x123 --private-key abc123 + +# Add a contract +flow config add contract --name MyToken --filename ./cadence/contracts/MyToken.cdc + +# Add a deployment +flow config add deployment --network testnet --account my-account --contract MyToken +``` + +### Remove Configuration Items + +```bash +# Remove an account +flow config remove account my-account + +# Remove a contract +flow config remove contract MyToken + +# Remove a deployment +flow config remove deployment testnet my-account MyToken +``` + +📖 **[Learn more about configuration management](./flow.json/manage-configuration.md)** + +## Account Management + +### List Accounts + +```bash +# List all configured accounts with status +flow accounts list +``` + +### Create Accounts + +```bash +# Interactive account creation +flow accounts create + +# Create with specific network +flow accounts create --network testnet + +# Create with custom key +flow accounts create --key +``` + +### Fund Accounts + +```bash +# Interactive funding prompt +flow accounts fund + +# Fund by account name from flow.json +flow accounts fund testnet-account + +# Fund by address +flow accounts fund 0x8e94eaa81771313a +``` + +### Manage Account Keys + +```bash +# Generate new key pair +flow keys generate + +# Decode a key +flow keys decode + +# Derive public key from private key +flow keys derive +``` + +📖 **[Learn more about account management](./accounts/create-accounts.md)** + +## Contract Interactions + +### Execute Scripts + +```bash +# Run a script +flow scripts execute cadence/scripts/GetBalance.cdc + +# Run with arguments +flow scripts execute cadence/scripts/GetBalance.cdc --arg 0x123 + +# Run on specific network +flow scripts execute cadence/scripts/GetBalance.cdc --network testnet +``` + +### Send Transactions + +```bash +# Send a transaction +flow transactions send cadence/transactions/TransferTokens.cdc + +# Send with arguments +flow transactions send cadence/transactions/TransferTokens.cdc --arg 0x123 --arg 100 + +# Send with specific signer +flow transactions send cadence/transactions/TransferTokens.cdc --signer my-account +``` + +### Get System Transactions + +```bash +# Get system transaction from latest block +flow transactions get-system latest + +# Get specific system transaction by ID +flow transactions get-system latest 07a8...b433 + +# Get system transaction from specific block height +flow transactions get-system 12345 +``` + +### Profile Transaction Performance + +```bash +# Profile a mainnet transaction +flow transactions profile 07a8...b433 --network mainnet + +# Profile with custom output location +flow transactions profile 0xabc123 --network testnet --output my-profile.pb.gz + +# Analyze profile with pprof +go tool pprof -http=:8080 profile-07a8b433.pb.gz +``` + +📖 **[Learn more about scripts](./scripts/execute-scripts.md)** | **[Learn more about transactions](./transactions/send-transactions.md)** | **[Learn more about transaction profiling](./transactions/profile-transactions.md)** + +## Dependency Management + +### Install Dependencies + +```bash +# Install a contract dependency +flow dependencies install testnet://8a4dce54554b225d.NumberFormatter + +# Install from mainnet +flow dependencies install mainnet://f233dcee88fe0abe.FungibleToken + +# Install with specific account +flow dependencies install testnet://8a4dce54554b225d.NumberFormatter --account my-account +``` + +### Manage Dependencies + +```bash +# List installed dependencies +flow dependencies list + +# Discover available contracts +flow dependencies discover + +# Install a contract dependency +flow dependencies install testnet://8a4dce54554b225d.NumberFormatter +``` + +📖 **[Learn more about dependency management](./dependency-manager.md)** + +## Scheduled Transactions + +### Setup Manager Resource + +```bash +# Initialize Manager resource for scheduled transactions +flow schedule setup --network testnet --signer my-account +``` + +### List Scheduled Transactions + +```bash +# List all scheduled transactions for an account +flow schedule list my-account --network testnet +``` + +### Get Transaction Details + +```bash +# Get details for a specific scheduled transaction +flow schedule get 123 --network testnet +``` + +### Cancel Scheduled Transaction + +```bash +# Cancel a scheduled transaction and receive refund +flow schedule cancel 123 --network testnet --signer my-account +``` + +📖 **[Learn more about scheduled transactions](./scheduled-transactions.md)** + +## Development Workflow + +### Local Development + +1. **Start the emulator:** +```bash +flow emulator start +``` + +2. **Deploy contracts:** +```bash +flow project deploy +``` + +3. **Run tests:** +```bash +flow test +``` + +4. **Execute scripts:** +```bash +flow scripts execute cadence/scripts/GetBalance.cdc +``` + +5. **Send transactions:** +```bash +flow transactions send cadence/transactions/TransferTokens.cdc +``` + +### Testnet Deployment + +1. **Configure testnet account:** +```bash +flow config add account --name testnet-account --address 0x123 --private-key abc123 +``` + +2. **Deploy to testnet:** +```bash +flow project deploy --network=testnet +``` + +3. **Test on testnet:** +```bash +flow scripts execute cadence/scripts/GetBalance.cdc --network=testnet +``` + +## Import Schema + +Use simplified imports in your Cadence code: + +```cadence +// Instead of complex import paths +import FungibleToken from 0x9a0766d93b6608b7 + +// Use simple contract names +import "FungibleToken" +``` + +The CLI automatically resolves imports based on your `flow.json` configuration. + +## Best Practices + +### 1. Use Configuration Commands + +Instead of manually editing `flow.json`, use CLI commands: +```bash +# ✅ Good +flow config add account --name my-account --address 0x123 + +# ❌ Avoid +# Manually editing flow.json +``` + +### 2. Test Locally First + +Always test on emulator before deploying: +```bash +# 1. Start emulator +flow emulator start + +# 2. Deploy locally +flow project deploy + +# 3. Run tests +flow test + +# 4. Deploy to testnet +flow project deploy --network=testnet +``` + +### 3. Use Descriptive Names + +Choose clear names for accounts and contracts: +```bash +# ✅ Good +flow config add account --name testnet-deployer +flow generate contract MyNFT + +# ❌ Avoid +flow config add account --name acc1 +flow generate contract c1 +``` + +### 4. Secure Your Keys + +Use secure key management: +```bash +# Use file-based keys +flow config add account --name my-account --key-file ./keys/my-account.key + +# Use environment variables +FLOW_PRIVATE_KEY=abc123 flow project deploy +``` + +📖 **[Learn more about security best practices](./flow.json/security.md)** + +## Related Documentation + +- **[Configuration Management](./flow.json/manage-configuration.md)** - Learn how to manage your `flow.json` file +- **[Project Deployment](./deployment/deploy-project-contracts.md)** - Deploy contracts to different networks +- **[Account Management](./accounts/create-accounts.md)** - Create and manage Flow accounts +- **[Testing](./tests.md)** - Write and run tests for your contracts +- **[Security](./flow.json/security.md)** - Secure your private keys and configuration \ No newline at end of file diff --git a/docs/tools/flow-cli/data-collection.md b/docs/build/tools/flow-cli/data-collection.md similarity index 100% rename from docs/tools/flow-cli/data-collection.md rename to docs/build/tools/flow-cli/data-collection.md diff --git a/docs/tools/flow-cli/dependency-manager.md b/docs/build/tools/flow-cli/dependency-manager.md similarity index 85% rename from docs/tools/flow-cli/dependency-manager.md rename to docs/build/tools/flow-cli/dependency-manager.md index d1d4389eda..f9f3d00686 100644 --- a/docs/tools/flow-cli/dependency-manager.md +++ b/docs/build/tools/flow-cli/dependency-manager.md @@ -31,7 +31,7 @@ This specifies the remote source of the contract on the network that will be use ### Installing Core Contracts Using Simplified Syntax -For core contracts, you can use a simplified syntax that defaults to the Flow Mainnet: +For core contracts (and [DeFiActions](https://github.com/onflow/FlowActions/tree/main?tab=readme-ov-file#deployments)), you can use a simplified syntax that defaults to the Flow Mainnet: ```bash flow dependencies install FlowToken @@ -79,14 +79,14 @@ After installing, your `flow.json` might include an entry like: ```json { - "dependencies": { - "FlowToken": { - "source": "testnet://7e60df042a9c0868.FlowToken", - "aliases": { - "emulator": "0ae53cb6e3f42a79" - } - } + "dependencies": { + "FlowToken": { + "source": "testnet://7e60df042a9c0868.FlowToken", + "aliases": { + "emulator": "0ae53cb6e3f42a79" + } } + } } ``` @@ -99,7 +99,7 @@ After installing, your `flow.json` might include an entry like: ## `discover` -The `discover` command helps you interactively find and install core contracts for your project. Core contracts are standard smart contracts maintained by the Flow Foundation and are commonly used across the Flow ecosystem (learn more about core contracts [here](../../build/core-contracts/index.md)). +The `discover` command helps you interactively find and install core contracts for your project. Core contracts are standard smart contracts maintained by the Flow Foundation and are commonly used across the Flow ecosystem (learn more about core contracts [here](../../cadence/core-contracts/index.md)). To use the `discover` command, run: @@ -127,4 +127,16 @@ Use arrow keys to navigate, space to select, enter to confirm or skip, q to quit [ ] Crypto ``` -After selecting the contracts, press `enter` to confirm. The selected contracts will be added to your `flow.json` file and will be accessible in your project. \ No newline at end of file +After selecting the contracts, press `enter` to confirm. The selected contracts will be added to your `flow.json` file and will be accessible in your project. + +## `list` + +The `list` command displays all the dependencies currently installed in your project. This is useful for reviewing what contracts your project depends on and their sources. + +To list your installed dependencies, run: + +```bash +flow dependencies list +``` + +This command will show you all the dependencies from your `flow.json` file along with their source information, helping you keep track of what external contracts your project is using. diff --git a/docs/tools/flow-cli/deployment/_category_.json b/docs/build/tools/flow-cli/deployment/_category_.json similarity index 100% rename from docs/tools/flow-cli/deployment/_category_.json rename to docs/build/tools/flow-cli/deployment/_category_.json diff --git a/docs/build/tools/flow-cli/deployment/deploy-project-contracts.md b/docs/build/tools/flow-cli/deployment/deploy-project-contracts.md new file mode 100644 index 0000000000..c91cbc182d --- /dev/null +++ b/docs/build/tools/flow-cli/deployment/deploy-project-contracts.md @@ -0,0 +1,402 @@ +--- +title: Deploy a Project +description: How to deploy Flow project contracts with the CLI +sidebar_position: 3 +--- + +```shell +flow project deploy +``` + +This command automatically deploys your project's contracts based on the configuration defined in your `flow.json` file. + +:::info + +Use Flow CLI commands to configure your project rather than manually edit `flow.json`. + +Before you use this command, read about how to +[configure project contracts and deployment targets] with CLI commands. + +::: + +## Example usage + +```shell +> flow project deploy --network=testnet + +Deploying 2 contracts for accounts: my-testnet-account + +NonFungibleToken -> 0x8910590293346ec4 +KittyItems -> 0x8910590293346ec4 + +✨ All contracts deployed successfully +``` + +:::info + +The `flow.json` configuration shown below is created automatically when you use CLI commands. You should use `flow config add contract` and `flow config add deployment` to configure your project rather than manually edit the file. See [Add Project Contracts] for details. + +::: + +Your `flow.json` file might look something like this: + +```json +{ + ... + "contracts": { + "NonFungibleToken": "./cadence/contracts/NonFungibleToken.cdc", + "KittyItems": "./cadence/contracts/KittyItems.cdc" + }, + "deployments": { + "testnet": { + "my-testnet-account": ["KittyItems", "NonFungibleToken"] + } + }, + ... +} +``` + +Here's a sketch of the contract source files: + +```cadence NonFungibleToken.cdc +access(all) contract NonFungibleToken { + // ... +} +``` + +```cadence KittyItems.cdc +import "NonFungibleToken" + +access(all) contract KittyItems { + // ... +} +``` + +## Initialization arguments + +To deploy contracts that take initialization arguments, you must add those arguments to the deployment configuration. + +:::info + +For basic deployments, use `flow config add deployment` to configure your contracts. Initialization arguments are an advanced feature that may require you to manually edit `flow.json` after the basic deployment is configured with CLI commands. + +::: + +You can specify each deployment as an object that contains +`name` and `args` keys that specify arguments to be +used during the deployment. Example: + +```json +{ + "deployments": { + "testnet": { + "my-testnet-account": [ + "NonFungibleToken", + { + "name": "Foo", + "args": [ + { "type": "String", "value": "Hello World" }, + { "type": "UInt32", "value": "10" } + ] + } + ] + } + } +} +``` + +:::danger + +⚠️ **Never** put raw private keys in `flow.json`. Always use `.pkey` files for key storage. Before you proceed, we recommend that you read the [Flow CLI security guidelines] +to learn about the best practices for private key storage. + +## Dependency resolution + +The `deploy` command attempts to resolve the import statements in all contracts being deployed. + +After the dependencies are found, the CLI will deploy the contracts in a deterministic order such that no contract is deployed until all of its dependencies are deployed. The command will return an error if no such ordering exists due to one or more cyclic dependencies. + +In the example above, `NonFungibleToken` will always be deployed before `KittyItems` since `KittyItems` imports `NonFungibleToken`. + +## Address replacement + +After it resolves all dependencies, the `deploy` command rewrites each contract so that its dependencies are imported from their _target addresses_ rather than their source file location. + +The rewritten versions are then deployed to their respective targets, which leaves the original contract files unchanged. + +### Contracts that import from other contracts + +In the example above, the `KittyItems` contract would be rewritten like this: + +```cadence KittyItems.cdc +import NonFungibleToken from 0xf8d6e0586b0a20c7 + +access(all) contract KittyItems { + // ... +} +``` + +### Contracts that import from dependencies + +When your contracts import from the `dependencies` section, the deploy command uses the network-specific aliases defined in those dependencies. + +**Example `flow.json` with dependencies:** + +```json +{ + "contracts": { + "ExampleConnectors": { + "source": "cadence/contracts/ExampleConnectors.cdc", + "aliases": { + "testing": "0000000000000007" + } + } + }, + "dependencies": { + "FlowToken": { + "source": "mainnet://1654653399040a61.FlowToken", + "hash": "cefb25fd19d9fc80ce02896267eb6157a6b0df7b1935caa8641421fe34c0e67a", + "aliases": { + "emulator": "0ae53cb6e3f42a79", + "mainnet": "1654653399040a61", + "testnet": "7e60df042a9c0868" + } + }, + "FungibleToken": { + "source": "mainnet://f233dcee88fe0abe.FungibleToken", + "hash": "23c1159cf99b2b039b6b868d782d57ae39b8d784045d81597f100a4782f0285b", + "aliases": { + "emulator": "ee82856bf20e2aa6", + "mainnet": "f233dcee88fe0abe", + "testnet": "9a0766d93b6608b7" + } + } + }, + "deployments": { + "testnet": { + "testnet-account": ["ExampleConnectors"] + } + } +} +``` + +**Original contract source:** + +```cadence ExampleConnectors.cdc +import "FungibleToken" +import "FlowToken" + +access(all) contract ExampleConnectors { + // ... +} +``` + +**Rewritten for testnet deployment:** + +```cadence ExampleConnectors.cdc +import FungibleToken from 0x9a0766d93b6608b7 +import FlowToken from 0x7e60df042a9c0868 + +access(all) contract ExampleConnectors { + // ... +} +``` + +**Rewritten for mainnet deployment:** + +```cadence ExampleConnectors.cdc +import FungibleToken from 0xf233dcee88fe0abe +import FlowToken from 0x1654653399040a61 + +access(all) contract ExampleConnectors { + // ... +} +``` + +The deploy command automatically uses the addresses from the `dependencies` section's aliases for the target network. Notice how the addresses change based on the network—testnet uses `0x9a0766d93b6608b7` for `FungibleToken`, while mainnet uses `0xf233dcee88fe0abe`. Contracts in the `dependencies` section are not deployed—they're assumed to already exist on the network at the addresses specified in their aliases. + +## Merge multiple configuration files + +You can use the `-f` flag multiple times to merge several configuration files. + +If there is an overlap in any of the fields in the configuration between two or more configuration files, the value of the overlapped field in the configuration that results will come from the configuration file that is on the further right order in the list of configuration files specified in the `-f` flag. + +:::danger + +**Never** put raw private keys in `flow.json`. Always use `.pkey` files for key storage. + +::: + +:::info + +Use `flow config add account` to create accounts in your main `flow.json` file. The merging feature is useful to separate sensitive account information into a separate file that you can exclude from version control. + +::: + +**Example usage:** + +```bash +flow project deploy -f flow.json -f private.json +``` + +**Example configuration files:** + +```json flow.json +{ + "accounts": { + "admin-account": { + "address": "f8d6e0586b0a20c7", + "key": { + "type": "file", + "location": "admin-account.pkey" + } + }, + "test-account": { + "address": "f8d6e0586b0a20c8", + "key": { + "type": "file", + "location": "test-account.pkey" + } + } + } +} +``` + +```json private.json +{ + "accounts": { + "admin-account": { + "address": "f1d6e0586b0a20c7", + "key": { + "type": "file", + "location": "admin-account-private.pkey" + } + } + } +} +``` + +When you use multiple configuration files with overlapping fields, the rightmost file takes precedence. +In this example, the merged configuration that results will be: + +```json +{ + "accounts": { + "admin-account": { + "address": "f1d6e0586b0a20c7", + "key": { + "type": "file", + "location": "admin-account-private.pkey" + } + }, + "test-account": { + "address": "f8d6e0586b0a20c8", + "key": { + "type": "file", + "location": "test-account.pkey" + } + } + } +} +``` + +**Security best practice:** Ensure `.pkey` files are added to `.gitignore` to prevent accidentally committing private keys to version control. + +## Flags + +### Allow updates + +- Flag: `--update` +- Valid inputs: `true`, `false` +- Default: `false` + +Indicate whether to overwrite and upgrade current contracts. The system will only overwrite contracts that are different from current contracts. + +### Show update diff + +- Flag: `--show-diff` +- Valid inputs: `true`, `false` +- Default: `false` + +Shows a diff to approve before an update between deployed contract and new contract updates. + +### Host + +- Flag: `--host` +- Valid inputs: an IP address or hostname. +- Default: `127.0.0.1:3569` (Flow Emulator) + +Specify the hostname of the Access API that will be used to execute the command. This flag overrides any host defined by the `--network` flag. + +### Network key + +- Flag: `--network-key` +- Valid inputs: A valid network public key of the host in hex string format + +Specify the network public key of the Access API that will be used to create a secure GRPC client when executing the command. + +### Network + +- Flag: `--network` +- Short Flag: `-n` +- Valid inputs: the name of a network defined in the configuration (`flow.json`) +- Default: `emulator` + +Specify which network you want the command to use for execution. + +### Filter + +- Flag: `--filter` +- Short Flag: `-x` +- Valid inputs: a case-sensitive name of the result property. + +Specify any property name from the result you want to return as the only value. + +### Output + +- Flag: `--output` +- Short Flag: `-o` +- Valid inputs: `json`, `inline` + +Specify the format of the command results. + +### Save + +- Flag: `--save` +- Short Flag: `-s` +- Valid inputs: a path in the current filesystem. + +Specify the filename where you want the result to be saved + +### Log + +- Flag: `--log` +- Short Flag: `-l` +- Valid inputs: `none`, `error`, `debug` +- Default: `info` + +Specify the log level. Control how much output you want to see during command execution. + +### Configuration + +- Flag: `--config-path` +- Short Flag: `-f` +- Valid inputs: a path in the current filesystem. +- Default: `flow.json` + +Specify the path to the `flow.json` configuration file. +You can use the `-f` flag multiple times to merge +several configuration files. + +### Version Check + +- Flag: `--skip-version-check` +- Default: `false` + +Skip version check during start up to speed up process for slow connections. + + + +[configure project contracts and deployment targets]: ./project-contracts.md +[Add Project Contracts]: ./project-contracts.md +[Flow CLI security guidelines]: ../flow.json/security.md \ No newline at end of file diff --git a/docs/build/tools/flow-cli/deployment/project-contracts.md b/docs/build/tools/flow-cli/deployment/project-contracts.md new file mode 100644 index 0000000000..0940ca71d8 --- /dev/null +++ b/docs/build/tools/flow-cli/deployment/project-contracts.md @@ -0,0 +1,129 @@ +--- +title: Add Project Contracts +description: How to define and configure Cadence contracts for Flow projects using Flow CLI commands +sidebar_position: 2 +--- + +## Generate a Contract + +Create a new contract file with the Flow CLI: + +```bash +flow generate contract Foo +``` + +This command creates `cadence/contracts/Foo.cdc` with a basic contract template and automatically adds it to your `flow.json` configuration. + +## Add a contract to configuration + +If you have a contract file, add it to your project configuration with the CLI: + +```bash +flow config add contract +``` + +Follow the interactive prompts: + +1. **Contract name**: Enter the contract name (for exxample, `Foo`) +2. **Contract filename**: Enter the path to your contract file (for example, `./cadence/contracts/Foo.cdc`) +3. **Add aliases**: Optionally add network aliases for dependencies + +You can also use flags to specify all details at once: + +```bash +flow config add contract \ + --name Foo \ + --filename ./cadence/contracts/Foo.cdc +``` + +**What gets added to `flow.json`:** + +```json +{ + "contracts": { + "Foo": "./cadence/contracts/Foo.cdc" + } +} +``` + +## Configure contract deployment targets + +After a contract is added to your configuration, configure deployment targets with the CLI: + +```bash +flow config add deployment +``` + +Follow the interactive prompts: + +1. **Network**: Select the network (for example, `testnet`, `mainnet`, `emulator`) +2. **Account**: Select the account to deploy to (for example, `my-testnet-account`) +3. **Contract**: Select the contract to deploy (for example, `Foo`) +4. **Deploy more contracts**: Choose `yes` to add additional contracts to the same deployment + +You can also use flags to specify all details: + +```bash +flow config add deployment \ + --network testnet \ + --account my-testnet-account \ + --contract Foo +``` + +**What gets added to `flow.json`:** + +```json +{ + "deployments": { + "testnet": { + "my-testnet-account": ["Foo"] + } + } +} +``` + +## Add multiple contracts to a deployment + +To deploy multiple contracts to the same account, run the deployment configuration command multiple times or use the interactive prompt to add more contracts: + +```bash +flow config add deployment --network testnet --account my-testnet-account --contract Bar +``` + +This adds `Bar` to the existing deployment: + +```json +{ + "deployments": { + "testnet": { + "my-testnet-account": ["Foo", "Bar"] + } + } +} +``` + +## Remove contracts and deployments + +Remove contracts or deployments using the CLI: + +```bash +# Remove a contract from configuration +flow config remove contract Foo + +# Remove a contract from a specific deployment +flow config remove deployment testnet my-testnet-account Foo +``` + +## Best Practices + +- **Use CLI commands**: Always use `flow config add` and `flow config remove` rather than manually edit `flow.json` +- **Generate contracts**: Use `flow generate contract` to create new contracts with proper structure +- **Verify configuration**: Use `flow accounts list` and check your `flow.json` to verify your configuration +- **Network-specific deployments**: Configure separate deployments for each network (emulator, testnet, mainnet) + +For more information, see [Manage Configuration] and [Production Deployment]. + + + +[Manage Configuration]: ../flow.json/manage-configuration.md +[Production Deployment]: ../../../../blockchain-development-tutorials/cadence/getting-started/production-deployment.md \ No newline at end of file diff --git a/docs/tools/flow-cli/flix.md b/docs/build/tools/flow-cli/flix.md similarity index 66% rename from docs/tools/flow-cli/flix.md rename to docs/build/tools/flow-cli/flix.md index baf9b35916..217f834716 100644 --- a/docs/tools/flow-cli/flix.md +++ b/docs/build/tools/flow-cli/flix.md @@ -5,7 +5,7 @@ description: Flow Interaction Templates (FLIX) via the CLI sidebar_position: 15 --- -FLIX helps developers reuse existing Cadence transactions and scripts to easily integrate with existing Cadence smart contracts. Get more information about [Flow Interaction Templates](../../build/advanced-concepts/flix.md) +FLIX helps developers reuse existing Cadence transactions and scripts to easily integrate with existing Cadence smart contracts. Get more information about [Flow Interaction Templates](../../cadence/advanced-concepts/flix.md) ## Introduction @@ -21,7 +21,7 @@ Usage: Available Commands: execute execute FLIX template with a given id, name, local filename, or url generate generate FLIX json template given local Cadence filename - package package file for FLIX template fcl-js is default + package package file for FLIX template fcl-js is default ``` @@ -36,11 +36,10 @@ flow flix execute [ ...] [flags] :::warning -A FLIX template might only support testnet and/or mainnet. Generally, emulator is not supported. This can be the case if the FLIX template relies on contract dependencies. +A FLIX template might only support testnet and/or mainnet. Generally, emulator is not supported. This can be the case if the FLIX template relies on contract dependencies. ::: - Queries can be a FLIX `id`, `name`, `url` or `path` to a local FLIX file. ### Execute Usage @@ -60,7 +59,7 @@ flow flix execute bd10ab0bf472e6b58ecc0398e9b3d1bd58a4205f14a7099c52c0640d958929 flow flix execute ./multiply.template.json 2 3 --network testnet ``` -The Flow CLI provides a `flix` command to `package` up generated plain and simple JavaScript. This JavaScript uses FCL (Flow Client Library) to call the cadence the Flow Interaction Templates (FLIX) is based on. +The Flow CLI provides a `flix` command to `package` up generated plain and simple JavaScript. This JavaScript uses FCL (Flow Client Library) to call the cadence the Flow Interaction Templates (FLIX) is based on. :::info @@ -68,16 +67,16 @@ Currently, `flix package` command only supports generating FCL (Flow Client Libr ::: - ```shell flow flix package [flags] ``` ### Generate -Generate FLIX json file. This command will take in a Cadence file and produce a FLIX json file. There are two ways to provide metadata to populate the FLIX json structure. - - Use `--pre-fill` flag to pass in a pre populated FLIX json structure - - Use `--exclude-networks` flag to specify excluded networks when generating a FLIX templates. Example, `--exclude-networks testnet,mainnet` +Generate FLIX json file. This command will take in a Cadence file and produce a FLIX json file. There are two ways to provide metadata to populate the FLIX json structure. + +- Use `--pre-fill` flag to pass in a pre populated FLIX json structure +- Use `--exclude-networks` flag to specify excluded networks when generating a FLIX templates. Example, `--exclude-networks testnet,mainnet` :::warning @@ -85,15 +84,15 @@ When generating a FLIX template, make sure all contract dependencies have been d ::: - ### Generate Usage ```shell -# Generate FLIX json file using cadence transaction or script, this example is not using a prefilled json file so will not have associated message metadata +# Generate FLIX json file using cadence transaction or script, this example is not using a prefilled json file so will not have associated message metadata flow flix generate cadence/transactions/update-helloworld.cdc --save cadence/templates/update-helloworld.template.json ``` Example of Cadence simple, no metadata associated + ```cadence import "HelloWorld" @@ -102,11 +101,12 @@ access(all) fun main(): String { } ``` - ### Cadence Doc Pragma: -It's recommended to use pragma to set the metadata for the script or transaction. More information on [Cadence Doc Pragma FLIP](https://github.com/onflow/flips/blob/main/application/20230406-interaction-template-cadence-doc.md) + +It's recommended to use pragma to set the metadata for the script or transaction. More information on [Cadence Doc Pragma FLIP](https://github.com/onflow/flips/blob/main/application/20230406-interaction-template-cadence-doc.md) A pragma is short for "pragmatic information", it's special instructions to convey information to a processor in this case the utility that generates FLIX. + ```cadence import "HelloWorld" @@ -134,47 +134,47 @@ transaction(greeting: String) { Cadence v0.42.7 supports additional Cadence pragma functionality that FlIX utility can use to generate FLIX. It will support parameters "title" and "description". ::: - The resulting json metadata is extracted from Cadence Doc Pragma + ```json { - "f_type": "InteractionTemplate", - "f_version": "1.1.0", - "id": "", - "data": { - "type": "transaction", - "interface": "", - "messages": [ - { - "key": "title", - "i18n": [ - { - "tag": "en-US", - "translation": "Update Greeting" - } - ] - }, - { - "key": "description", - "i18n": [ - { - "tag": "en-US", - "translation": "Update the greeting on the HelloWorld contract" - } - ] - } - ], - "cadence": {}, - "dependencies": [], - "parameters": [ - { - "label": "greeting", - "index": 0, - "type": "String", - "messages": [] - } + "f_type": "InteractionTemplate", + "f_version": "1.1.0", + "id": "", + "data": { + "type": "transaction", + "interface": "", + "messages": [ + { + "key": "title", + "i18n": [ + { + "tag": "en-US", + "translation": "Update Greeting" + } ] - } + }, + { + "key": "description", + "i18n": [ + { + "tag": "en-US", + "translation": "Update the greeting on the HelloWorld contract" + } + ] + } + ], + "cadence": {}, + "dependencies": [], + "parameters": [ + { + "label": "greeting", + "index": 0, + "type": "String", + "messages": [] + } + ] + } } ``` @@ -184,7 +184,7 @@ Example of using a prefilled FLIX json file. No need to use Cadence pragma when flow flix generate cadence/scripts/read-helloworld.cdc --pre-fill cadence/templates/read-helloworld.prefill.json --save cadence/templates/read-helloworld.template.json ``` -Using a pre-filled FLIX template, the cadence can be simple but no metadata accompanies it. +Using a pre-filled FLIX template, the cadence can be simple but no metadata accompanies it. ```cadence import "HelloWorld" @@ -194,111 +194,109 @@ access(all) fun main(): String { ``` Example of json prefill file with message metadata: + ```json { - "f_type": "InteractionTemplate", - "f_version": "1.1.0", - "id": "", - "data": { - "type": "script", - "interface": "", - "messages": [ - { - "key": "title", - "i18n": [ - { - "tag": "en-US", - "translation": "Get Greeting" - } - ] - }, - { - "key": "description", - "i18n": [ - { - "tag": "en-US", - "translation": "Call HelloWorld contract to get greeting" - } - ] - } + "f_type": "InteractionTemplate", + "f_version": "1.1.0", + "id": "", + "data": { + "type": "script", + "interface": "", + "messages": [ + { + "key": "title", + "i18n": [ + { + "tag": "en-US", + "translation": "Get Greeting" + } + ] + }, + { + "key": "description", + "i18n": [ + { + "tag": "en-US", + "translation": "Call HelloWorld contract to get greeting" + } ] - } + } + ] + } } - ``` The resulting FLIX json file after generation: ```json { - "f_type": "InteractionTemplate", - "f_version": "1.1.0", - "id": "fd9abd34f51741401473eb1cf676b105fed28b50b86220a1619e50d4f80b0be1", - "data": { - "type": "script", - "interface": "", - "messages": [ - { - "key": "title", - "i18n": [ - { - "tag": "en-US", - "translation": "Get Greeting" - } - ] - }, - { - "key": "description", - "i18n": [ - { - "tag": "en-US", - "translation": "Call HelloWorld contract to get greeting" - } - ] - } - ], - "cadence": { - "body": "import \"HelloWorld\"\naccess(all) fun main(): String {\n return HelloWorld.greeting\n}\n", - "network_pins": [ - { - "network": "testnet", - "pin_self": "41c4c25562d467c534dc92baba92e0c9ab207628731ee4eb4e883425abda692c" + "f_type": "InteractionTemplate", + "f_version": "1.1.0", + "id": "fd9abd34f51741401473eb1cf676b105fed28b50b86220a1619e50d4f80b0be1", + "data": { + "type": "script", + "interface": "", + "messages": [ + { + "key": "title", + "i18n": [ + { + "tag": "en-US", + "translation": "Get Greeting" + } + ] + }, + { + "key": "description", + "i18n": [ + { + "tag": "en-US", + "translation": "Call HelloWorld contract to get greeting" + } + ] + } + ], + "cadence": { + "body": "import \"HelloWorld\"\naccess(all) fun main(): String {\n return HelloWorld.greeting\n}\n", + "network_pins": [ + { + "network": "testnet", + "pin_self": "41c4c25562d467c534dc92baba92e0c9ab207628731ee4eb4e883425abda692c" + } + ] + }, + "dependencies": [ + { + "contracts": [ + { + "contract": "HelloWorld", + "networks": [ + { + "network": "testnet", + "address": "0xe15193734357cf5c", + "dependency_pin_block_height": 137864533, + "dependency_pin": { + "pin": "aad46badcab3caaeb4f0435625f43e15bb4c15b1d55c74a89e6f04850c745858", + "pin_self": "a06b3cd29330a3c22df3ac2383653e89c249c5e773fd4bbee73c45ea10294b97", + "pin_contract_name": "HelloWorld", + "pin_contract_address": "0xe15193734357cf5c", + "imports": [] } + } ] - }, - "dependencies": [ - { - "contracts": [ - { - "contract": "HelloWorld", - "networks": [ - { - "network": "testnet", - "address": "0xe15193734357cf5c", - "dependency_pin_block_height": 137864533, - "dependency_pin": { - "pin": "aad46badcab3caaeb4f0435625f43e15bb4c15b1d55c74a89e6f04850c745858", - "pin_self": "a06b3cd29330a3c22df3ac2383653e89c249c5e773fd4bbee73c45ea10294b97", - "pin_contract_name": "HelloWorld", - "pin_contract_address": "0xe15193734357cf5c", - "imports": [] - } - } - ] - } - ] - } - ], - "parameters": null - } + } + ] + } + ], + "parameters": null + } } - ``` - ### Package -Queries can be a FLIX `url` or `path` to a local FLIX file. This command leverages [FCL](../clients/fcl-js/) which will execute FLIX cadence code. Package files can be generated in JavaScript or TypeScript. +Queries can be a FLIX `url` or `path` to a local FLIX file. This command leverages [FCL](../clients/fcl-js/) which will execute FLIX cadence code. Package files can be generated in JavaScript or TypeScript. :::warning @@ -315,70 +313,66 @@ flow flix package transfer-flow --save ./package/transfer-flow.js ```shell # Generate package code for a FLIX script using id, since there is no saving file, the result will display in terminal -flow flix package bd10ab0bf472e6b58ecc0398e9b3d1bd58a4205f14a7099c52c0640d9589295f +flow flix package bd10ab0bf472e6b58ecc0398e9b3d1bd58a4205f14a7099c52c0640d9589295f ``` ```shell -# Generate package code using local template file to save in a local file +# Generate package code using local template file to save in a local file flow flix package ./multiply.template.json --save ./multiply.js ``` ```shell -# Generate package code using local template file to save in a local typescript file -flow flix package ./multiply.template.json --lang ts --save ./multiply.ts +# Generate package code using local template file to save in a local typescript file +flow flix package ./multiply.template.json --lang ts --save ./multiply.ts ``` - ### Example Package Output + ```shell flow flix package https://flix.flow.com/v1/templates\?name\=transfer-flow ``` ```javascript - /** This binding file was auto generated based on FLIX template v1.0.0. Changes to this file might get overwritten. Note fcl version 1.3.0 or higher is required to use templates. **/ -import * as fcl from "@onflow/fcl" -const flixTemplate = "https://flix.flow.com/v1/templates?name=transfer-flow" +import * as fcl from '@onflow/fcl'; +const flixTemplate = 'https://flix.flow.com/v1/templates?name=transfer-flow'; /** -* Transfer tokens from one account to another -* @param {Object} Parameters - parameters for the cadence -* @param {string} Parameters.amount - The amount of FLOW tokens to send: UFix64 -* @param {string} Parameters.to - The Flow account the tokens will go to: Address -* @returns {Promise} - returns a promise which resolves to the transaction id -*/ -export async function transferTokens({amount, to}) { + * Transfer tokens from one account to another + * @param {Object} Parameters - parameters for the cadence + * @param {string} Parameters.amount - The amount of FLOW tokens to send: UFix64 + * @param {string} Parameters.to - The Flow account the tokens will go to: Address + * @returns {Promise} - returns a promise which resolves to the transaction id + */ +export async function transferTokens({ amount, to }) { const transactionId = await fcl.mutate({ template: flixTemplate, - args: (arg, t) => [arg(amount, t.UFix64), arg(to, t.Address)] + args: (arg, t) => [arg(amount, t.UFix64), arg(to, t.Address)], }); - return transactionId + return transactionId; } - - ``` ```shell -# Generate TypeScript version of package file +# Generate TypeScript version of package file flow flix package https://flix.flow.com/v1/templates?name=transfer-flow --lang ts ``` ```typescript - /** This binding file was auto generated based on FLIX template v1.1.0. Changes to this file might get overwritten. Note fcl version 1.9.0 or higher is required to use templates. **/ -import * as fcl from "@onflow/fcl" -const flixTemplate = "https://flix.flow.com/v1/templates?name=transfer-flow" +import * as fcl from '@onflow/fcl'; +const flixTemplate = 'https://flix.flow.com/v1/templates?name=transfer-flow'; interface TransferTokensParams { amount: string; // The amount of FLOW tokens to send @@ -386,21 +380,24 @@ interface TransferTokensParams { } /** -* transferTokens: Transfer tokens from one account to another -* @param string amount - The amount of FLOW tokens to send -* @param string to - The Flow account the tokens will go to -* @returns {Promise} - Returns a promise that resolves to the transaction ID -*/ -export async function transferTokens({amount, to}: TransferTokensParams): Promise { + * transferTokens: Transfer tokens from one account to another + * @param string amount - The amount of FLOW tokens to send + * @param string to - The Flow account the tokens will go to + * @returns {Promise} - Returns a promise that resolves to the transaction ID + */ +export async function transferTokens({ + amount, + to, +}: TransferTokensParams): Promise { const transactionId = await fcl.mutate({ template: flixTemplate, - args: (arg, t) => [arg(amount, t.UFix64), arg(to, t.Address)] + args: (arg, t) => [arg(amount, t.UFix64), arg(to, t.Address)], }); - return transactionId + return transactionId; } - ``` + :::warning Notice that fcl v1.9.0 is needed to use FLIX v1.1 templates @@ -416,8 +413,9 @@ For a list of all templates, check out the [FLIX template repository](https://gi To generate a FLIX, see the [FLIX CLI readme](https://github.com/onflow/flow-interaction-template-tools/tree/master/cli). ## Arguments + - Name: `argument` -- Valid input: valid [FLIX](https://github.com/onflow/flips/blob/main/application/20220503-interaction-templates.md) +- Valid input: valid [FLIX](https://github.com/onflow/flips/blob/main/application/20220503-interaction-templates.md) Input argument value matching corresponding types in the source code and passed in the same order. You can pass a `nil` value to optional arguments by executing the flow FLIX execute script like this: `flow flix execute template.json nil`. @@ -431,7 +429,7 @@ You can pass a `nil` value to optional arguments by executing the flow FLIX exec - Example: `flow flix execute template.script.json '[{"type": "String", "value": "Hello World"}]'` Arguments passed to the Cadence script in the Cadence JSON format. -Cadence JSON format contains `type` and `value` keys and is +Cadence JSON format contains `type` and `value` keys and is [documented here](https://cadencelang.dev/docs/1.0/json-cadence-spec). ## Pre Fill @@ -439,7 +437,6 @@ Cadence JSON format contains `type` and `value` keys and is - Flag: `--pre-fill` - Valid inputs: a json file in the FLIX json structure [FLIX json format](https://github.com/onflow/flips/blob/main/application/20220503-interaction-templates.md) - ## Block Height - Flag: `--block-height` @@ -478,13 +475,13 @@ Specify the name of the account that will be used as payer in the transaction. Specify the name of the account(s) that will be used as authorizer(s) in the transaction. If you want to provide multiple authorizers separate them using commas (e.g. `alice,bob`) -### Gas Limit +### Compute Limit -- Flag: `--gas-limit` +- Flag: `--compute-limit` - Valid inputs: an integer greater than zero. - Default: `1000` -Specify the gas limit for this transaction. +Specify the compute unit (gas) limit for this transaction. ### Host diff --git a/docs/tools/flow-cli/flow.json/_category_.json b/docs/build/tools/flow-cli/flow.json/_category_.json similarity index 100% rename from docs/tools/flow-cli/flow.json/_category_.json rename to docs/build/tools/flow-cli/flow.json/_category_.json diff --git a/docs/build/tools/flow-cli/flow.json/configuration.md b/docs/build/tools/flow-cli/flow.json/configuration.md new file mode 100644 index 0000000000..0ab128714b --- /dev/null +++ b/docs/build/tools/flow-cli/flow.json/configuration.md @@ -0,0 +1,328 @@ +--- +title: Configuration +description: Understanding and configuring your Flow project with flow.json +sidebar_position: 2 +--- + +The `flow.json` file is the central configuration file for your Flow project. It tells the Flow CLI how to interact with networks, manage accounts, deploy contracts, and organize your project structure. + +## Quick Start + +When you run `flow init`, a basic `flow.json` file is created for you: + +```json +{ + "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": "ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee" + } + }, + "deployments": {}, + "contracts": {} +} +``` + +This gives you everything you need to get started with local development. As your project grows, you'll add more configuration to support different networks and deployment targets. + +## Configuration Sections + +### Networks + +The `networks` section defines which Flow networks your project can connect to. + +```json +"networks": { + "emulator": "127.0.0.1:3569", + "mainnet": "access.mainnet.nodes.onflow.org:9000", + "testnet": "access.devnet.nodes.onflow.org:9000" +} +``` + +**Common Networks:** + +- `emulator`: Your local development environment +- `testnet`: Flow's test network for development and testing +- `mainnet`: Flow's production network + +**Secure Connections:** +For enhanced security, you can specify network keys: + +```json +"networks": { + "testnetSecure": { + "host": "access-001.devnet30.nodes.onflow.org:9001", + "key": "ba69f7d2e82b9edf25b103c195cd371cf0cc047ef8884a9bbe331e62982d46daeebf836f7445a2ac16741013b192959d8ad26998aff12f2adc67a99e1eb2988d" + } +} +``` + +**Fork Networks:** +Fork networks allow you to test against a local emulator that mirrors mainnet or testnet state. When you run `flow emulator --fork mainnet`, the CLI automatically creates a `mainnet-fork` network configuration that inherits contract aliases from the parent network: + +```json +"networks": { + "mainnet-fork": { + "host": "127.0.0.1:3569", + "fork": "mainnet" + } +} +``` + +The `fork` property tells the CLI to inherit all contract aliases from the specified network (e.g., `mainnet`), so you don't need to manually duplicate aliases for forked networks. + +Learn more: [Fork Testing Overview](../fork-testing.md) + +### Accounts + +The `accounts` section defines the accounts you can use for transactions and deployments. + +#### Simple Account Format + +```json +"accounts": { + "my-account": { + "address": "f8d6e0586b0a20c7", + "key": "ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee" + } +} +``` + +#### Advanced Account Format + +For more control over key management: + +```json +"accounts": { + "my-account": { + "address": "f8d6e0586b0a20c7", + "key": { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "privateKey": "ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee" + } + } +} +``` + +**Key Types:** + +- `hex`: Standard hex-encoded private key +- `file`: Read key from a separate file +- `bip44`: Derive from mnemonic phrase +- `google-kms`: Use Google Cloud KMS + +**File-Based Keys:** +For better security, you can store private keys in separate files: + +```json +"accounts": { + "admin-account": { + "address": "f8d6e0586b0a20c7", + "key": { + "type": "file", + "location": "./keys/admin.key" + } + } +} +``` + +The key file should contain only the hex-encoded private key (e.g., `ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee`). + +**Special Address Values:** + +- `"service"`: Use the default service account (emulator only) + +### Contracts + +The `contracts` section maps contract names to their source files. + +#### Simple Contract Format + +```json +"contracts": { + "MyContract": "./cadence/contracts/MyContract.cdc", + "AnotherContract": "./cadence/contracts/AnotherContract.cdc" +} +``` + +#### Advanced Contract Format with Aliases + +Use aliases when contracts are already deployed on specific networks: + +```json +"contracts": { + "FungibleToken": { + "source": "./cadence/contracts/FungibleToken.cdc", + "aliases": { + "testnet": "9a0766d93b6608b7", + "mainnet": "f233dcee88fe0abe" + } + } +} +``` + +**When to Use Aliases:** + +- For core contracts already deployed on mainnet/testnet +- To avoid redeploying dependencies +- To use the official versions of common contracts + +#### Cadence Import Aliasing + +When deploying the same contract to multiple addresses with different names, use the `canonical` field to reference the original contract. This allows you to import multiple instances of the same contract with different identifiers. + +```json +"contracts": { + "FUSD": { + "source": "./contracts/FUSD.cdc", + "aliases": { + "testnet": "0x9a0766d93b6608b7" + } + }, + "FUSD1": { + "source": "./contracts/FUSD.cdc", + "aliases": { + "testnet": "0xe223d8a629e49c68" + }, + "canonical": "FUSD" + } +} +``` + +Flow CLI automatically transforms imports for aliased contracts: + +```cadence +import "FUSD" +import "FUSD1" +``` + +Becomes: + +```cadence +import FUSD from 0x9a0766d93b6608b7 +import FUSD as FUSD1 from 0xe223d8a629e49c68 +``` + +### Deployments + +The `deployments` section defines which contracts get deployed to which accounts on which networks. + +```json +"deployments": { + "emulator": { + "emulator-account": ["MyContract", "AnotherContract"] + }, + "testnet": { + "my-testnet-account": ["MyContract"] + } +} +``` + +**Format:** `"NETWORK": { "ACCOUNT": ["CONTRACT1", "CONTRACT2"] }` + +**Important Notes:** + +- Don't deploy contracts that have aliases defined for that network +- Contracts are deployed in dependency order automatically +- You can deploy the same contract to multiple accounts (but not in the same deploy command) + +### Emulators + +Customize emulator settings (optional): + +```json +"emulators": { + "custom-emulator": { + "port": 3600, + "serviceAccount": "emulator-account" + } +} +``` + +## Complete Example + +Here's a complete `flow.json` for a project with multiple contracts and networks: + +```json +{ + "networks": { + "emulator": "127.0.0.1:3569", + "testnet": "access.devnet.nodes.onflow.org:9000", + "mainnet": "access.mainnet.nodes.onflow.org:9000" + }, + + "accounts": { + "emulator-account": { + "address": "f8d6e0586b0a20c7", + "key": "ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee" + }, + "testnet-account": { + "address": "3ae53cb6e3f42a79", + "key": "12332967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111" + } + }, + + "contracts": { + "FungibleToken": { + "source": "./cadence/contracts/FungibleToken.cdc", + "aliases": { + "testnet": "9a0766d93b6608b7", + "mainnet": "f233dcee88fe0abe" + } + }, + "MyToken": "./cadence/contracts/MyToken.cdc", + "MyNFT": "./cadence/contracts/MyNFT.cdc" + }, + + "deployments": { + "emulator": { + "emulator-account": ["FungibleToken", "MyToken", "MyNFT"] + }, + "testnet": { + "testnet-account": ["MyToken", "MyNFT"] + } + } +} +``` + +## Managing Configuration + +Instead of editing `flow.json` manually, use the CLI commands: + +```bash +# Add an account +flow config add account + +# Add a contract +flow config add contract + +# Add a deployment +flow config add deployment + +# Remove configuration +flow config remove account my-account +``` + +## Best Practices + +1. **Use CLI commands** when possible instead of manual editing +2. **Keep private keys secure** - consider using file-based keys for production +3. **Use aliases** for core contracts to avoid redeployment +4. **Test on emulator first** before deploying to testnet +5. **Use different accounts** for different networks +6. **Backup your configuration** before making major changes + +## Related Commands + +- [`flow init`](./initialize-configuration.md) - Initialize a new project +- [`flow config add`](./manage-configuration.md) - Add configuration items +- [`flow project deploy`](../deployment/deploy-project-contracts.md) - Deploy contracts +- [`flow accounts create`](../accounts/create-accounts.md) - Create new accounts diff --git a/docs/build/tools/flow-cli/flow.json/initialize-configuration.md b/docs/build/tools/flow-cli/flow.json/initialize-configuration.md new file mode 100644 index 0000000000..5f0e2bbb90 --- /dev/null +++ b/docs/build/tools/flow-cli/flow.json/initialize-configuration.md @@ -0,0 +1,127 @@ +--- +title: Initialize Configuration +description: How to initialize Flow configuration using CLI +sidebar_position: 1 +--- + +The `flow init` command creates a new Flow project with a basic `flow.json` configuration file. This is the first step in setting up any Flow project. + +## Basic Usage + +```shell +flow init +``` + +This command will: + +- Create a new `flow.json` configuration file +- Set up default networks (emulator, testnet, mainnet) +- Create an emulator service account +- Generate a basic project structure with `cadence/` directories +- Give you options for project scaffolding + +## Project Structure + +After running `flow init`, you'll have: + +``` +my-project/ +├── flow.json +├── emulator-account.pkey +└── cadence/ + ├── contracts/ + ├── scripts/ + ├── transactions/ + └── tests/ +``` + +## Configuration Only + +If you only want to generate the `flow.json` file without creating the full project structure, use the `--config-only` flag: + +```shell +flow init --config-only +``` + +This is useful when: + +- You already have a project structure +- You want to add Flow configuration to an existing project +- You're setting up configuration for a specific environment + +## Global Configuration + +You can create a global `flow.json` file that applies to all Flow projects on your system: + +```shell +flow init --global +``` + +**Global configuration locations:** + +- **macOS/Linux:** `~/flow.json` +- **Windows:** `C:\Users\$USER\flow.json` + +**Priority order:** + +1. Local `flow.json` (highest priority) +2. Global `flow.json` (lowest priority) + +Local configuration files will override global settings for overlapping properties. + +## Error Handling + +If a `flow.json` file already exists, you'll see this error: + +```shell +❌ Command Error: configuration already exists at: flow.json +``` + +**Solutions:** + +- Delete the existing `flow.json` file first +- Initialize in a different directory +- Use `--config-only` to create a new config in a different location + +## Flags + +### Configuration Only + +```shell +flow init --config-only +``` + +Creates only the `flow.json` file without project structure. + +### Global Flags + +The following global flags are also available: + +```shell +# Log level +flow init --log debug + +# Output format +flow init --output json + +# Approve prompts automatically +flow init --yes +``` + +**Available log levels:** `debug`, `info`, `error`, `none` + +## Next Steps + +After initializing your configuration: + +1. **Review the generated `flow.json`** - Understand the default setup +2. **Add your contracts** - Use `flow config add contract` +3. **Create accounts** - Use `flow accounts create` or `flow config add account` +4. **Configure deployments** - Use `flow config add deployment` +5. **Start developing** - Run `flow emulator start` + +## Related Commands + +- [`flow config add`](./manage-configuration.md) - Add configuration items +- [`flow accounts create`](../accounts/create-accounts.md) - Create new accounts +- [`flow project deploy`](../deployment/deploy-project-contracts.md) - Deploy contracts diff --git a/docs/build/tools/flow-cli/flow.json/manage-configuration.md b/docs/build/tools/flow-cli/flow.json/manage-configuration.md new file mode 100644 index 0000000000..654f7ded07 --- /dev/null +++ b/docs/build/tools/flow-cli/flow.json/manage-configuration.md @@ -0,0 +1,312 @@ +--- +title: Manage Configuration +description: How to configure the Flow CLI using config commands +sidebar_position: 3 +--- + +Instead of manually editing `flow.json`, use the Flow CLI's `config` commands to add, remove, and manage your project configuration. These commands provide validation and ensure your configuration is properly formatted. + +## Basic Commands + +```shell +# Add configuration items +flow config add + +# Remove configuration items +flow config remove +``` + +## Adding Configuration + +### Add an Account + +```shell +flow config add account +``` + +You can use flags to specify account details: + +```shell +flow config add account \ + --name my-testnet-account \ + --address f8d6e0586b0a20c7 \ + --private-key ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee \ + --sig-algo ECDSA_P256 \ + --hash-algo SHA3_256 \ + --key-index 0 +``` + +**Available flags:** +- `--name`: Account name +- `--address`: Account address +- `--private-key`: Private key +- `--sig-algo`: Signature algorithm (default: ECDSA_P256) +- `--hash-algo`: Hash algorithm (default: SHA3_256) +- `--key-index`: Key index (default: 0) + +**What gets added to `flow.json`:** +```json +"accounts": { + "my-testnet-account": { + "address": "f8d6e0586b0a20c7", + "key": "ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee" + } +} +``` + +### Add a Contract + +```shell +flow config add contract +``` + +You can use flags to specify contract details: + +```shell +flow config add contract \ + --name MyToken \ + --filename ./cadence/contracts/MyToken.cdc \ + --testnet-alias 9a0766d93b6608b7 \ + --mainnet-alias f233dcee88fe0abe +``` + +**Available flags:** +- `--name`: Contract name +- `--filename`: Path to contract source file +- `--testnet-alias`: Address for testnet alias +- `--mainnet-alias`: Address for mainnet alias +- `--emulator-alias`: Address for emulator alias + +**What gets added to `flow.json`:** +```json +"contracts": { + "MyToken": { + "source": "./cadence/contracts/MyToken.cdc", + "aliases": { + "testnet": "9a0766d93b6608b7", + "mainnet": "f233dcee88fe0abe" + } + } +} +``` + +### Add a Network + +```shell +flow config add network +``` + +You can use flags to specify network details: + +```shell +flow config add network \ + --name custom-testnet \ + --host access-001.devnet30.nodes.onflow.org:9001 \ + --network-key ba69f7d2e82b9edf25b103c195cd371cf0cc047ef8884a9bbe331e62982d46daeebf836f7445a2ac16741013b192959d8ad26998aff12f2adc67a99e1eb2988d +``` + +**Available flags:** +- `--name`: Network name +- `--host`: Flow Access API host address +- `--network-key`: Network key for secure connections + +**What gets added to `flow.json`:** +```json +"networks": { + "custom-testnet": { + "host": "access-001.devnet30.nodes.onflow.org:9001", + "key": "ba69f7d2e82b9edf25b103c195cd371cf0cc047ef8884a9bbe331e62982d46daeebf836f7445a2ac16741013b192959d8ad26998aff12f2adc67a99e1eb2988d" + } +} +``` + +### Add a Deployment + +```shell +flow config add deployment +``` + +You can use flags to specify deployment details: + +```shell +flow config add deployment \ + --network testnet \ + --account my-testnet-account \ + --contract MyToken +``` + +**Available flags:** +- `--network`: Network name for deployment +- `--account`: Account name for deployment +- `--contract`: Contract name(s) to deploy (can specify multiple) + +**What gets added to `flow.json`:** +```json +"deployments": { + "testnet": { + "my-testnet-account": ["MyToken"] + } +} +``` + +## Removing Configuration + +### Remove an Account + +```shell +flow config remove account my-testnet-account +``` + +### Remove a Contract + +```shell +flow config remove contract MyToken +``` + +### Remove a Network + +```shell +flow config remove network custom-testnet +``` + +### Remove a Deployment + +```shell +flow config remove deployment my-testnet-account testnet +``` + +**Note:** This removes all deployments for the specified account on the specified network. + +## Configuration File Management + +### Using Custom Configuration Files + +```shell +# Use a specific configuration file +flow config add account --config-path ./config/flow.json + +# Use multiple configuration files (merged in order) +flow config add account -f flow.json -f private.json +``` + +### Configuration File Priority + +When using multiple configuration files with `-f` flag: + +1. Files are merged from left to right +2. Later files override earlier ones for overlapping properties +3. Non-overlapping properties are combined + +**Example:** +```shell +flow config add account -f flow.json -f private.json +``` + +If both files have an `admin-account`, the one from `private.json` will be used. + +### Security Best Practices + +For better security, consider using separate configuration files for sensitive data: + +**Main configuration file (`flow.json`):** +```json +{ + "accounts": { + "my-testnet-account": { + "address": "3ae53cb6e3f42a79", + "key": { + "type": "file", + "location": "./my-testnet-account.key" + } + } + } +} +``` + +**Private key file (`my-testnet-account.key`):** +``` +334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111 +``` + +**Private configuration file (`private.json`):** +```json +{ + "accounts": { + "my-testnet-account": { + "address": "3ae53cb6e3f42a79", + "key": "334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111" + } + } +} +``` + +⚠️ **Important:** Always add private files to `.gitignore` to prevent committing sensitive data to source control. + +## Validation + +The `config add` command validates all inputs: + +- **Account addresses** must be valid Flow addresses (16-character hex) +- **Private keys** must be valid hex-encoded keys +- **Contract sources** must point to existing `.cdc` files +- **Network hosts** must be valid host:port combinations +- **Deployments** must reference existing accounts and contracts + +## Best Practices + +1. **Use CLI commands** instead of manual editing when possible +2. **Validate your configuration** by running `flow config add` commands +3. **Use descriptive names** for accounts and contracts +4. **Keep sensitive data separate** using multiple config files +5. **Test deployments** on emulator before adding to testnet/mainnet + +## Common Use Cases + +### Setting Up a New Project + +```shell +# Initialize project +flow init + +# Add your contracts +flow config add contract --name MyToken --filename ./cadence/contracts/MyToken.cdc +flow config add contract --name MyNFT --filename ./cadence/contracts/MyNFT.cdc + +# Create accounts for different networks +flow config add account --name emulator-account --address f8d6e0586b0a20c7 --private-key ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee +flow config add account --name testnet-account --address 3ae53cb6e3f42a79 --private-key 12332967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111 + +# Configure deployments +flow config add deployment --network emulator --account emulator-account --contract MyToken --contract MyNFT +flow config add deployment --network testnet --account testnet-account --contract MyToken --contract MyNFT +``` + +### Adding to Existing Project + +```shell +# Add new contract +flow config add contract --name NewContract --filename ./cadence/contracts/NewContract.cdc + +# Add deployment for new contract +flow config add deployment --network testnet --account testnet-account --contract NewContract +``` + +### Managing Multiple Environments + +```shell +# Use separate config files for different environments +flow config add account --name admin-account --address f8d6e0586b0a20c7 --private-key ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee -f flow.json +flow config add account --name admin-account --address f1d6e0586b0a20c7 --private-key 3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7 -f private.json +``` + +## Related Commands + +- [`flow init`](./initialize-configuration.md) - Initialize a new project +- [`flow project deploy`](../deployment/deploy-project-contracts.md) - Deploy contracts +- [`flow accounts create`](../accounts/create-accounts.md) - Create new accounts + + + + + + diff --git a/docs/build/tools/flow-cli/flow.json/security.md b/docs/build/tools/flow-cli/flow.json/security.md new file mode 100644 index 0000000000..22694cf556 --- /dev/null +++ b/docs/build/tools/flow-cli/flow.json/security.md @@ -0,0 +1,324 @@ +--- +title: Security +description: How to securely use Flow CLI and protect your private keys +sidebar_position: 4 +--- + +Managing accounts and private keys requires careful attention to security. This guide covers best practices for keeping your Flow accounts and private keys secure when using the Flow CLI. + +## Security Overview + +⚠️ **Critical Warning**: Never commit private keys to source control. Always use secure methods to store and manage your private keys. + +The Flow CLI provides several secure options for managing private account data: + +1. **File-based keys** - Store keys in separate files +2. **Environment variables** - Use system environment variables +3. **Private configuration files** - Separate sensitive config from main config +4. **Multiple config files** - Merge secure and public configurations + +## File-Based Keys + +Store private keys in separate files that are excluded from source control. + +### Setup + +1. **Create a key file** (e.g., `my-account.key`): +```bash +# Only the hex-encoded private key +334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111 +``` + +2. **Add to `.gitignore`**: +```bash +# Private key files +*.key +*.pkey +private.json +.env +``` + +3. **Configure in `flow.json`**: +```json +{ + "accounts": { + "my-testnet-account": { + "address": "3ae53cb6e3f42a79", + "key": { + "type": "file", + "location": "./my-account.key" + } + } + } +} +``` + +### Benefits +- ✅ Keys are never stored in configuration files +- ✅ Easy to manage multiple keys +- ✅ Clear separation of concerns +- ✅ Works with all Flow CLI commands + +## Environment Variables + +Use environment variables for sensitive data like private keys and addresses. + +### Setup + +1. **Set environment variables**: +```bash +export FLOW_PRIVATE_KEY="334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111" +export FLOW_ACCOUNT_ADDRESS="3ae53cb6e3f42a79" +``` + +2. **Reference in `flow.json`**: +```json +{ + "accounts": { + "my-testnet-account": { + "address": "$FLOW_ACCOUNT_ADDRESS", + "key": "$FLOW_PRIVATE_KEY" + } + } +} +``` + +3. **Use with CLI commands**: +```bash +FLOW_PRIVATE_KEY="your-key" flow project deploy +``` + +### Benefits +- ✅ Keys never stored in files +- ✅ Easy to manage different environments +- ✅ Works with CI/CD systems +- ✅ Can be rotated easily + +## Private Configuration Files + +Create separate configuration files for sensitive data and merge them when needed. + +### Setup + +1. **Main configuration** (`flow.json`): +```json +{ + "networks": { + "testnet": "access.devnet.nodes.onflow.org:9000" + }, + "contracts": { + "MyContract": "./cadence/contracts/MyContract.cdc" + } +} +``` + +2. **Private configuration** (`private.json`): +```json +{ + "accounts": { + "my-testnet-account": { + "address": "3ae53cb6e3f42a79", + "key": "334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111" + } + } +} +``` + +3. **Add to `.gitignore`**: +```bash +private.json +secrets.json +*.private.json +``` + +4. **Use with CLI commands**: +```bash +flow project deploy -f flow.json -f private.json +``` + +### Benefits +- ✅ Clear separation of public and private data +- ✅ Easy to manage multiple environments +- ✅ Can be shared safely (without private files) +- ✅ Works with all CLI commands + +## Environment Files (.env) + +Use `.env` files for local development with automatic loading by the CLI. + +### Setup + +1. **Create `.env` file**: +```bash +# .env +FLOW_PRIVATE_KEY=334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111 +FLOW_ACCOUNT_ADDRESS=3ae53cb6e3f42a79 +FLOW_NETWORK=testnet +``` + +2. **Reference in `flow.json`**: +```json +{ + "accounts": { + "my-testnet-account": { + "address": "$FLOW_ACCOUNT_ADDRESS", + "key": "$FLOW_PRIVATE_KEY" + } + }, + "networks": { + "testnet": "access.devnet.nodes.onflow.org:9000" + } +} +``` + +3. **Add to `.gitignore`**: +```bash +.env +.env.local +.env.*.local +``` + +### Benefits +- ✅ Automatic loading by CLI +- ✅ Easy local development +- ✅ Can have different files for different environments +- ✅ Standard practice for many tools + +## Multiple Configuration Files + +Merge multiple configuration files for complex setups. + +### Priority Order + +When using multiple files, they are merged in order: +1. **Left to right** - Files specified first have lowest priority +2. **Later files override** - Properties in later files take precedence +3. **Non-overlapping properties** - Are combined from all files + +### Example + +```bash +flow project deploy -f flow.json -f private.json -f local.json +``` + +**Result**: `local.json` overrides `private.json`, which overrides `flow.json` + +### Use Cases + +- **Development**: `flow.json` + `dev-private.json` +- **Staging**: `flow.json` + `staging-private.json` +- **Production**: `flow.json` + `prod-private.json` + +## Security Best Practices + +### 1. Never Commit Private Keys + +```bash +# Always add these to .gitignore +*.key +*.pkey +private.json +secrets.json +.env +.env.local +*.private.json +``` + +### 2. Use Different Keys for Different Environments + +- **Development**: Use testnet keys +- **Staging**: Use separate testnet keys +- **Production**: Use mainnet keys with highest security + +### 3. Rotate Keys Regularly + +- Generate new keys periodically +- Update configuration files +- Test with new keys before switching + +### 4. Limit Key Permissions + +- Use keys with minimal required permissions +- Consider using different keys for different operations +- Monitor key usage + +### 5. Secure Key Storage + +- Use hardware security modules (HSMs) for production +- Consider cloud key management services +- Encrypt key files when possible + +## Common Security Mistakes + +### ❌ Don't Do This + +```json +// flow.json - NEVER do this +{ + "accounts": { + "my-account": { + "address": "3ae53cb6e3f42a79", + "key": "334232967f52bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad1111" + } + } +} +``` + +### ✅ Do This Instead + +```json +// flow.json - Safe to commit +{ + "accounts": { + "my-account": { + "address": "3ae53cb6e3f42a79", + "key": { + "type": "file", + "location": "./my-account.key" + } + } + } +} +``` + +:::info Extracting Existing Inline Keys + +If you already have inline keys in your `flow.json`, you can easily extract them to separate files: + +```bash +flow config extract-key --all +``` + +This command creates `.pkey` files with restricted permissions, updates your `flow.json` to reference them, and adds the key files to `.gitignore`. + +::: + +## Troubleshooting + +### Environment Variables Not Loading + +Check that your environment variables are set: +```bash +echo $FLOW_PRIVATE_KEY +``` + +### Key File Not Found + +Verify the key file path in your configuration: +```bash +ls -la ./my-account.key +``` + +### Multiple Config Files Not Merging + +Check the order of your `-f` flags: +```bash +# Correct order (left to right, later overrides earlier) +flow config add account -f flow.json -f private.json +``` + +## Related Commands + +- [`flow config add`](./manage-configuration.md) - Add configuration items securely +- [`flow project deploy`](../deployment/deploy-project-contracts.md) - Deploy with secure configuration +- [`flow accounts create`](../accounts/create-accounts.md) - Create accounts securely diff --git a/docs/build/tools/flow-cli/fork-testing.md b/docs/build/tools/flow-cli/fork-testing.md new file mode 100644 index 0000000000..9d6a5507f5 --- /dev/null +++ b/docs/build/tools/flow-cli/fork-testing.md @@ -0,0 +1,220 @@ +--- +title: Fork Testing +description: Test your Flow applications against production state using mainnet or testnet forks +sidebar_position: 15 +--- + +# Fork Testing + +Fork testing allows you to run tests and development environments against a **local copy of mainnet or testnet state**. This gives you access to real contracts, accounts, and data without deploying to live networks or affecting production state. + +## What is Fork Testing? + +Fork testing creates a local Flow network that mirrors the state of a real network (mainnet or testnet). Your code runs locally, but can read from and interact with production contract implementations, real account balances, and actual on-chain data. + +**Key Benefits:** + +- ✅ **Test against real production contracts** - No need to mock complex dependencies +- ✅ **Access real account state** - Test with actual balances, NFTs, and storage +- ✅ **Reproduce production issues** - Debug problems at specific block heights +- ✅ **Test contract upgrades safely** - Verify changes work with real mainnet state +- ✅ **Safe testing environment** - All changes stay local, never affect the real network +- ✅ **Fast iteration** - No deployment costs or wait times + +Fork testing is an essential part of a comprehensive testing strategy. It complements unit tests and integration tests by letting you validate your contracts against real-world state and dependencies. Learn more about building a complete testing approach in the [Testing Strategy guide](../../../build/cadence/smart-contracts/testing-strategy.md). + +## Two Fork Testing Modes + +The Flow CLI provides two different fork testing modes for different use cases: + +### 1. Emulator Fork Mode (`flow emulator --fork`) + +**Best for:** + +- Frontend and app development +- E2E testing (Cypress, Playwright) +- Manual testing and exploration +- Wallet integration testing +- Bot and indexer development + +**How it works:** +Starts a full emulator with REST and gRPC APIs that you can connect to with FCL, dev wallet, or any Flow SDK. + +```bash +flow emulator --fork mainnet +``` + +**Learn more:** [Interactive Testing with Forked Emulator](../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md) + +### 2. Test Framework Fork Mode (`flow test` + `#test_fork`) + +**Best for:** + +- Cadence integration tests +- Contract testing against real dependencies +- Testing contract logic with real mainnet state + +**How it works:** +Runs your `*_test.cdc` files against a forked network using the [Cadence Testing Framework](../../../build/cadence/smart-contracts/testing.md). Add the `#test_fork` pragma to your test file, then run: + +```bash +flow test +``` + +**Learn more:** [Fork Testing with Cadence](../../../blockchain-development-tutorials/cadence/fork-testing/index.md) + +## Quick Comparison + +| Feature | `flow emulator --fork` | `flow test` + `#test_fork` | +| --------------- | --------------------------------------- | -------------------------- | +| **Use for** | App E2E, manual testing, debugging | Cadence integration tests | +| **Connects to** | Frontend, wallets, bots, E2E tools | Cadence Testing Framework | +| **Run with** | FCL, Cypress, Playwright, manual clicks | `flow test` command | +| **Best for** | User flows, UI testing, exploration | Contract logic validation | +| **Examples** | React app, wallet flows, E2E suites | `*_test.cdc` files | + +## Common Use Cases + +### DeFi Protocol Testing + +Test your DeFi contracts against real mainnet state - real DEX liquidity, real oracle prices, real token supplies. + +### Contract Upgrade Testing + +Deploy your upgraded contract to a fork and verify it works with real mainnet state before deploying to production. + +### Bug Reproduction + +Fork to the exact block height where a bug occurred and debug with the actual state that caused the issue. + +### Integration Testing + +Test how your contracts interact with production versions of core contracts (FungibleToken, NFT standards, etc). + +## Getting Started + +### Prerequisites + +- [Flow CLI](./install.md) v2.12.0 or later +- Basic understanding of Flow development + +### Quick Start: Emulator Fork + +```bash +# 1. Initialize a Flow project +flow init + +# 2. Install dependencies (e.g., FlowToken) +flow dependencies install FlowToken FungibleToken + +# 3. Start the forked emulator +flow emulator --fork mainnet + +# 4. In another terminal, run scripts/transactions +flow scripts execute myScript.cdc --network mainnet-fork +``` + +**Next steps:** Follow the [complete emulator fork tutorial](../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md) + +### Quick Start: Cadence Test Fork + +Add the fork pragma to your test file: + +```cadence +#test_fork(network: "mainnet", height: nil) + +import Test + +access(all) fun testExample() { + // Your test code here +} +``` + +Then run the test: + +```bash +flow test tests/MyContract_test.cdc +``` + +**Next steps:** Follow the [complete Cadence fork testing tutorial](../../../blockchain-development-tutorials/cadence/fork-testing/index.md) + +## Key Features + +### Pin to Block Heights + +Fork to specific block heights for reproducible testing: + +```bash +# Emulator fork with block height +flow emulator --fork mainnet --fork-height +``` + +```cadence +// Test with block height - add to your test file +#test_fork(network: "mainnet", height: ) +``` + +```bash +# Then run the test +flow test test_file.cdc +``` + +Replace `` with the specific block number you want to test against. Note that block heights are only available within the current spork. + +### Account Impersonation + +Fork mode disables signature verification, allowing you to execute transactions as any mainnet account for testing. + +### Dependency Mocking + +Override specific mainnet contracts with your own versions while keeping all other contracts unchanged - perfect for testing contract upgrades. + +### Automatic Configuration + +Fork networks are automatically configured when you run fork commands. Contract aliases from the parent network (mainnet/testnet) are automatically inherited. + +Learn more: [flow.json Configuration - Fork Networks](./flow.json/configuration.md#networks) + +## Best Practices + +1. **Pin block heights in CI/CD** - Ensures reproducible test results +2. **Test on testnet first** - Avoid mainnet rate limits during development +3. **Use the right mode** - Emulator fork for apps, test fork for Cadence contracts +4. **Mock external services** - Fork only mirrors Flow state, not external APIs +5. **Document your fork heights** - Keep track of which blocks work for testing + +## Network Requirements + +Fork testing requires network access to Flow's public access nodes: + +- **Mainnet:** `access.mainnet.nodes.onflow.org:9000` +- **Testnet:** `access.devnet.nodes.onflow.org:9000` + +Data is fetched on-demand and cached locally for performance. + +## Limitations + +- **Spork boundaries:** Historical data is only available within the current spork +- **Off-chain services:** Oracles, IPFS, and cross-chain bridges must be mocked +- **Network latency:** First access to accounts/contracts requires network fetch + +Learn more: [Network Upgrade (Spork) Process](../../../protocol/node-ops/node-operation/network-upgrade.md) + +## Tutorials + +- [Interactive Testing with Forked Emulator](../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md) - Complete guide to `flow emulator --fork` +- [Fork Testing with Cadence](../../../blockchain-development-tutorials/cadence/fork-testing/index.md) - Complete guide to `flow test` with `#test_fork` + +## Related Documentation + +- [Flow Emulator](../emulator/index.md) - Learn more about the Flow emulator +- [Cadence Testing Framework](../../../build/cadence/smart-contracts/testing.md) - Write and run Cadence tests +- [flow.json Configuration](./flow.json/configuration.md) - Configure fork networks +- [Testing Strategy](../../../build/cadence/smart-contracts/testing-strategy.md) - Overall testing approach +- [Dependency Manager](./dependency-manager.md) - Install and manage contract dependencies + +## Need Help? + +- Review the [complete tutorials](../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md) for step-by-step guidance +- Check the [troubleshooting sections](../../../blockchain-development-tutorials/cadence/emulator-fork-testing/index.md#troubleshooting) in the tutorials +- Ask questions in the [Flow Discord](https://discord.gg/flow) diff --git a/docs/build/tools/flow-cli/generate.md b/docs/build/tools/flow-cli/generate.md new file mode 100644 index 0000000000..8c1f57b75a --- /dev/null +++ b/docs/build/tools/flow-cli/generate.md @@ -0,0 +1,181 @@ +--- +title: Generating Cadence Boilerplate +sidebar_label: Generating Cadence Boilerplate +description: Generate template files for common Cadence code using the Flow CLI +sidebar_position: 12 +--- + +The `flow generate` command provides a convenient way to create boilerplate template files for common Cadence code components. This command streamlines the development process by automatically generating properly structured files with the correct syntax and organization. + +## Overview + +```bash +flow generate [command] +``` + +**Aliases:** `generate`, `g` + +The generate command supports four main subcommands for creating different types of Cadence files: + +- **contract** - Generate Cadence smart contract templates +- **script** - Generate Cadence script templates +- **test** - Generate Cadence test templates +- **transaction** - Generate Cadence transaction templates + +## Generate Contract + +Creates a new Cadence smart contract with a basic template structure. + +### Usage + +```bash +flow generate contract [flags] +``` + +### Example + +```bash +flow generate contract HelloWorld +``` + +This command creates a file `cadence/contracts/HelloWorld.cdc` with the following content: + +```cadence +access(all) contract HelloWorld { + init() {} +} +``` + +:::info +When generating a contract, a corresponding test file will also be created automatically (unless `--skip-tests` is used). For example, generating `HelloWorld` contract will also create `cadence/tests/HelloWorld.test.cdc`. +::: + +### Flags + +- `--dir string` - Directory to generate files in (defaults to `cadence/contracts/`) +- `--skip-tests` - Skip generating test files +- `-h, --help` - Help for contract command + +## Generate Transaction + +Creates a new Cadence transaction with a basic template structure. + +### Usage + +```bash +flow generate transaction [flags] +``` + +### Example + +```bash +flow generate transaction TransferTokens +``` + +This command creates a file `cadence/transactions/TransferTokens.cdc` with the following content: + +```cadence +transaction() { + prepare() {} + + execute {} +} +``` + +### Flags + +- `--dir string` - Directory to generate files in (defaults to `cadence/transactions/`) +- `--skip-tests` - Skip generating test files +- `-h, --help` - Help for transaction command + +## Generate Script + +Creates a new Cadence script with a basic template structure. + +### Usage + +```bash +flow generate script [flags] +``` + +### Example + +```bash +flow generate script GetBalance +``` + +This command creates a file `cadence/scripts/GetBalance.cdc` with the following content: + +```cadence +access(all) fun main() {} +``` + +### Flags + +- `--dir string` - Directory to generate files in (defaults to `cadence/scripts/`) +- `--skip-tests` - Skip generating test files +- `-h, --help` - Help for script command + +## Generate Test + +Creates a new Cadence test file with a basic template structure. + +### Usage + +```bash +flow generate test [flags] +``` + +### Example + +```bash +flow generate test MyToken +``` + +This command creates a file `cadence/tests/MyToken.test.cdc` with a basic test structure. + +After generating a test, you can run it using `flow test`. For more information about writing and running Cadence tests, see the [Cadence Tests documentation](./tests.md). + +### Flags + +- `--dir string` - Directory to generate files in (defaults to `cadence/tests/`) +- `--skip-tests` - Skip generating test files +- `-h, --help` - Help for test command + +## Custom Directory Usage + +All generate commands support the `--dir` flag to specify a custom directory for the generated files. This is useful when your project requires a different organizational structure than the default. + +### Examples + +```bash +# Generate contract in a custom directory +flow generate contract MyToken --dir=src/contracts + +# Generate transaction in a custom directory +flow generate transaction Transfer --dir=src/transactions + +# Generate script in a custom directory +flow generate script GetData --dir=src/scripts + +# Generate test in a custom directory +flow generate test MyToken --dir=src/tests +``` + +## Project Structure + +When using the default directories, the generate command creates the following structure: + +``` +cadence/ +├── contracts/ +│ └── MyToken.cdc +├── scripts/ +│ └── GetBalance.cdc +├── transactions/ +│ └── TransferTokens.cdc +└── tests/ + └── MyToken.test.cdc +``` + +The generate command is an essential tool for accelerating Flow development by providing standardized, well-structured boilerplate code for all common Cadence components. diff --git a/docs/tools/flow-cli/get-flow-data/_category_.json b/docs/build/tools/flow-cli/get-flow-data/_category_.json similarity index 100% rename from docs/tools/flow-cli/get-flow-data/_category_.json rename to docs/build/tools/flow-cli/get-flow-data/_category_.json diff --git a/docs/tools/flow-cli/get-flow-data/get-blocks.md b/docs/build/tools/flow-cli/get-flow-data/get-blocks.md similarity index 97% rename from docs/tools/flow-cli/get-flow-data/get-blocks.md rename to docs/build/tools/flow-cli/get-flow-data/get-blocks.md index 59ceef2161..00e0fe1030 100644 --- a/docs/tools/flow-cli/get-flow-data/get-blocks.md +++ b/docs/build/tools/flow-cli/get-flow-data/get-blocks.md @@ -53,6 +53,7 @@ Total Collections 8 ## Arguments ### Query + - Name: `` - Valid Input: Block ID, `latest` or block height @@ -61,11 +62,11 @@ Specify the block to retrieve by block ID or block height. ## Arguments ### Address + - Name: `address` - Valid Input: Flow account address -Flow [account address](../../../build/basics/accounts.md) (prefixed with `0x` or not). - +Flow [account address](../../../cadence/basics/accounts.md) (prefixed with `0x` or not). ## Flags @@ -166,4 +167,4 @@ several configuration files. - Flag: `--skip-version-check` - Default: `false` -Skip version check during start up to speed up process for slow connections. \ No newline at end of file +Skip version check during start up to speed up process for slow connections. diff --git a/docs/tools/flow-cli/get-flow-data/get-collections.md b/docs/build/tools/flow-cli/get-flow-data/get-collections.md similarity index 100% rename from docs/tools/flow-cli/get-flow-data/get-collections.md rename to docs/build/tools/flow-cli/get-flow-data/get-collections.md diff --git a/docs/tools/flow-cli/get-flow-data/get-events.md b/docs/build/tools/flow-cli/get-flow-data/get-events.md similarity index 100% rename from docs/tools/flow-cli/get-flow-data/get-events.md rename to docs/build/tools/flow-cli/get-flow-data/get-events.md diff --git a/docs/tools/flow-cli/get-flow-data/get-status.md b/docs/build/tools/flow-cli/get-flow-data/get-status.md similarity index 100% rename from docs/tools/flow-cli/get-flow-data/get-status.md rename to docs/build/tools/flow-cli/get-flow-data/get-status.md diff --git a/docs/tools/flow-cli/index.md b/docs/build/tools/flow-cli/index.md similarity index 76% rename from docs/tools/flow-cli/index.md rename to docs/build/tools/flow-cli/index.md index 583c9679a8..4993be5797 100644 --- a/docs/tools/flow-cli/index.md +++ b/docs/build/tools/flow-cli/index.md @@ -14,7 +14,9 @@ With Flow CLI, developers can: - **Send Transactions**: Build, sign, and submit transactions to the Flow network, allowing for contract interaction and fund transfers. - **Query Chain State**: Retrieve data from the Flow blockchain, including account balances, event logs, and the status of specific transactions. - **Deploy Smart Contracts**: Easily deploy and update Cadence smart contracts on any Flow environment (emulator, testnet, or mainnet). +- **Profile Transaction Performance**: Generate detailed computational profiles of sealed transactions to optimize gas costs and identify performance bottlenecks. - **Use the Emulator:** Set up a local Flow blockchain instance with the Flow emulator to test and debug smart contracts in a development environment before deploying them on the network. +- **Test with Fork Mode**: Use [fork testing](fork-testing.md) to run tests and development environments against a local copy of mainnet or testnet state, giving you access to real contracts and data without affecting production. - **Interact with the [Flow Access API](/http-api)**: Automate complex workflows using configuration files and command-line scripting, which allows for greater flexibility in continuous integration (CI) or custom development tools. - **Access Flow’s Tooling Ecosystem**: Integrate Flow CLI with other developer tools like the [Cadence Extension for VSCode](https://marketplace.visualstudio.com/items?itemName=onflow.cadence) to enhance your development experience. @@ -27,4 +29,12 @@ macOS, Linux, and Windows. ## Create Your First Project -To get started with creating your first Flow project and to learn more about how to use the Flow CLI super commands, please refer to the [Super Commands documentation](super-commands.md). These commands simplify the setup and development process, allowing you to focus on building your application without worrying about the underlying configurations. +Get started by running: + +```zsh +flow init +``` + +The `flow init` command gets you up and running with a new project setup in one command. Choose from scaffolds for scheduled transactions, DeFi actions, stablecoins, and more, or start with a basic Cadence project. + +To learn more about Flow CLI commands and how to use them, please refer to the [Commands documentation](./commands.md). diff --git a/docs/tools/flow-cli/install.md b/docs/build/tools/flow-cli/install.md similarity index 82% rename from docs/tools/flow-cli/install.md rename to docs/build/tools/flow-cli/install.md index 0afd8c8e01..86882b9d5e 100644 --- a/docs/tools/flow-cli/install.md +++ b/docs/build/tools/flow-cli/install.md @@ -59,9 +59,9 @@ _This installation method only works on Windows 10, 8.1, or 7 (SP1, with [PowerS 1. Open PowerShell ([Instructions](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-7#finding-powershell-in-windows-10-81-80-and-7)) 2. In PowerShell, run: - ```powershell - iex "& { $(irm 'https://raw.githubusercontent.com/onflow/flow-cli/master/install.ps1') }" - ``` + ```powershell + iex "& { $(irm 'https://raw.githubusercontent.com/onflow/flow-cli/master/install.ps1') }" + ``` To update, simply re-run the installation command above. @@ -106,16 +106,24 @@ _This update method only works on Windows 10, 8.1, or 7 (SP1, with [PowerShell 3 1. Open PowerShell ([Instructions](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-7#finding-powershell-in-windows-10-81-80-and-7)) 2. In PowerShell, run: - ```powershell - iex "& { $(irm 'https://raw.githubusercontent.com/onflow/flow-cli/master/install.ps1') }" - ``` + ```powershell + iex "& { $(irm 'https://raw.githubusercontent.com/onflow/flow-cli/master/install.ps1') }" + ``` ## Uninstalling Flow CLI -To remove the flow CLI you can run the following command if it was previously installed using a pre-built binary. +To remove the flow CLI you can run the following command if it was previously installed using a pre-built binary. - macOS: `rm /usr/local/bin/flow` - Linux: `rm ~/.local/bin/flow` - Windows: `rm ~/Users/{user}/AppData/Flow/flow.exe` If you installed it using Hombrew you can remove it using: `brew uninstall flow-cli`. + +## Next Steps + +Now that you have the Flow CLI installed, you can: + +- **[Get started with Flow CLI commands](./commands.md)** - Learn the essential commands for project development +- **[Initialize a new project](./flow.json/initialize-configuration.md)** - Create your first Flow project +- **[Configure your project](./flow.json/configuration.md)** - Set up your `flow.json` configuration file diff --git a/docs/tools/flow-cli/keys/_category_.json b/docs/build/tools/flow-cli/keys/_category_.json similarity index 100% rename from docs/tools/flow-cli/keys/_category_.json rename to docs/build/tools/flow-cli/keys/_category_.json diff --git a/docs/tools/flow-cli/keys/decode-keys.md b/docs/build/tools/flow-cli/keys/decode-keys.md similarity index 100% rename from docs/tools/flow-cli/keys/decode-keys.md rename to docs/build/tools/flow-cli/keys/decode-keys.md diff --git a/docs/tools/flow-cli/keys/derive-keys.md b/docs/build/tools/flow-cli/keys/derive-keys.md similarity index 100% rename from docs/tools/flow-cli/keys/derive-keys.md rename to docs/build/tools/flow-cli/keys/derive-keys.md diff --git a/docs/tools/flow-cli/keys/generate-keys.md b/docs/build/tools/flow-cli/keys/generate-keys.md similarity index 93% rename from docs/tools/flow-cli/keys/generate-keys.md rename to docs/build/tools/flow-cli/keys/generate-keys.md index 1af084c670..409d0b2f11 100644 --- a/docs/tools/flow-cli/keys/generate-keys.md +++ b/docs/build/tools/flow-cli/keys/generate-keys.md @@ -5,7 +5,7 @@ sidebar_position: 1 --- The Flow CLI provides a command to generate ECDSA key pairs -that can be [attached to new or existing Flow accounts](../../../build/basics/accounts.md). +that can be [attached to new or existing Flow accounts](../../../cadence/basics/accounts.md). ```shell flow keys generate @@ -24,9 +24,9 @@ flow keys generate ```shell > flow keys generate -🔴️ Store Private Key safely and don't share with anyone! -Private Key c778170793026a9a7a3815dabed68ded445bde7f40a8c66889908197412be89f -Public Key 584245c57e5316d6606c53b1ce46dae29f5c9bd26e9e8...aaa5091b2eebcb2ac71c75cf70842878878a2d650f7 +🔴️ Store Private Key safely and don't share with anyone! +Private Key c778170793026a9a7a3815dabed68ded445bde7f40a8c66889908197412be89f +Public Key 584245c57e5316d6606c53b1ce46dae29f5c9bd26e9e8...aaa5091b2eebcb2ac71c75cf70842878878a2d650f7 ``` ## Flags @@ -43,7 +43,7 @@ result in the same key. If no seed is specified, the key pair will be generated using a random 32 byte seed. -⚠️ Using seed with production keys can be dangerous if seed was not generated +⚠️ Using seed with production keys can be dangerous if seed was not generated by using safe random generators. ### Signature Algorithm diff --git a/docs/tools/flow-cli/lint.md b/docs/build/tools/flow-cli/lint.md similarity index 100% rename from docs/tools/flow-cli/lint.md rename to docs/build/tools/flow-cli/lint.md diff --git a/docs/build/tools/flow-cli/scheduled-transactions.md b/docs/build/tools/flow-cli/scheduled-transactions.md new file mode 100644 index 0000000000..7b0e4e7330 --- /dev/null +++ b/docs/build/tools/flow-cli/scheduled-transactions.md @@ -0,0 +1,235 @@ +--- +title: Scheduled Transactions +description: Manage scheduled transactions on Flow with the CLI +sidebar_position: 14 +--- + +The Flow CLI provides commands to manage scheduled transactions. These commands allow you to set up a Manager resource, list scheduled transactions, get transaction details, and cancel transactions. + +## What are Scheduled Transactions? + +Scheduled transactions enable smart contracts to schedule autonomous execution in the future without external triggers. This allows for use cases like recurring payments, automated arbitrage, and time-based contract logic. + +The scheduled transactions system uses priorities (High, Medium, Low) with different execution guarantees and fee multipliers to ensure predictable performance while enabling novel autonomous blockchain patterns. + +📖 **[Learn more about scheduled transactions](../../../blockchain-development-tutorials/forte/scheduled-transactions/scheduled-transactions-introduction.md)** + +## Prerequisites + +Before using the scheduled transactions commands, you must initialize a Manager resource in your account storage. The Manager resource is provided by the **FlowTransactionSchedulerUtils** core contract and provides a convenient way to group, schedule, cancel, and query scheduled transactions through a single resource. + +## Why Use the Manager? + +While it's possible to schedule transactions directly, **using the Manager resource is essential for proper tooling integration**. The Manager provides a standardized interface that allows CLI commands, block explorers, and other developer tools to discover and interact with your scheduled transactions. + +**Key benefits of using the Manager:** +- **Tooling Integration**: CLI commands and other tools can automatically discover and manage your scheduled transactions +- **Centralized Management**: All your scheduled transactions are organized in one place for easy tracking +- **Enhanced Querying**: Query transactions by handler type, timestamp, or status through standardized interfaces +- **Metadata Access**: Tools can resolve handler views and metadata to provide richer information about your scheduled transactions + +Without the Manager, your scheduled transactions exist but cannot be easily discovered or managed through tooling, requiring manual tracking and interaction. + +## Commands + +### Setup Manager Resource + +Initialize a Manager resource in your account storage to start managing scheduled transactions. + +```shell +flow schedule setup +``` + +This command creates and stores a Manager resource at the standard storage path, allowing you to manage scheduled transactions for your account. + +#### Example Usage + +```shell +flow schedule setup --network testnet --signer my-account +``` + +#### Flags + +- `--signer` - The account that will own the Manager resource +- `--network` / `-n` - Network to execute on (emulator, testnet, mainnet) +- `--host` - Access API hostname +- `--config-path` / `-f` - Path to flow.json configuration file + +--- + +### List Scheduled Transactions + +List all scheduled transactions for a given account that has a Manager resource. + +```shell +flow schedule list +``` + +#### Arguments + +**Account** +- Name: `account` +- Valid inputs: Flow account address (with or without `0x` prefix) or account name from flow.json + +The account address or name that has scheduled transactions to list. + +#### Example Usage + +```shell +flow schedule list 0x01cf0e2f2f715450 --network testnet +``` + +#### Flags + +- `--network` / `-n` - Network to query (emulator, testnet, mainnet) +- `--host` - Access API hostname +- `--output` / `-o` - Output format (`json`, `inline`) +- `--filter` / `-x` - Filter output by property name +- `--save` / `-s` - Save output to file +- `--config-path` / `-f` - Path to flow.json configuration file + +--- + +### Get Transaction Details + +Get detailed information about a specific scheduled transaction by its ID. + +```shell +flow schedule get +``` + +#### Arguments + +**Transaction ID** +- Name: `transaction-id` +- Valid inputs: Unsigned integer (UInt64) + +The unique identifier of the scheduled transaction to retrieve. + +#### Example Usage + +```shell +flow schedule get 123 --network testnet +``` + +#### Flags + +- `--network` / `-n` - Network to query (emulator, testnet, mainnet) +- `--host` - Access API hostname +- `--output` / `-o` - Output format (`json`, `inline`) +- `--filter` / `-x` - Filter output by property name +- `--save` / `-s` - Save output to file +- `--config-path` / `-f` - Path to flow.json configuration file + +--- + +### Cancel Scheduled Transaction + +Cancel a scheduled transaction and receive a partial fee refund. + +```shell +flow schedule cancel +``` + +When you cancel a scheduled transaction, a portion of the fees paid will be refunded based on the configured refund multiplier. The transaction must be in a scheduled state (not already executed or canceled). + +#### Arguments + +**Transaction ID** +- Name: `transaction-id` +- Valid inputs: Unsigned integer (UInt64) + +The unique identifier of the scheduled transaction to cancel. + +#### Example Usage + +```shell +flow schedule cancel 123 --network testnet --signer my-account +``` + +#### Flags + +- `--signer` - Account that owns the Manager resource containing the transaction +- `--network` / `-n` - Network to execute on (emulator, testnet, mainnet) +- `--host` - Access API hostname +- `--output` / `-o` - Output format (`json`, `inline`) +- `--config-path` / `-f` - Path to flow.json configuration file + +--- + +## Common Flags + +These flags are available across all scheduled transactions commands: + +### Network + +- Flag: `--network` +- Short Flag: `-n` +- Valid inputs: the name of a network defined in the configuration (`flow.json`) +- Default: `emulator` + +Specify which network you want the command to use for execution. + +### Host + +- Flag: `--host` +- Valid inputs: an IP address or hostname +- Default: `127.0.0.1:3569` (Flow Emulator) + +Specify the hostname of the Access API that will be used to execute the commands. This flag overrides any host defined by the `--network` flag. + +### Network Key + +- Flag: `--network-key` +- Valid inputs: A valid network public key of the host in hex string format + +Specify the network public key of the Access API that will be used to create a secure GRPC client when executing the command. + +### Configuration + +- Flag: `--config-path` +- Short Flag: `-f` +- Valid inputs: a path in the current filesystem +- Default: `flow.json` + +Specify the path to the `flow.json` configuration file. You can use the `-f` flag multiple times to merge several configuration files. + +### Output + +- Flag: `--output` +- Short Flag: `-o` +- Valid inputs: `json`, `inline` + +Specify the format of the command results. + +### Filter + +- Flag: `--filter` +- Short Flag: `-x` +- Valid inputs: a case-sensitive name of the result property + +Specify any property name from the result you want to return as the only value. + +### Save + +- Flag: `--save` +- Short Flag: `-s` +- Valid inputs: a path in the current filesystem + +Specify the filename where you want the result to be saved. + +### Log + +- Flag: `--log` +- Short Flag: `-l` +- Valid inputs: `none`, `error`, `debug` +- Default: `info` + +Specify the log level. Control how much output you want to see during command execution. + +### Version Check + +- Flag: `--skip-version-check` +- Default: `false` + +Skip version check during start up to speed up process for slow connections. diff --git a/docs/tools/flow-cli/scripts/_category_.json b/docs/build/tools/flow-cli/scripts/_category_.json similarity index 100% rename from docs/tools/flow-cli/scripts/_category_.json rename to docs/build/tools/flow-cli/scripts/_category_.json diff --git a/docs/tools/flow-cli/scripts/execute-scripts.md b/docs/build/tools/flow-cli/scripts/execute-scripts.md similarity index 100% rename from docs/tools/flow-cli/scripts/execute-scripts.md rename to docs/build/tools/flow-cli/scripts/execute-scripts.md diff --git a/docs/tools/flow-cli/tests.md b/docs/build/tools/flow-cli/tests.md similarity index 66% rename from docs/tools/flow-cli/tests.md rename to docs/build/tools/flow-cli/tests.md index c5d83a4c08..8e8ce0b531 100644 --- a/docs/tools/flow-cli/tests.md +++ b/docs/build/tools/flow-cli/tests.md @@ -3,6 +3,29 @@ title: Running Cadence Tests sidebar_label: Running Cadence Tests description: How to run Cadence tests from the CLI sidebar_position: 11 +keywords: + - flow test + - Cadence tests + - Flow CLI + - test command + - test flags + - code coverage + - fork testing + - flow test --fork + - fork-height + - fork-host + - mainnet fork + - testnet fork + - test discovery + - test aliases + - testing configuration + - test selection + - test by name + - random testing + - coverage reporting + - test automation + - integration testing + - spork boundaries --- The Flow CLI provides a straightforward command to execute Cadence tests, enabling developers to validate their scripts and smart contracts effectively. @@ -72,10 +95,8 @@ Assuming you have a test script named `test_script_test.cdc` in your project dir // test_script_test.cdc import Test -access(all) let blockchain = Test.newEmulatorBlockchain() - access(all) fun testSumOfTwo() { - let scriptResult = blockchain.executeScript( + let scriptResult = Test.executeScript( "access(all) fun main(a: Int, b: Int): Int { return a + b }", [2, 3] ) @@ -102,19 +123,19 @@ Test results: - PASS: test_script_test.cdc > testSumOfTwo ``` -To learn more about writing tests in Cadence, visit the [Cadence Testing Framework](../../build/smart-contracts/testing.md) documentation. +To learn more about writing tests in Cadence, visit the [Cadence Testing Framework](../../cadence/smart-contracts/testing.md) documentation. --- -### Running Specific Tests +### Running Specific Tests and Files -If you wish to run a specific test script rather than all tests, you can provide the path to the test file: +Run specific test scripts or directories by providing their paths: ```shell -flow test path/to/your/test_script_test.cdc +flow test path/to/your/test_script_test.cdc path/to/another_test.cdc tests/subsuite/ ``` -This will execute only the tests contained in the specified file. +This executes only the tests contained in the specified files and directories. --- @@ -224,4 +245,76 @@ flow test --name=testSumOfTwo This command will run only the test function named `testSumOfTwo` across all test scripts that contain it. -To dive deeper into testing the functionality of your Cadence scripts and contracts, explore the [Cadence Testing Framework](https://cadence-lang.org/docs/testing-framework) documentation. \ No newline at end of file +To dive deeper into testing the functionality of your Cadence scripts and contracts, explore the [Cadence Testing Framework](https://cadence-lang.org/docs/testing-framework) documentation. + +--- + +### Fork Testing Flags + +Run tests against forked mainnet or testnet state. For a step-by-step tutorial, see: [Fork Testing with Cadence](../../../blockchain-development-tutorials/cadence/fork-testing/index.md). For background and best practices, see the guide: [Testing Strategy on Flow](../../cadence/smart-contracts/testing-strategy.md). + +#### Configuring Fork Tests + +**Recommended**: Use the `#test_fork` pragma in your test file: + +```cadence +#test_fork(network: "mainnet", height: nil) + +import Test + +access(all) fun testAgainstMainnet() { + // Test runs against mainnet state +} +``` + +Then run with: + +```shell +flow test +``` + +The pragma configures fork testing directly in your test files, making tests self-documenting. You can also use CLI flags (documented below) to override or configure fork tests without modifying test files. + +#### --fork + +- Type: `string` +- Default: `""` (empty). If provided without a value, defaults to `mainnet`. + +Fork tests from a network defined in `flow.json`. The CLI resolves the GRPC access host and chain ID from the selected network configuration. + +```shell +flow test --fork # Uses mainnet by default +flow test --fork testnet # Uses testnet +flow test --fork mynet # Uses a custom network defined in flow.json +``` + +Requirements: + +- The network must exist in `flow.json` +- The network must have a valid `host` configured + +#### --fork-host + +- Type: `string` +- Default: `""` + +Directly specify a GRPC access node host. This bypasses the `flow.json` network lookup. + +```shell +flow test --fork-host access.mainnet.nodes.onflow.org:9000 +``` + +See public access node URLs in [Flow Networks](../../../protocol/flow-networks/index.md). + +#### --fork-height + +- Type: `uint64` +- Default: `0` + +Pin the fork to a specific block height for historical state testing. Only blocks from the current spork (since the most recent network upgrade) are available via public access nodes; earlier blocks are not accessible via public access nodes. + +```shell +flow test --fork mainnet --fork-height 85432100 +``` + +> Note: Historical data beyond spork boundaries is not available via standard access nodes. See the [Network Upgrade (Spork) Process](../../../protocol/node-ops/node-operation/network-upgrade.md). diff --git a/docs/tools/flow-cli/transactions/_category_.json b/docs/build/tools/flow-cli/transactions/_category_.json similarity index 100% rename from docs/tools/flow-cli/transactions/_category_.json rename to docs/build/tools/flow-cli/transactions/_category_.json diff --git a/docs/tools/flow-cli/transactions/build-transactions.md b/docs/build/tools/flow-cli/transactions/build-transactions.md similarity index 93% rename from docs/tools/flow-cli/transactions/build-transactions.md rename to docs/build/tools/flow-cli/transactions/build-transactions.md index 8184ff9c35..a257b26376 100644 --- a/docs/tools/flow-cli/transactions/build-transactions.md +++ b/docs/build/tools/flow-cli/transactions/build-transactions.md @@ -5,12 +5,13 @@ sidebar_position: 3 --- The Flow CLI provides a command to build a transactions with options to specify -authorizer accounts, payer account and proposer account. +authorizer accounts, payer account and proposer account. The `build` command doesn't produce any signatures and instead -is designed to be used with the `sign` and `send-signed` commands. +is designed to be used with the `sign` and `send-signed` commands. Use this functionality in the following order: + 1. Use this command (`build`) to build the transaction. 2. Use the `sign` command to sign with each account specified in the build process. 3. Use the `send-signed` command to submit the signed transaction to the Flow network. @@ -32,7 +33,7 @@ ID e8c0a69952fbe50a66703985e220307c8d44b8fa36c76cbca03f8c43d0167847 Payer e03daebed8ca0615 Authorizers [f3fcd2c1a78f5eee] -Proposal Key: +Proposal Key: Address 179b6b1cb6755e31 Index 0 Sequence 1 @@ -66,6 +67,7 @@ f9013df90138b8d17472616e...73616374696f6e286eeec0c0 ``` JSON arguments from a file example: + ```shell > flow transactions build tx1.cdc --args-json "$(cat args.json)" ``` @@ -81,12 +83,13 @@ The first argument is a path to a Cadence file containing the transaction to be executed. ### Arguments + - Name: `argument` - Valid inputs: valid [cadence values](https://cadencelang.dev/docs/1.0/json-cadence-spec) matching argument type in transaction code. Input arguments values matching corresponding types in the source code and passed in the same order. -For passing complex argument values see [send transaction](./send-transactions.md#example-usage) document. +For passing complex argument values see [send transaction](./send-transactions.md#example-usage) document. ## Flags @@ -97,7 +100,7 @@ For passing complex argument values see [send transaction](./send-transactions.m - Default: service account Specify account address that will be paying for the transaction. -Read more about payers [here](../../../build/basics/transactions.md). +Read more about payers [here](../../../cadence/basics/transactions.md). ### Proposer @@ -123,7 +126,7 @@ Specify key index for the proposer account. - Default: service account Additional authorizer addresses to add to the transaction. -Read more about authorizers [here](../../../build/basics/transactions.md). +Read more about authorizers [here](../../../cadence/basics/transactions.md). ### Arguments JSON @@ -137,11 +140,11 @@ Cadence JSON format contains `type` and `value` keys and is ### Gas Limit -- Flag: `--gas-limit` +- Flag: `--compute-limit` - Valid inputs: an integer greater than zero. - Default: `1000` -Specify the gas limit for this transaction. +Specify the compute unit (gas) limit for this transaction. ### Host @@ -224,4 +227,3 @@ files by using `-f` flag multiple times. - Default: `false` Skip version check during start up to speed up process for slow connections. - diff --git a/docs/tools/flow-cli/transactions/complex-transactions.md b/docs/build/tools/flow-cli/transactions/complex-transactions.md similarity index 81% rename from docs/tools/flow-cli/transactions/complex-transactions.md rename to docs/build/tools/flow-cli/transactions/complex-transactions.md index 605a2f086b..755d90078d 100644 --- a/docs/tools/flow-cli/transactions/complex-transactions.md +++ b/docs/build/tools/flow-cli/transactions/complex-transactions.md @@ -6,16 +6,17 @@ sidebar_position: 4 **Simple Transactions** -Sending a transaction using the Flow CLI can simply be +Sending a transaction using the Flow CLI can simply be achieved by using the [send command documented here](./send-transactions.md). **Complex Transactions** -If you would like to build more complex transactions the Flow CLI provides -commands to build, sign and send transactions allowing you to specify different -authorizers, signers and proposers. +If you would like to build more complex transactions the Flow CLI provides +commands to build, sign and send transactions allowing you to specify different +authorizers, signers and proposers. The process of sending a complex transactions includes three steps: + 1. [build a transaction](./build-transactions.md) 2. [sign the built transaction](./sign-transaction.md) 3. [send signed transaction](./send-signed-transactions.md) @@ -23,29 +24,38 @@ The process of sending a complex transactions includes three steps: Read more about each command flags and arguments in the above links. ## Examples + We will describe common examples for complex transactions. All examples are using an [example configuration](./complex-transactions.md#configuration). ### Single payer, proposer and authorizer + The simplest Flow transaction declares a single account as the proposer, payer and authorizer. Build the transaction: + ```shell -> flow transactions build tx.cdc - --proposer alice - --payer alice - --authorizer alice +> flow transactions build tx.cdc + --proposer alice + --payer alice + --authorizer alice --filter payload --save tx1 ``` + Sign the transaction: + ```shell -> flow transactions sign tx1 --signer alice +> flow transactions sign tx1 --signer alice --filter payload --save tx2 ``` + Submit the signed transaction: + ```shell > flow transactions send-signed tx2 ``` + Transaction content (`tx.cdc`): + ``` transaction { prepare(signer: &Account) {} @@ -54,36 +64,47 @@ transaction { ``` ### Single payer and proposer, multiple authorizers -A transaction that declares same payer and proposer but multiple authorizers each required to sign the transaction. Please note that the order of signing is important, and [the payer must sign last](../../../build/basics/transactions.md#payer-signs-last). + +A transaction that declares same payer and proposer but multiple authorizers each required to sign the transaction. Please note that the order of signing is important, and [the payer must sign last](../../../cadence/basics/transactions.md#payer-signs-last). Build the transaction: + ```shell -> flow transactions build tx.cdc +> flow transactions build tx.cdc --proposer alice --payer alice --authorizer bob - --authorizer charlie + --authorizer charlie --filter payload --save tx1 ``` + Sign the transaction with authorizers: + ```shell > flow transactions sign tx1 --signer bob --filter payload --save tx2 ``` + ```shell > flow transactions sign tx2 --signer charlie --filter payload --save tx3 ``` + Sign the transaction with payer: + ```shell > flow transactions sign tx3 --signer alice --filter payload --save tx4 ``` + Submit the signed transaction: + ```shell > flow transactions send-signed tx4 ``` + Transaction content (`tx.cdc`): + ``` transaction { prepare(bob: &Account, charlie: &Account) {} @@ -92,37 +113,49 @@ transaction { ``` ### Different payer, proposer and authorizer -A transaction that declares different payer, proposer and authorizer each signing separately. -Please note that the order of signing is important, and [the payer must sign last](../../../build/basics/transactions.md#payer-signs-last). + +A transaction that declares different payer, proposer and authorizer each signing separately. +Please note that the order of signing is important, and [the payer must sign last](../../../cadence/basics/transactions.md#payer-signs-last). Build the transaction: + ```shell -> flow transactions build tx.cdc - --proposer alice - --payer bob - --authorizer charlie +> flow transactions build tx.cdc + --proposer alice + --payer bob + --authorizer charlie --filter payload --save tx1 ``` + Sign the transaction with proposer: + ```shell -> flow transactions sign tx1 --signer alice +> flow transactions sign tx1 --signer alice --filter payload --save tx2 ``` + Sign the transaction with authorizer: + ```shell -> flow transactions sign tx2 --signer charlie +> flow transactions sign tx2 --signer charlie --filter payload --save tx3 ``` + Sign the transaction with payer: + ```shell -> flow transactions sign tx3 --signer bob +> flow transactions sign tx3 --signer bob --filter payload --save tx4 ``` + Submit the signed transaction: + ```shell > flow transactions send-signed tx4 ``` + Transaction content (`tx.cdc`): + ``` transaction { prepare(charlie: &Account) {} @@ -131,32 +164,41 @@ transaction { ``` ### Single payer, proposer and authorizer but multiple keys -A transaction that declares same payer, proposer and authorizer but the signer account has two keys with half weight, required to sign with both. +A transaction that declares same payer, proposer and authorizer but the signer account has two keys with half weight, required to sign with both. Build the transaction: + ```shell -> flow transactions build tx.cdc - --proposer dylan1 +> flow transactions build tx.cdc + --proposer dylan1 --payer dylan1 - --authorizer dylan1 + --authorizer dylan1 --filter payload --save tx1 ``` + Sign the transaction with the first key: + ```shell -> flow transactions sign tx1 --signer dylan1 +> flow transactions sign tx1 --signer dylan1 --filter payload --save tx2 ``` + Sign the transaction with the second key: + ```shell -> flow transactions sign tx2 --signer dylan2 +> flow transactions sign tx2 --signer dylan2 --filter payload --save tx3 ``` + Submit the signed transaction: + ```shell > flow transactions send-signed tx3 ``` + Transaction content (`tx.cdc`): + ``` transaction { prepare(signer: &Account) {} @@ -165,10 +207,12 @@ transaction { ``` ### Configuration + This is an example configuration using mock values: + ```json { - ... + ... "accounts": { "alice": { "address": "0x1", diff --git a/docs/tools/flow-cli/transactions/decode-transactions.md b/docs/build/tools/flow-cli/transactions/decode-transactions.md similarity index 100% rename from docs/tools/flow-cli/transactions/decode-transactions.md rename to docs/build/tools/flow-cli/transactions/decode-transactions.md diff --git a/docs/build/tools/flow-cli/transactions/get-system-transactions.md b/docs/build/tools/flow-cli/transactions/get-system-transactions.md new file mode 100644 index 0000000000..9e768a57c2 --- /dev/null +++ b/docs/build/tools/flow-cli/transactions/get-system-transactions.md @@ -0,0 +1,199 @@ +--- +title: Get a System Transaction +description: How to get a Flow system transaction from the command line +sidebar_position: 8 +keywords: + - flow cli + - transactions + - system transaction + - system chunk + - scheduled transactions + - forte upgrade + - blocks + - block id + - tx_id + - fee-events + - access api + - emulator + - testnet +--- + +The Flow CLI provides a command to fetch the system transaction for a given block reference. You can optionally provide a transaction ID to target a specific system transaction within that block. + +```shell +flow transactions get-system [tx_id] +``` + +::::warning + +Querying with a system transaction ID (`[tx_id]`) is part of the Forte network upgrade and is currently available on Flow Emulator (CLI v2.7.0+) and [Flow Testnet]. See the announcement for context: [Forte: Introducing Actions & Agents]. + +:::: + +## Use Cases + +- System chunk transaction for protocol operations: see [Epoch Scripts and Events] and [Staking rewards via system chunk]. +- Transactions related to scheduled transactions: see [Introduction to Scheduled Transactions]. Consider `--include fee-events` for scheduled transaction fee details. + +## Example Usage + +```shell +> flow transactions get-system latest --network mainnet + +Status ✅ SEALED +ID 40bc4b100c1930c61381c22e0f4c10a7f5827975ee25715527c1061b8d71e5aa +Payer — +Authorizers [] + +Proposal Key: — + +No Payload Signatures +No Envelope Signatures + +Events: + Index 0 + Type A.1654653399040a61.FlowToken.TokensDeposited + Tx ID 40bc4b100c1930c61381c22e0f4c10a7f5827975ee25715527c1061b8d71e5aa + Values + - amount (UFix64): 0.00100000 + - to ({}?): 5068e27f275c546c + +Code (hidden, use --include code) + +Payload (hidden, use --include payload) +``` + +Select a specific system transaction within the block by ID: + +```shell +> flow transactions get-system latest 07a8...b433 --network mainnet +``` + +## Arguments + +### Block Reference + +- Name: `` +- Valid Input: a block ID (hex), the keyword `latest`, or a block height (number). + +The first argument is a reference to the block whose system transaction you want to fetch. + +### Transaction ID (optional) + +- Name: `[tx_id]` +- Valid Input: a transaction ID (hex). + +Optionally narrow the result to a specific system transaction within the referenced block. + +## Flags + +### Include Fields + +- Flag: `--include` +- Valid inputs: `code`, `payload`, `signatures`, `fee-events` + +Specify fields to include in the result output. Applies only to the text output. + +### Exclude Fields + +- Flag: `--exclude` +- Valid inputs: `events` + +Specify fields to exclude from the result output. Applies only to the text output. + +### Host + +- Flag: `--host` +- Valid inputs: an IP address or host address. +- Default: `127.0.0.1:3569` (Flow Emulator) + +Specify the host address of the Access API that will be +used to execute the command. This flag overrides +any host defined by the `--network` flag. + +### Network Key + +- Flag: `--network-key` +- Valid inputs: A valid network public key of the host in hex string format + +Specify the network public key of the Access API that will be +used to create secure client connections when executing the command. + +### Network + +- Flag: `--network` +- Short Flag: `-n` +- Valid inputs: the name of a network defined in the configuration (`flow.json`) +- Default: `emulator` + +Specify which network you want the command to use for execution. + +### Filter + +- Flag: `--filter` +- Short Flag: `-x` +- Valid inputs: a case-sensitive name of the result property. + +Specify any property name from the result you want to return as the only value. + +### Output + +- Flag: `--output` +- Short Flag: `-o` +- Valid inputs: `json`, `inline` + +Specify the format of the command results. + +### Save + +- Flag: `--save` +- Short Flag: `-s` +- Valid inputs: a path in the current file system. + +Specify the filename where you want the result to be saved + +### Log + +- Flag: `--log` +- Short Flag: `-l` +- Valid inputs: `none`, `error`, `debug` +- Default: `info` + +Specify the log level. Control how much output you want to see during command execution. + +### Configuration + +- Flag: `--config-path` +- Short Flag: `-f` +- Valid inputs: a path in the current file system. +- Default: `flow.json` + +Specify the path to the `flow.json` configuration file. +You can use the `-f` flag multiple times to merge +several configuration files. + +### Version Check + +- Flag: `--skip-version-check` +- Default: `false` + +Skip version check during start up to speed up process for slow connections. + +## Notes + +System transactions currently cover: + +- System chunk transactions used by protocol operations. See an overview of system chunks and service events: [Epoch Scripts and Events]. +- Scheduled transaction execution. Learn more: [Introduction to Scheduled Transaction]. + +More resources: + +- [Staking rewards via system chunk] +- [Epoch schedule and system chunk transactions] + +[Forte: Introducing Actions & Agents]: https://flow.com/post/forte-introducing-actions-agents-supercharging-composability-and-automation +[Flow Testnet]: ../../../../protocol/flow-networks/accessing-testnet.md +[Epoch Scripts and Events]: ../../../../protocol/staking/05-epoch-scripts-events.md +[Staking rewards via system chunk]: ../../../../protocol/staking/08-staking-rewards.md +[Introduction to Scheduled Transactions]: ../../../../blockchain-development-tutorials/forte/scheduled-transactions/scheduled-transactions-introduction.md +[Epoch schedule and system chunk transactions]: ../../../../protocol/staking/03-schedule.md diff --git a/docs/tools/flow-cli/transactions/get-transactions.md b/docs/build/tools/flow-cli/transactions/get-transactions.md similarity index 100% rename from docs/tools/flow-cli/transactions/get-transactions.md rename to docs/build/tools/flow-cli/transactions/get-transactions.md diff --git a/docs/build/tools/flow-cli/transactions/profile-transactions.md b/docs/build/tools/flow-cli/transactions/profile-transactions.md new file mode 100644 index 0000000000..764932f0db --- /dev/null +++ b/docs/build/tools/flow-cli/transactions/profile-transactions.md @@ -0,0 +1,264 @@ +--- +title: Profile a Transaction +description: How to profile the computational performance of a Flow transaction +sidebar_position: 9 +keywords: + - flow cli + - transactions + - profiling + - performance + - optimization + - computation + - pprof + - gas optimization + - cadence profiling +--- + +The Flow CLI provides a command to profile the computational performance of sealed transactions on any Flow network. This diagnostic tool generates detailed CPU profiles in the industry-standard `pprof` format, allowing you to analyze exactly where computation is being spent during transaction execution. + +:::info +The command works by forking the blockchain state and replaying the transaction in an isolated environment, ensuring accurate profiling results that match the original execution. Learn more about state forking in the [Fork Testing guide](../fork-testing.md). +::: + +```shell +flow transactions profile --network [flags] +``` + +## Use Cases + +Transaction profiling helps developers: + +- **Optimize Transaction Costs**: Identify computational bottlenecks and optimize gas-heavy operations +- **Debug High Gas Usage**: Understand why a transaction consumed more computation than expected +- **Analyze Production Transactions**: Profile real transactions on mainnet or testnet to understand actual performance +- **Compare Implementations**: Evaluate different approaches by comparing their computational profiles +- **Find Performance Issues**: Trace computation usage through contract calls and dependencies + +## Example Usage + +Profile a mainnet transaction: + +```shell +> flow transactions profile 07a8...b433 --network mainnet + +Transaction Profiling Report +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Transaction ID: 07a8...b433 +Network: mainnet +Block Height: 12345678 +Status: SEALED +Events emitted: 5 +Computation: 1234 + +Profile saved: profile-07a8b433.pb.gz + +Analyze with: + go tool pprof -http=:8080 profile-07a8b433.pb.gz +``` + +Profile with custom output location: + +```shell +> flow transactions profile 0xabc123 --network testnet --output my-profile.pb.gz + +Profile saved: my-profile.pb.gz +``` + +Profile an emulator transaction: + +```shell +> flow transactions profile 0xdef456 --network emulator +``` + +## Analyzing Profile Data + +The generated `.pb.gz` file can be analyzed using Go's pprof tools. If you don't have Go installed, see the [Go installation guide](https://go.dev/doc/install). + +### Interactive Web Interface + +Open the profile in an interactive web interface: + +```bash +go tool pprof -http=:8080 profile-07a8b433.pb.gz +``` + +Then navigate to `http://localhost:8080` in your browser. + +The pprof web interface provides several visualization options: + +| View | Description | +|------|-------------| +| **Flame Graph** | Visual representation of call stacks with computation costs | +| **Graph** | Directed graph showing call relationships | +| **Top** | List of functions sorted by computation usage | +| **Source** | Source code annotated with computation costs | + +### Command-Line Analysis + +View top computation consumers: + +```bash +go tool pprof -top profile-07a8b433.pb.gz +``` + +List all functions with costs: + +```bash +go tool pprof -list=. profile-07a8b433.pb.gz +``` + +Generate a flame graph image: + +```bash +go tool pprof -png profile-07a8b433.pb.gz > profile.png +``` + +For comprehensive information on analyzing computation profiles, see the [Cadence Computation Profiling guide](../../../cadence/advanced-concepts/computation-profiling.md). + +## How It Works + +The profiling process: + +1. **Fetches the Transaction**: Retrieves the target sealed transaction by ID from the specified network +2. **Forks Blockchain State**: Creates a fork of the blockchain state from the block immediately before the transaction's block (uses the same forking mechanism as [Fork Testing](../fork-testing.md)) +3. **Replays Execution**: Replays all prior transactions in the same block to recreate the exact state +4. **Profiles Target Transaction**: Executes the target transaction with Cadence runtime profiling enabled +5. **Exports Profile**: Saves the profiling data to a pprof-compatible file + +This ensures the profile accurately reflects the transaction's execution in its original context. + +:::info +The transaction profiling command uses Flow's state forking capabilities under the hood to create an accurate execution environment. Learn more about state forking in the [Fork Testing guide](../fork-testing.md). +::: + +## Arguments + +### Transaction ID + +- Name: `` +- Valid Input: transaction ID (with or without `0x` prefix) + +The transaction ID to profile. The transaction must be sealed. + +## Flags + +### Network + +- Flag: `--network` +- Short Flag: `-n` +- Valid inputs: the name of a network defined in `flow.json` +- **Required** + +Specify which network the transaction was executed on (e.g., `mainnet`, `testnet`, `emulator`). + +### Output + +- Flag: `--output` +- Short Flag: `-o` +- Valid inputs: valid file path +- Default: `profile-{tx_id_prefix}.pb.gz` + +Custom output file path for the profile data. The file will be saved in compressed pprof format (`.pb.gz`). + +### Host + +- Flag: `--host` +- Valid inputs: an IP address or hostname +- Default: `127.0.0.1:3569` (Flow Emulator) + +Specify the hostname of the Access API that will be used to fetch transaction data. This flag overrides any host defined by the `--network` flag. + +### Network Key + +- Flag: `--network-key` +- Valid inputs: A valid network public key of the host in hex string format + +Specify the network public key of the Access API that will be used to create a secure GRPC client when executing the command. + +### Filter + +- Flag: `--filter` +- Short Flag: `-x` +- Valid inputs: a case-sensitive name of the result property + +Specify any property name from the result you want to return as the only value. + +### Output Format + +- Flag: `--output` +- Short Flag: `-o` +- Valid inputs: `json`, `inline` + +Specify the format of the command results displayed in the console. + +### Save + +- Flag: `--save` +- Short Flag: `-s` +- Valid inputs: a path in the current filesystem + +Specify the filename where you want the result summary to be saved. + +### Log + +- Flag: `--log` +- Short Flag: `-l` +- Valid inputs: `none`, `error`, `debug` +- Default: `info` + +Specify the log level. Control how much output you want to see during command execution. + +### Configuration + +- Flag: `--config-path` +- Short Flag: `-f` +- Valid inputs: a path in the current filesystem +- Default: `flow.json` + +Specify the path to the `flow.json` configuration file. + +### Version Check + +- Flag: `--skip-version-check` +- Default: `false` + +Skip version check during start up to speed up process for slow connections. + +## Requirements + +### Transaction Must Be Sealed + +Only sealed transactions can be profiled. Attempting to profile a pending or finalized transaction will result in an error. + +```shell +Error: transaction is not sealed (status: PENDING) +``` + +Wait for the transaction to be sealed before profiling, or use a different transaction. + +### Network Configuration + +The network must be properly configured in your `flow.json` file: + +```json +{ + "networks": { + "mainnet": "access.mainnet.nodes.onflow.org:9000", + "testnet": "access.devnet.nodes.onflow.org:9000" + } +} +``` + +### Go Toolchain (for analysis) + +To analyze the generated profile files, you need Go installed on your system. The `pprof` tool is included in the standard Go distribution. + +Install Go from: https://go.dev/doc/install + +## Related Documentation + +- **[Cadence Computation Profiling](../../../cadence/advanced-concepts/computation-profiling.md)** - Comprehensive guide on profiling and optimization +- **[Fork Testing Guide](../fork-testing.md)** - Learn more about the state forking capabilities used by this command +- **[Testing Strategy](../../../cadence/smart-contracts/testing-strategy.md)** - How profiling fits into your overall testing and optimization workflow +- **[Transaction Fees](../../../cadence/basics/fees.md)** - Understanding computation costs and fee optimization diff --git a/docs/tools/flow-cli/transactions/send-signed-transactions.md b/docs/build/tools/flow-cli/transactions/send-signed-transactions.md similarity index 100% rename from docs/tools/flow-cli/transactions/send-signed-transactions.md rename to docs/build/tools/flow-cli/transactions/send-signed-transactions.md diff --git a/docs/tools/flow-cli/transactions/send-transactions.md b/docs/build/tools/flow-cli/transactions/send-transactions.md similarity index 94% rename from docs/tools/flow-cli/transactions/send-transactions.md rename to docs/build/tools/flow-cli/transactions/send-transactions.md index c48ec7e25e..59cc81cff7 100644 --- a/docs/tools/flow-cli/transactions/send-transactions.md +++ b/docs/build/tools/flow-cli/transactions/send-transactions.md @@ -15,13 +15,13 @@ flow transactions send [ ...] [flags] ```shell > flow transactions send ./tx.cdc "Hello" - + Status ✅ SEALED ID b04b6bcc3164f5ee6b77fa502c3a682e0db57fc47e5b8a8ef3b56aae50ad49c8 Payer f8d6e0586b0a20c7 Authorizers [f8d6e0586b0a20c7] -Proposal Key: +Proposal Key: Address f8d6e0586b0a20c7 Index 0 Sequence 0 @@ -40,10 +40,13 @@ Payload (hidden, use --include payload) ``` Multiple arguments example: + ```shell > flow transactions send tx1.cdc Foo 1 2 10.9 0x1 '[123,222]' '["a","b"]' ``` + Transaction code: + ``` transaction(a: String, b: Int, c: UInt16, d: UFix64, e: Address, f: [Int], g: [String]) { prepare(authorizer: &Account) {} @@ -64,6 +67,7 @@ In the above example, the `flow.json` file would look something like this: ``` JSON arguments from a file example: + ```shell > flow transactions send tx1.cdc --args-json "$(cat args.json)" ``` @@ -71,6 +75,7 @@ JSON arguments from a file example: ## Arguments ### Code Filename + - Name: `code filename` - Valid inputs: Any filename and path valid on the system. @@ -78,8 +83,9 @@ The first argument is a path to a Cadence file containing the transaction to be executed. ### Arguments + - Name: `argument` -- Valid inputs: valid [cadence values](https://cadencelang.dev/docs/1.0/json-cadence-spec) +- Valid inputs: valid [cadence values](https://cadencelang.dev/docs/1.0/json-cadence-spec) matching argument type in transaction code. Input arguments values matching corresponding types in the source code and passed in the same order. @@ -98,13 +104,13 @@ Specify fields to include in the result output. Applies only to the text output. - Flag: `--code` -⚠️ No longer supported: use filename argument. +⚠️ No longer supported: use filename argument. ### Results - Flag: `--results` -⚠️ No longer supported: all transactions will provide result. +⚠️ No longer supported: all transactions will provide result. ### Exclude Fields @@ -148,16 +154,16 @@ Specify the name of the account(s) that will be used as authorizer(s) in the tra - Example: `flow transactions send ./tx.cdc '[{"type": "String", "value": "Hello World"}]'` Arguments passed to the Cadence transaction in Cadence JSON format. -Cadence JSON format contains `type` and `value` keys and is +Cadence JSON format contains `type` and `value` keys and is [documented here](https://cadencelang.dev/docs/1.0/json-cadence-spec). -### Gas Limit +### Compute Limit -- Flag: `--gas-limit` +- Flag: `--compute-limit` - Valid inputs: an integer greater than zero. - Default: `1000` -Specify the gas limit for this transaction. +Specify the compute unit (gas) limit for this transaction. ### Host diff --git a/docs/tools/flow-cli/transactions/sign-transaction.md b/docs/build/tools/flow-cli/transactions/sign-transaction.md similarity index 100% rename from docs/tools/flow-cli/transactions/sign-transaction.md rename to docs/build/tools/flow-cli/transactions/sign-transaction.md diff --git a/docs/tools/flow-cli/utils/_category_.json b/docs/build/tools/flow-cli/utils/_category_.json similarity index 100% rename from docs/tools/flow-cli/utils/_category_.json rename to docs/build/tools/flow-cli/utils/_category_.json diff --git a/docs/tools/flow-cli/utils/signature-generate.md b/docs/build/tools/flow-cli/utils/signature-generate.md similarity index 100% rename from docs/tools/flow-cli/utils/signature-generate.md rename to docs/build/tools/flow-cli/utils/signature-generate.md diff --git a/docs/tools/flow-cli/utils/signature-verify.md b/docs/build/tools/flow-cli/utils/signature-verify.md similarity index 100% rename from docs/tools/flow-cli/utils/signature-verify.md rename to docs/build/tools/flow-cli/utils/signature-verify.md diff --git a/docs/tools/flow-cli/utils/snapshot-save.md b/docs/build/tools/flow-cli/utils/snapshot-save.md similarity index 100% rename from docs/tools/flow-cli/utils/snapshot-save.md rename to docs/build/tools/flow-cli/utils/snapshot-save.md diff --git a/docs/tools/flow-cli/utils/tools.md b/docs/build/tools/flow-cli/utils/tools.md similarity index 100% rename from docs/tools/flow-cli/utils/tools.md rename to docs/build/tools/flow-cli/utils/tools.md diff --git a/docs/tools/flow-dev-wallet/index.md b/docs/build/tools/flow-dev-wallet/index.md similarity index 96% rename from docs/tools/flow-dev-wallet/index.md rename to docs/build/tools/flow-dev-wallet/index.md index 2d7342747b..bac494585b 100644 --- a/docs/tools/flow-dev-wallet/index.md +++ b/docs/build/tools/flow-dev-wallet/index.md @@ -22,7 +22,7 @@ other instances of Flow. :::info -To see a full list of Flow compatible wallets visit [Wallets page](../../ecosystem/wallets.md) +To see a full list of Flow compatible wallets visit [Wallets page](../../../ecosystem/wallets.md) ::: @@ -50,9 +50,11 @@ Start the Emulator and deploy the contracts by running the following command fro flow emulator start flow project deploy --network emulator ``` -### Start the Dev Wallet -In a separate terminal session, start the dev wallet service. +### Start the Dev Wallet + +In a separate terminal session, start the dev wallet service. + ```sh flow dev-wallet ``` @@ -233,6 +235,6 @@ Releasing a new version of Dev Wallet is as simple as tagging and creating a rel Additionally, consider exploring these resources: -- [Guide to Creating a Fungible Token on Flow](../../build/guides/fungible-token.md) +- [Guide to Creating a Fungible Token on Flow](../../../blockchain-development-tutorials/tokens/fungible-token-cadence.md) - [Tutorial on Fungible Tokens](https://cadence-lang.org/docs/tutorial/fungible-tokens) -- [Faucets](../../ecosystem/faucets.md) +- [Faucets](../../../ecosystem/faucets.md) diff --git a/docs/build/tools/index.mdx b/docs/build/tools/index.mdx new file mode 100644 index 0000000000..a84a35c9b6 --- /dev/null +++ b/docs/build/tools/index.mdx @@ -0,0 +1,191 @@ +--- +sidebar_position: 12 +title: Tools +description: Essential tools for the Flow blockchain ecosystem +--- + +import DocCardList from '@theme/DocCardList'; + +# Tools & SDKs + +Flow provides a comprehensive suite of development tools to help you build, test, and deploy applications on the blockchain. + +## Which Tool Should I Use? + +| I want to... | Use this | +|--------------|----------| +| Build a React frontend | [React SDK](./react-sdk/index.mdx) | +| Build with vanilla JS/TypeScript | [FCL-JS](./clients/fcl-js/index.md) | +| Build a Go backend | [Flow Go SDK](./clients/flow-go-sdk/index.md) | +| Develop and test locally | [Flow CLI](./flow-cli/index.md) + [Emulator](./emulator/index.md) | +| Write and debug Cadence | [VS Code Extension](./vscode-extension/index.md) | +| Simulate wallet interactions | [Flow Dev Wallet](./flow-dev-wallet/index.md) | +| Build a wallet provider | [Wallet Provider Spec](./wallet-provider-spec/index.md) | + +## Core Tools + + + +## Community Tools + +Tools built by the Flow community to enhance your development experience. + + diff --git a/docs/build/tools/react-native-sdk/components.md b/docs/build/tools/react-native-sdk/components.md new file mode 100644 index 0000000000..49d9c8baaa --- /dev/null +++ b/docs/build/tools/react-native-sdk/components.md @@ -0,0 +1,106 @@ +--- +title: 'Components' +description: Reusable UI components for Flow interactions in React Native. +sidebar_position: 3 +--- + +## Connect + +A drop-in wallet connection component that handles the entire authentication flow. When disconnected, it displays a "Connect Wallet" button. When connected, it shows the user's address and opens a Profile modal on press. + +**Props:** + +- `onConnect?: () => void` – Callback triggered after successful authentication +- `onDisconnect?: () => void` – Callback triggered after logout +- `balanceType?: "cadence" | "evm" | "combined"` – Specifies which balance to display (default: `"cadence"`) + - `"cadence"`: Shows the token balance from the Cadence side + - `"evm"`: Shows the token balance from the Flow EVM side + - `"combined"`: Shows the total combined token balance from both sides +- `balanceTokens?: TokenConfig[]` – Optional array of token configurations to display in the balance selector +- `modalEnabled?: boolean` – Whether to show the profile modal on press when connected (default: `true`) + +**Basic Usage:** + +The simplest way to add wallet connection to your app: + +```tsx +import { View, Text } from "react-native"; +import { Connect } from "@onflow/react-native-sdk"; + +function WalletSection() { + return ( + + Connect Wallet + Connect your Flow wallet to interact with the blockchain. + + + ); +} +``` + +**With Callbacks:** + +```tsx +import { Connect } from "@onflow/react-native-sdk"; + + console.log("Wallet connected!")} + onDisconnect={() => console.log("Wallet disconnected")} +/> +``` + +**With Balance Display:** + +```tsx +import { Connect } from "@onflow/react-native-sdk"; + + +``` + +--- + +## Profile + +A standalone component for displaying wallet information including account address and balance. Use this when you want to show user details separately from the Connect button. + +**Props:** + +- `onDisconnect?: () => void` – Callback triggered when the user presses the disconnect button +- `balanceType?: "cadence" | "evm" | "combined"` – Specifies which balance to display (default: `"cadence"`) + - `"cadence"`: Shows the token balance from the Cadence side + - `"evm"`: Shows the token balance from the Flow EVM side + - `"combined"`: Shows the total combined token balance from both sides +- `balanceTokens?: TokenConfig[]` – Optional array of token configurations to display in the balance selector + +**Usage:** + +```tsx +import { View } from "react-native"; +import { Profile, useFlowCurrentUser } from "@onflow/react-native-sdk"; + +function UserProfile() { + const { user } = useFlowCurrentUser(); + + if (!user?.loggedIn) { + return null; + } + + return ( + + console.log("User disconnected")} + /> + + ); +} +``` diff --git a/docs/build/tools/react-native-sdk/hooks.md b/docs/build/tools/react-native-sdk/hooks.md new file mode 100644 index 0000000000..b76eda352d --- /dev/null +++ b/docs/build/tools/react-native-sdk/hooks.md @@ -0,0 +1,1465 @@ +--- +title: 'Hooks' +description: React hooks for interacting with the Flow blockchain in React Native. +sidebar_position: 2 +--- + +:::info + +Many of these hooks are built using [`@tanstack/react-query`](https://tanstack.com/query/latest), which provides powerful caching, revalidation, and background refetching features. As a result, you'll see return types like `UseQueryResult` and `UseMutationResult` throughout this section. Other types—such as `Account`, `Block`, and `CurrentUser`—are from the [Flow Client Library (FCL) TypeDefs](https://github.com/onflow/fcl-js/blob/master/packages/typedefs/src/index.ts). Refer to their respective documentation for full type definitions and usage patterns. + +::: + +## Cadence Hooks + +### `useFlowCurrentUser` + +```tsx +import { useFlowCurrentUser } from "@onflow/react-native-sdk" +``` + +#### Parameters + +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: + +- `user: CurrentUser` – The current user object from FCL +- `authenticate: () => Promise` – Triggers wallet authentication +- `unauthenticate: () => void` – Logs the user out + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function AuthComponent() { + const { user, authenticate, unauthenticate } = useFlowCurrentUser() + + return ( + + {user?.loggedIn ? ( + + Logged in as {user?.addr} + + Logout + + + ) : ( + + Login + + )} + + ) +} +``` + +--- + +### `useFlowAccount` + +```tsx +import { useFlowAccount } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `address?: string` – Flow address (with or without `0x` prefix) +- `query?: UseQueryOptions` – Optional TanStackQuery options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function AccountDetails() { + const { data: account, isLoading, error, refetch } = useFlowAccount({ + address: "0x1cf0e2f2f715450", + query: { staleTime: 5000 }, + }) + + if (isLoading) return Loading account... + if (error) return Error fetching account: {error.message} + if (!account) return No account data + + return ( + + Account: {account.address} + Balance: {account.balance} + refetch()}> + Refetch + + + ) +} +``` + +--- + +### `useFlowBlock` + +```tsx +import { useFlowBlock } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `sealed?: boolean` – If `true`, fetch latest sealed block +- `id?: string` – Block by ID +- `height?: number` – Block by height +- `query?: UseQueryOptions` – Optional TanStackQuery options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +Only one of `sealed`, `id`, or `height` should be provided. + +#### Returns: `UseQueryResult` + +```tsx +import { View, Text } from 'react-native'; + +function LatestBlock() { + const { data: block, isLoading, error } = useFlowBlock({ query: { staleTime: 10000 } }) + + if (isLoading) return Loading... + if (error) return Error: {error.message} + if (!block) return No block data. + + return ( + + Block {block.height} + ID: {block.id} + + ) +} +``` + +--- + +### `useFlowChainId` + +```tsx +import { useFlowChainId } from "@onflow/react-native-sdk" +``` + +This hook retrieves the Flow chain ID, which is useful for identifying the current network. + +#### Parameters: + +- `query?: Omit, "queryKey" | "queryFn">` – Optional TanStack Query options like `staleTime`, `enabled`, etc. +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +Valid chain IDs include: `testnet` (Flow Testnet), `mainnet` (Flow Mainnet), and `emulator` (Flow Emulator). The `flow-` prefix will be stripped from the chain ID returned by the access node (e.g. `flow-testnet` will return `testnet`). + +```tsx +import { View, Text } from 'react-native'; + +function ChainIdExample() { + const { data: chainId, isLoading, error } = useFlowChainId({ + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading chain ID... + if (error) return Error fetching chain ID: {error.message} + + return Current Flow Chain ID: {chainId} +} +``` + +--- + +### `useFlowClient` + +This hook returns the `FlowClient` for the current `` context. + +#### Parameters: + +- `flowClient?: FlowClient` - Optional `FlowClient` instance to override the result + +--- + +### `useFlowConfig` + +```tsx +import { useFlowConfig } from "@onflow/react-native-sdk" +``` + +#### Returns: `FlowConfig` + +```tsx +import { View, Text } from 'react-native'; + +function MyComponent() { + const config = useFlowConfig() + + return ( + + Current network: {config.flowNetwork} + Current access node: {config.accessNodeUrl} + + ) +} +``` + +--- + +### `useFlowEvents` + +```tsx +import { useFlowEvents } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `startBlockId?: string` – Optional ID of the block to start listening from +- `startHeight?: number` – Optional block height to start listening from +- `eventTypes?: string[]` – Array of event type strings (e.g., `A.0xDeaDBeef.Contract.EventName`) +- `addresses?: string[]` – Filter by Flow addresses +- `contracts?: string[]` – Filter by contract identifiers +- `opts?: { heartbeatInterval?: number }` – Options for subscription heartbeat +- `onEvent: (event: Event) => void` – Callback for each event received +- `onError?: (error: Error) => void` – Optional error handler +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Example: + +```tsx +import { View, Text } from 'react-native'; + +function EventListener() { + useFlowEvents({ + eventTypes: ["A.0xDeaDBeef.SomeContract.SomeEvent"], + onEvent: (event) => console.log("New event:", event), + onError: (error) => console.error("Error:", error), + }) + + return Listening for events... +} +``` + +--- + +### `useFlowQuery` + +```tsx +import { useFlowQuery } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `cadence: string` – Cadence script to run +- `args?: (arg, t) => unknown[]` – Function returning FCL arguments +- `query?: UseQueryOptions` – Optional TanStackQuery options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function QueryExample() { + const { data, isLoading, error, refetch } = useFlowQuery({ + cadence: ` + access(all) + fun main(a: Int, b: Int): Int { + return a + b + } + `, + args: (arg, t) => [arg(1, t.Int), arg(2, t.Int)], + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading query... + if (error) return Error: {error.message} + + return ( + + Result: {data} + refetch()}> + Refetch + + + ) +} +``` + +--- + +### `useFlowQueryRaw` + +```tsx +import { useFlowQueryRaw } from "@onflow/react-native-sdk" +``` + +This hook is identical to `useFlowQuery` but returns the raw, non-decoded response data from the Flow blockchain. This is useful when you need access to the original response structure or want to handle decoding manually. + +#### Parameters: + +- `cadence: string` – Cadence script to run +- `args?: (arg, t) => unknown[]` – Function returning FCL arguments +- `query?: UseQueryOptions` – Optional TanStackQuery options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +The returned data will be in its raw, non-decoded format as received from the Flow access node. + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function QueryRawExample() { + const { data: rawData, isLoading, error, refetch } = useFlowQueryRaw({ + cadence: ` + access(all) + fun main(a: Int, b: Int): Int { + return a + b + } + `, + args: (arg, t) => [arg(1, t.Int), arg(2, t.Int)], + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading query... + if (error) return Error: {error.message} + + return ( + + Raw Result: {JSON.stringify(rawData, null, 2)} + refetch()}> + Refetch + + + ) +} +``` + +--- + +### `useFlowMutate` + +```tsx +import { useFlowMutate } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseMutationResult` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; +import * as fcl from '@onflow/fcl'; + +function CreatePage() { + const { mutate, isPending, error, data: txId } = useFlowMutate({ + mutation: { + onSuccess: (txId) => console.log("TX ID:", txId), + }, + }) + + const sendTransaction = () => { + mutate({ + cadence: `transaction() { + prepare(acct: &Account) { + log(acct.address) + } + }`, + args: (arg, t) => [], + proposer: fcl.currentUser, + payer: fcl.currentUser, + authorizations: [], + limit: 100, + }) + } + + return ( + + + Send Transaction + + {isPending && Sending transaction...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useFlowRevertibleRandom` + +```tsx +import { useFlowRevertibleRandom } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `min?: string` – Minimum random value (inclusive), as a UInt256 decimal string. Defaults to `"0"`. +- `max: string` – Maximum random value (inclusive), as a UInt256 decimal string. **Required**. +- `count?: number` – Number of random values to fetch (must be at least 1). Defaults to `1`. +- `query?: Omit, "queryKey" | "queryFn">` – Optional TanStack Query settings like `staleTime`, `enabled`, `retry`, etc. +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +Each `RevertibleRandomResult` includes: + +- `blockHeight: string` — The block height from which the random value was generated. +- `value: string` — The random UInt256 value, returned as a decimal string. + +```tsx +import { View, Text, TouchableOpacity, FlatList } from 'react-native'; + +function RandomValues() { + const { data: randoms, isLoading, error, refetch } = useFlowRevertibleRandom({ + min: "0", + max: "1000000000000000000000000", + count: 3, + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading random numbers... + if (error) return Error fetching random numbers: {error.message} + if (!randoms) return No random values generated. + + return ( + + Generated Random Numbers + idx.toString()} + renderItem={({ item }) => ( + Block {item.blockHeight}: {item.value} + )} + /> + refetch()}> + Regenerate + + + ) +} +``` + +#### Notes: + +* Randomness is generated using the **onchain `revertibleRandom`** function on Flow, producing pseudorandom values tied to block and script execution. +* Values are **deterministic**: The values returned for identical calls within the same block will be identical. +* If `count` is larger than one, the returned values are distinct. +* This hook is designed for simple use cases that don't require unpredictability, such as randomized UIs. + Since the hook uses script executions on existing blocks, the random source is already public and the randoms are predictable. +* For **more advanced use cases** that **do** require onchain randomness logic via transactions, Flow provides built-in support using Cadence's `revertibleRandom` and [commit-reveal scheme]. + +[commit-reveal scheme]: ../../cadence/advanced-concepts/randomness#commit-reveal-scheme + +--- + +### `useFlowTransaction` + +```tsx +import { useFlowTransaction } from "@onflow/react-native-sdk" +``` + +Fetches a Flow transaction by ID and returns the decoded transaction object. + +#### Parameters: + +* `txId?: string` – The Flow transaction ID or scheduled transaction ID to fetch. +* `query?: Omit, "queryKey" | "queryFn">` – Optional TanStack Query options like `staleTime`, `enabled`, etc. +* `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function TransactionDetails({ txId }: { txId: string }) { + const { data: transaction, isLoading, error, refetch } = useFlowTransaction({ + txId, + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading transaction... + if (error) return Error fetching transaction: {error.message} + if (!transaction) return No transaction data. + + return ( + + Transaction ID: {transaction.id} + Gas Limit: {transaction.gasLimit} + Arguments: {JSON.stringify(transaction.arguments, null, 2)} + refetch()}> + Refetch + + + ) +} +``` + +--- + +### `useFlowTransactionStatus` + +```tsx +import { useFlowTransactionStatus } from "@onflow/react-native-sdk" +``` + +#### Parameters: + +- `id: string` – Transaction ID or scheduled transaction ID to subscribe to +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: + +- `transactionStatus: TransactionStatus | null` +- `error: Error | null` + +```tsx +import { View, Text } from 'react-native'; + +function TransactionStatusComponent() { + const txId = "your-transaction-id-here" + const { transactionStatus, error } = useFlowTransactionStatus({ id: txId }) + + if (error) return Error: {error.message} + + return Status: {transactionStatus?.statusString} +} +``` + +--- + +### `useFlowNftMetadata` + +```tsx +import { useFlowNftMetadata } from "@onflow/react-native-sdk" +``` + +This hook fetches NFT metadata including display information, traits, rarity, and collection details. + +#### Parameters: + +- `accountAddress?: string` – Flow address of the account holding the NFT +- `tokenId?: string | number` – The NFT token ID +- `publicPathIdentifier?: string` – Public path identifier for the collection +- `query?: UseQueryOptions` – Optional TanStack Query options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +Where `NftViewResult` is defined as: + +```typescript +interface NftViewResult { + name: string + description: string + thumbnailUrl: string + externalUrl?: string + collectionName?: string + collectionExternalUrl?: string + tokenID: string + traits?: Record + rarity?: string + serialNumber?: string +} +``` + +```tsx +import { View, Text, Image, FlatList } from 'react-native'; + +function NftMetadataExample() { + const { data: nft, isLoading, error } = useFlowNftMetadata({ + accountAddress: "0x1cf0e2f2f715450", + tokenId: "123", + publicPathIdentifier: "exampleNFTCollection", + query: { staleTime: 60000 }, + }) + + if (isLoading) return Loading NFT metadata... + if (error) return Error: {error.message} + if (!nft) return NFT not found + + return ( + + {nft.name} + + {nft.description} + {nft.collectionName && Collection: {nft.collectionName}} + {nft.rarity && Rarity: {nft.rarity}} + {nft.traits && ( + + Traits: + {Object.entries(nft.traits).map(([key, value]) => ( + {key}: {value} + ))} + + )} + + ) +} +``` + +--- + +### `useFlowAuthz` + +```tsx +import { useFlowAuthz } from "@onflow/react-native-sdk" +``` + +A React hook that returns an authorization function for Flow transactions. If no custom authorization is provided, it returns the current user's wallet authorization. + +#### Parameters: + +- `authz?: AuthorizationFunction` – Optional custom authorization function +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +Where `AuthorizationFunction` is defined as: + +```typescript +type AuthorizationFunction = ( + account: Partial +) => Partial | Promise> +``` + +#### Returns: `AuthorizationFunction` + +The authorization function is compatible with Flow transactions' authorizations parameter. + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; +import * as fcl from '@onflow/fcl'; + +// Example 1: Using current user authorization +function CurrentUserAuthExample() { + const authorization = useFlowAuthz() + + const sendTransaction = async () => { + const txId = await fcl.mutate({ + cadence: ` + transaction { + prepare(signer: auth(Storage) &Account) { + log(signer.address) + } + } + `, + authorizations: [authorization], + limit: 100, + }) + console.log("Transaction ID:", txId) + } + + return ( + + Send Transaction + + ) +} +``` + +```tsx +// Example 2: Using custom authorization function +function CustomAuthExample() { + const customAuthz = (account) => ({ + ...account, + addr: "0xCUSTOMOADDRESS", + keyId: 0, + signingFunction: async (signable) => ({ + signature: "0x...", + }), + }) + + const authorization = useFlowAuthz({ authz: customAuthz }) + + const sendTransaction = async () => { + const txId = await fcl.mutate({ + cadence: ` + transaction { + prepare(signer: auth(Storage) &Account) { + log(signer.address) + } + } + `, + authorizations: [authorization], + limit: 100, + }) + console.log("Transaction ID:", txId) + } + + return ( + + Send Custom Auth Transaction + + ) +} +``` + +--- + +### `useFlowScheduledTransaction` + +```tsx +import { useFlowScheduledTransaction } from "@onflow/react-native-sdk" +``` + +Fetches a scheduled transaction by ID. + +#### Parameters: + +- `txId?: string` – Scheduled transaction ID +- `includeHandlerData?: boolean` – Include handler data (default: false) +- `query?: UseQueryOptions` – Optional TanStack Query options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +Where `ScheduledTransaction` is defined as: + +```typescript +interface ScheduledTransaction { + id: string + priority: ScheduledTransactionPriority // 0 = Low, 1 = Medium, 2 = High + executionEffort: bigint + status: ScheduledTransactionStatus // 0 = Pending, 1 = Processing, 2 = Completed, 3 = Failed, 4 = Cancelled + fees: { + value: bigint + formatted: string + } + scheduledTimestamp: number + handlerTypeIdentifier: string + handlerAddress: string + handlerUUID?: string // Only included if includeHandlerData is true + handlerResolvedViews?: {[viewType: string]: any} // Only included if includeHandlerData is true +} +``` + +```tsx +import { View, Text } from 'react-native'; + +function ScheduledTransactionDetails({ txId }: { txId: string }) { + const { data: transaction, isLoading, error } = useFlowScheduledTransaction({ + txId, + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading scheduled transaction... + if (error) return Error: {error.message} + if (!transaction) return Transaction not found + + return ( + + Scheduled Transaction #{transaction.id} + Status: {transaction.status} + Priority: {transaction.priority} + Fees: {transaction.fees.formatted} FLOW + Handler: {transaction.handlerTypeIdentifier} + + ) +} +``` + +--- + +### `useFlowScheduledTransactionList` + +```tsx +import { useFlowScheduledTransactionList } from "@onflow/react-native-sdk" +``` + +Lists all scheduled transactions for an account. + +#### Parameters: + +- `account?: string` – Flow address to query +- `includeHandlerData?: boolean` – Include handler data (default: false) +- `query?: UseQueryOptions` – Optional TanStack Query options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +```tsx +import { View, Text, TouchableOpacity, FlatList } from 'react-native'; + +function ScheduledTransactionsList({ account }: { account: string }) { + const { data: transactions, isLoading, error, refetch } = useFlowScheduledTransactionList({ + account, + query: { staleTime: 10000 }, + }) + + if (isLoading) return Loading scheduled transactions... + if (error) return Error: {error.message} + if (!transactions || transactions.length === 0) return No scheduled transactions + + return ( + + Scheduled Transactions for {account} + refetch()}> + Refresh + + tx.id} + renderItem={({ item: tx }) => ( + + Transaction #{tx.id} - Status: {tx.status} - Fees: {tx.fees.formatted} FLOW + + )} + /> + + ) +} +``` + +--- + +### `useFlowScheduledTransactionCancel` + +```tsx +import { useFlowScheduledTransactionCancel } from "@onflow/react-native-sdk" +``` + +Cancels a scheduled transaction and refunds fees. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStack Query mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseFlowScheduledTransactionCancelResult` + +Where `UseFlowScheduledTransactionCancelResult` is defined as: + +```typescript +interface UseFlowScheduledTransactionCancelResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + cancelTransaction: (txId: string) => void + cancelTransactionAsync: (txId: string) => Promise +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function CancelScheduledTransaction() { + const { cancelTransactionAsync, isPending, error, data: txId } = useFlowScheduledTransactionCancel({ + mutation: { + onSuccess: (txId) => console.log("Cancel transaction ID:", txId), + }, + }) + + const handleCancel = async (scheduledTxId: string) => { + try { + const resultTxId = await cancelTransactionAsync(scheduledTxId) + console.log("Successfully canceled scheduled transaction:", resultTxId) + } catch (error) { + console.error("Failed to cancel:", error) + } + } + + return ( + + handleCancel("42")} disabled={isPending}> + Cancel Scheduled Transaction #42 + + {isPending && Canceling transaction...} + {error && Error: {error.message}} + {txId && Cancel Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useFlowScheduledTransactionSetup` + +```tsx +import { useFlowScheduledTransactionSetup } from "@onflow/react-native-sdk" +``` + +Sets up the Transaction Scheduler Manager resource. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStack Query mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseFlowScheduledTransactionSetupResult` + +Where `UseFlowScheduledTransactionSetupResult` is defined as: + +```typescript +interface UseFlowScheduledTransactionSetupResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + setup: () => void + setupAsync: () => Promise +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function SchedulerSetup() { + const { setupAsync, isPending, error, data: txId } = useFlowScheduledTransactionSetup({ + mutation: { + onSuccess: (txId) => console.log("Setup transaction ID:", txId), + }, + }) + + const handleSetup = async () => { + try { + const resultTxId = await setupAsync() + console.log("Scheduler setup successful:", resultTxId) + } catch (error) { + console.error("Setup failed:", error) + } + } + + return ( + + + Setup Transaction Scheduler + + {isPending && Setting up scheduler...} + {error && Error: {error.message}} + {txId && Setup Transaction ID: {txId}} + + ) +} +``` + +--- + +## Cross-VM Hooks + +### `useCrossVmBatchTransaction` + +```tsx +import { useCrossVmBatchTransaction } from "@onflow/react-native-sdk" +``` + +This hook allows you to execute multiple EVM transactions in a single atomic Cadence transaction. It is useful for batch processing EVM calls while ensuring they are executed together, either all succeeding or allowing for some to fail without affecting the others. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBatchTransactionResult` + +Where `UseCrossVmBatchTransactionResult` is defined as: + +```typescript +interface UseCrossVmBatchTransactionResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + mutate: (calls: UseCrossVmBatchTransactionMutateArgs) => void + mutateAsync: (calls: UseCrossVmBatchTransactionMutateArgs) => Promise +} +``` + +Where `UseCrossVmBatchTransactionMutateArgs` is defined as: + +```typescript +interface UseCrossVmBatchTransactionMutateArgs { + calls: EvmBatchCall[] + mustPass?: boolean +} +``` + +Where `EvmBatchCall` is defined as: + +```typescript +interface EvmBatchCall { + // The target EVM contract address (as a string) + address: string + // The contract ABI fragment + abi: Abi + // The name of the function to call + functionName: string + // The function arguments + args?: readonly unknown[] + // The gas limit for the call + gasLimit?: bigint + // The value to send with the call + value?: bigint +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function CrossVmBatchTransactionExample() { + const { sendBatchTransaction, isPending, error, data: txId } = useCrossVmBatchTransaction({ + mutation: { + onSuccess: (txId) => console.log("TX ID:", txId), + }, + }) + + const sendTransaction = () => { + const calls = [ + { + address: "0x1234567890abcdef", + abi: { + // ABI definition for the contract + }, + functionName: "transfer", + args: ["0xabcdef1234567890", 100n], + gasLimit: 21000n, + }, + ] + + sendBatchTransaction({calls}) + } + + return ( + + + Send Cross-VM Transaction + + {isPending && Sending transaction...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useCrossVmTokenBalance` + +```tsx +import { useCrossVmTokenBalance } from "@onflow/react-native-sdk" +``` + +Fetch the balance of a token balance for a given user across both Cadence and EVM environments. + +#### Parameters: + +- `owner: string` – Cadence address of the account whose token balances you want. +- `vaultIdentifier?: string` – Optional Cadence resource identifier (e.g. "0x1cf0e2f2f715450.FlowToken.Vault") for onchain balance +- `erc20AddressHexArg?: string` – Optional bridged ERC-20 contract address (hex) for EVM/COA balance +- `query?: Omit, "queryKey" | "queryFn">` – Optional TanStack Query config (e.g. staleTime, enabled) +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +> **Note:** You must pass `owner`, and one of `vaultIdentifier` or `erc20AddressHexArg`. + +#### Returns: `UseQueryResult` + +Where `UseCrossVmTokenBalanceData` is defined as: + +```typescript +interface UseCrossVmTokenBalanceData { + cadence: TokenBalance // Token balance of Cadence vault + evm: TokenBalance // Token balance of EVM (COA stored in /storage/coa) + combined: TokenBalance // Combined balance of both Cadence and EVM +} +``` + +Where `TokenBalance` is defined as: + +```typescript +interface TokenBalance { + value: bigint // Balance value in smallest unit + formatted: string // Formatted balance string (e.g. "123.45") + precision: number // Number of decimal places for the token +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function UseCrossVmTokenBalanceExample() { + const { data, isLoading, error, refetch } = useCrossVmTokenBalance({ + owner: '0x1e4aa0b87d10b141', + vaultIdentifier: 'A.1654653399040a61.FlowToken.Vault', + query: { staleTime: 10000 }, + }); + + if (isLoading) return Loading token balance... + if (error) return Error fetching token balance: {error.message} + + return ( + + Token Balances + Cadence Balance: {data.cadence.formatted} (Value: {data.cadence.value.toString()}) + EVM Balance: {data.evm.formatted} (Value: {data.evm.value.toString()}) + Combined Balance: {data.combined.formatted} (Value: {data.combined.value.toString()}) + refetch()}> + Refetch + + + ) +} +``` + +--- + +### `useCrossVmTransactionStatus` + +```tsx +import { useCrossVmTransactionStatus } from "@onflow/react-native-sdk" +``` + +Subscribes to status updates for a given Cross-VM Flow transaction ID that executes EVM calls. This hook monitors the transaction status and extracts EVM call results if available. + +#### Parameters: + +- `id?: string` – Optional Flow transaction ID to monitor +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmTransactionStatusResult` + +Where `UseCrossVmTransactionStatusResult` is defined as: + +```typescript +interface UseCrossVmTransactionStatusResult { + transactionStatus: TransactionStatus | null // Latest transaction status, or null before any update + evmResults?: CallOutcome[] // EVM transaction results, if available + error: Error | null // Any error encountered during status updates +} +``` + +Where `CallOutcome` is defined as: + +```typescript +interface CallOutcome { + status: "passed" | "failed" | "skipped" // Status of the EVM call + hash?: string // EVM transaction hash if available + errorMessage?: string // Error message if the call failed +} +``` + +```tsx +import { View, Text, FlatList } from 'react-native'; + +function CrossVmTransactionStatusComponent() { + const txId = "your-cross-vm-transaction-id-here" + const { transactionStatus, evmResults, error } = useCrossVmTransactionStatus({ id: txId }) + + if (error) return Error: {error.message} + + return ( + + Flow Status: {transactionStatus?.statusString} + {evmResults && evmResults.length > 0 && ( + + EVM Call Results: + idx.toString()} + renderItem={({ item, index }) => ( + + Call {index}: {item.status} + {item.hash && Hash: {item.hash}} + {item.errorMessage && Error: {item.errorMessage}} + + )} + /> + + )} + + ) +} +``` + +--- + +### `useCrossVmBridgeNftFromEvm` + +```tsx +import { useCrossVmBridgeNftFromEvm } from "@onflow/react-native-sdk" +``` + +This hook bridges NFTs from Flow EVM to Cadence. It withdraws an NFT from the signer's COA (Cadence Owned Account) in EVM and deposits it into their Cadence collection. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeNftFromEvmTxResult` + +Where `UseCrossVmBridgeNftFromEvmTxResult` is defined as: + +```typescript +interface UseCrossVmBridgeNftFromEvmTxResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeNftFromEvm: (args: UseCrossVmBridgeNftFromEvmTxMutateArgs) => void + crossVmBridgeNftFromEvmAsync: (args: UseCrossVmBridgeNftFromEvmTxMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeNftFromEvmTxMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeNftFromEvmTxMutateArgs { + nftIdentifier: string // Cadence type identifier (e.g., "A.0x123.MyNFT.NFT") + nftId: string // EVM NFT ID as string representation of UInt256 +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function BridgeNftFromEvmExample() { + const { crossVmBridgeNftFromEvm, isPending, error, data: txId } = useCrossVmBridgeNftFromEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeNftFromEvm({ + nftIdentifier: "A.0x1cf0e2f2f715450.ExampleNFT.NFT", + nftId: "123", + }) + } + + return ( + + + Bridge NFT from EVM + + {isPending && Bridging NFT...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useCrossVmBridgeNftToEvm` + +```tsx +import { useCrossVmBridgeNftToEvm } from "@onflow/react-native-sdk" +``` + +This hook bridges NFTs from Cadence to Flow EVM and executes arbitrary EVM transactions atomically. It withdraws NFTs from the signer's Cadence collection and deposits them into their COA in EVM, then executes the provided EVM calls. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeNftToEvmTxResult` + +Where `UseCrossVmBridgeNftToEvmTxResult` is defined as: + +```typescript +interface UseCrossVmBridgeNftToEvmTxResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeNftToEvm: (args: UseCrossVmBridgeNftToEvmTxMutateArgs) => void + crossVmBridgeNftToEvmAsync: (args: UseCrossVmBridgeNftToEvmTxMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeNftToEvmTxMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeNftToEvmTxMutateArgs { + nftIdentifier: string // Cadence NFT type identifier + nftIds: string[] // Array of NFT IDs to bridge + calls: EvmBatchCall[] // Array of EVM calls to execute after bridging +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function BridgeNftToEvmExample() { + const { crossVmBridgeNftToEvm, isPending, error, data: txId } = useCrossVmBridgeNftToEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeNftToEvm({ + nftIdentifier: "A.0x1cf0e2f2f715450.ExampleNFT.NFT", + nftIds: ["1", "2", "3"], + calls: [ + { + address: "0x1234567890abcdef1234567890abcdef12345678", + abi: myContractAbi, + functionName: "transferNFT", + args: ["0xRecipient", 1n], + gasLimit: 100000n, + }, + ], + }) + } + + return ( + + + Bridge NFTs to EVM + + {isPending && Bridging NFTs...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useCrossVmBridgeTokenFromEvm` + +```tsx +import { useCrossVmBridgeTokenFromEvm } from "@onflow/react-native-sdk" +``` + +This hook bridges fungible tokens from Flow EVM to Cadence. It withdraws tokens from the signer's COA in EVM and deposits them into their Cadence vault. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeTokenFromEvmResult` + +Where `UseCrossVmBridgeTokenFromEvmResult` is defined as: + +```typescript +interface UseCrossVmBridgeTokenFromEvmResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeTokenFromEvm: (args: UseCrossVmBridgeTokenFromEvmMutateArgs) => void + crossVmBridgeTokenFromEvmAsync: (args: UseCrossVmBridgeTokenFromEvmMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeTokenFromEvmMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeTokenFromEvmMutateArgs { + vaultIdentifier: string // Cadence vault type identifier (e.g., "A.0x123.FlowToken.Vault") + amount: string // Amount as UInt256 string representation +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function BridgeTokenFromEvmExample() { + const { crossVmBridgeTokenFromEvm, isPending, error, data: txId } = useCrossVmBridgeTokenFromEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeTokenFromEvm({ + vaultIdentifier: "A.0x1654653399040a61.FlowToken.Vault", + amount: "1000000000", // Amount in smallest unit + }) + } + + return ( + + + Bridge Tokens from EVM + + {isPending && Bridging tokens...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` + +--- + +### `useCrossVmBridgeTokenToEvm` + +```tsx +import { useCrossVmBridgeTokenToEvm } from "@onflow/react-native-sdk" +``` + +This hook bridges fungible tokens from Cadence to Flow EVM and executes arbitrary EVM transactions atomically. It withdraws tokens from the signer's Cadence vault and deposits them into their COA in EVM, then executes the provided EVM calls. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeTokenToEvmResult` + +Where `UseCrossVmBridgeTokenToEvmResult` is defined as: + +```typescript +interface UseCrossVmBridgeTokenToEvmResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeTokenToEvm: (args: UseCrossVmBridgeTokenToEvmMutateArgs) => void + crossVmBridgeTokenToEvmAsync: (args: UseCrossVmBridgeTokenToEvmMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeTokenToEvmMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeTokenToEvmMutateArgs { + vaultIdentifier: string // Cadence vault type identifier + amount: string // Amount as decimal string (e.g., "1.5") + calls: EvmBatchCall[] // Array of EVM calls to execute after bridging +} +``` + +```tsx +import { View, Text, TouchableOpacity } from 'react-native'; + +function BridgeTokenToEvmExample() { + const { crossVmBridgeTokenToEvm, isPending, error, data: txId } = useCrossVmBridgeTokenToEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeTokenToEvm({ + vaultIdentifier: "A.0x1654653399040a61.FlowToken.Vault", + amount: "10.5", + calls: [ + { + address: "0x1234567890abcdef1234567890abcdef12345678", + abi: erc20Abi, + functionName: "transfer", + args: ["0xRecipient", 1000000n], + gasLimit: 100000n, + }, + ], + }) + } + + return ( + + + Bridge Tokens to EVM + + {isPending && Bridging tokens...} + {error && Error: {error.message}} + {txId && Transaction ID: {txId}} + + ) +} +``` diff --git a/docs/build/tools/react-native-sdk/index.mdx b/docs/build/tools/react-native-sdk/index.mdx new file mode 100644 index 0000000000..028f3c8379 --- /dev/null +++ b/docs/build/tools/react-native-sdk/index.mdx @@ -0,0 +1,231 @@ +--- +title: 'Flow React Native SDK' +description: React Native hooks and components for interacting with the Flow blockchain. +sidebar_position: 1 +--- + +# Flow React Native SDK + +**The easiest way to build React Native apps on Flow.** A lightweight, TypeScript-first library for seamless Flow blockchain integration in your React Native apps. + +:::note +This SDK shares the same hooks as the [Flow React SDK](../react-sdk/index.mdx), so if you're familiar with the web version, you'll feel right at home. The main differences are the React Native-specific components (`Connect`, `Profile`) and mobile wallet integrations. +::: + +## Quick Start + +### 1. Install + +```bash +npm install @onflow/react-native-sdk +``` + +### 2. Wrap Your App + +Create a provider wrapper component: + +```tsx title="components/flow-provider-wrapper.tsx" +import { FlowProvider } from '@onflow/react-native-sdk'; +import flowJSON from '../flow.json'; + +export function FlowProviderWrapper({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} +``` + +Then wrap your app in the root layout: + +```tsx title="app/_layout.tsx" +import { FlowProviderWrapper } from '@/components/flow-provider-wrapper'; +import { Stack } from 'expo-router'; +import { StatusBar } from 'expo-status-bar'; +import { View } from 'react-native'; + +export default function RootLayout() { + return ( + + + + + + + ); +} +``` + +### 3. Start Building + +```tsx +import { View, Text, Pressable } from 'react-native'; +import { + Connect, + useFlowCurrentUser, + useFlowQuery, +} from '@onflow/react-native-sdk'; + +function MyApp() { + const { user } = useFlowCurrentUser(); + + const { + data: balance, + isLoading, + refetch, + } = useFlowQuery({ + cadence: ` + import FlowToken from 0x7e60df042a9c0868 + + access(all) fun main(address: Address): UFix64 { + let account = getAccount(address) + let vaultRef = account.capabilities + .get<&FlowToken.Vault>(/public/flowTokenBalance) + .borrow() + ?? panic("Could not borrow Balance reference") + return vaultRef.balance + } + `, + args: (arg, t) => [arg(user?.addr, t.Address)], + query: { enabled: !!user?.addr }, + }); + + return ( + + + {user?.loggedIn && ( + + Welcome, {user.addr}! + {isLoading ? ( + Loading balance... + ) : ( + Balance: {balance ? String(balance) : '0.00'} FLOW + )} + refetch()}> + Refresh + + + )} + + ); +} +``` + +:::info Starter Template +Get started quickly with the [flow-react-native-sdk-starter](https://github.com/onflow/flow-react-native-sdk-starter) template which includes a pre-configured Expo project with wallet connection, balance queries, and transaction examples. +::: + +--- + +## Configuration Options + +The `FlowProvider` accepts the following configuration: + +| Property | Description | +| ------------------------ | ----------------------------------------------------------------------------- | +| `accessNodeUrl` | REST endpoint for blockchain access (e.g., `https://rest-testnet.onflow.org`) | +| `discoveryWallet` | URL for wallet discovery/selection UI | +| `discoveryAuthnEndpoint` | API endpoint for authentication | +| `flowNetwork` | Network selection: `"testnet"` or `"mainnet"` | +| `appDetailTitle` | App name displayed in wallet | +| `appDetailUrl` | App URL displayed in wallet | +| `appDetailIcon` | App icon URL displayed in wallet | +| `appDetailDescription` | App description displayed in wallet | +| `walletconnectProjectId` | WalletConnect Cloud project ID | + +**Mainnet Configuration:** + +```tsx +config={{ + accessNodeUrl: "https://rest-mainnet.onflow.org", + discoveryWallet: "https://fcl-discovery.onflow.org/authn", + discoveryAuthnEndpoint: "https://fcl-discovery.onflow.org/api/authn", + flowNetwork: "mainnet", + // ... other options +}} +``` + +--- + +## [Hooks](./hooks.md) + +**Cadence Hooks** for native Flow interactions: + +- Authentication & user management +- Account details & balances +- Block & transaction queries +- Real-time event subscriptions +- Script execution & mutations + +**Cross-VM Hooks** for bridging Cadence ↔ Flow EVM: + +- Atomic batch transactions +- Token & NFT bridging +- Cross-chain balance queries + +[→ View all hooks](./hooks.md) + +--- + +## [Components](./components.md) + +Native UI components for React Native: + +- `` – Wallet authentication with balance display +- `` – Standalone wallet information display + +[→ View all components](./components.md) + +--- + +## Why Choose React Native SDK? + +**Developer Experience First** + +- TypeScript-native with full type safety +- Familiar React Native patterns and conventions +- Comprehensive error handling and loading states + +**Production Ready** + +- Built on battle-tested libraries (TanStack Query) +- Automatic retries, caching, and background updates +- Cross-VM support for hybrid Cadence/EVM applications + +**Mobile Native** + +- Native mobile wallet integrations via WalletConnect +- React Native components that feel native +- Expo and bare React Native support + +--- + +## Need Help? + +- **[Hooks Documentation](./hooks.md)** – Detailed API reference for all hooks +- **[Components Documentation](./components.md)** – UI components guide +- **[Configuration Guide](../flow-cli/flow.json/configuration.md)** – Learn about configuring `flow.json` diff --git a/docs/build/tools/react-sdk/components.md b/docs/build/tools/react-sdk/components.md new file mode 100644 index 0000000000..cf118fe4c1 --- /dev/null +++ b/docs/build/tools/react-sdk/components.md @@ -0,0 +1,404 @@ +--- +title: 'Components' +description: Reusable UI components for Flow interactions. +sidebar_position: 3 +--- + +import { Connect, TransactionDialog, TransactionLink, TransactionButton } from "@onflow/react-sdk" +import { FlowProvider } from "@onflow/react-sdk" +import FlowProviderDemo from '@site/src/components/FlowProviderDemo'; +import TransactionDialogDemo from '@site/src/components/TransactionDialogDemo'; +import PlaygroundButton from '@site/src/components/PlaygroundButton'; + +# React SDK Components + +## Components + +### `Connect` + +A drop-in wallet connection component with UI for copy address, logout, and balance display. Displays user scheduled transactions within its profile modal with support for multiple tokens. + +
+ +**Props:** + +- `variant?: ButtonProps["variant"]` – Optional button style variant (default: `"primary"`) +- `onConnect?: () => void` – Callback triggered after successful authentication +- `onDisconnect?: () => void` – Callback triggered after logout +- `balanceType?: "cadence" | "evm" | "combined"` – Specifies which balance to display (default: `"cadence"`). Options: + - `"cadence"`: Shows the token balance from the Cadence side + - `"evm"`: Shows the token balance from the Flow EVM side + - `"combined"`: Shows the total combined token balance from both sides +- `balanceTokens?: TokenConfig[]` – Optional array of token configurations to display in the balance selector. Each `TokenConfig` requires: + - `symbol: string` – Token symbol (e.g. "FLOW", "USDC") + - `name: string` – Full token name + - Either `vaultIdentifier: string` (for Cadence tokens) or `erc20Address: string` (for EVM tokens) +- `modalConfig?: ConnectModalConfig` – Optional configuration for the profile modal: + - `scheduledTransactions.show?: boolean` – Whether to show the scheduled transactions tab (default: `false`) + - `scheduledTransactions.filterHandlerTypes?: string[]` – Optional array of handler type identifiers to filter displayed transactions +- `modalEnabled?: boolean` – Whether to show the profile modal on click when connected (default: `true`). When `false`, clicking the button when connected will disconnect instead + +:::note WalletConnect Support + +To enable WalletConnect as a wallet option, add your registered project ID to the `walletconnectProjectId` field in your `FlowProvider` config. + +::: + +```tsx +import { Connect } from "@onflow/react-sdk" + + console.log("Connected!")} + onDisconnect={() => console.log("Logged out")} +/> +``` + +#### Live Demo + + + console.log("Connected!")} + onDisconnect={() => console.log("Logged out")} + /> + + +--- + +### `Profile` + +A standalone component for displaying wallet information including account address, balance and optional scheduled transactions. + +
+ +**Props:** + +- `onDisconnect?: () => void` – Callback triggered when the user clicks the disconnect button +- `balanceType?: "cadence" | "evm" | "combined"` – Specifies which balance to display (default: `"cadence"`). Options: + - `"cadence"`: Shows the token balance from the Cadence side + - `"evm"`: Shows the token balance from the Flow EVM side + - `"combined"`: Shows the total combined token balance from both sides +- `balanceTokens?: TokenConfig[]` – Optional array of token configurations to display in the balance selector. Each `TokenConfig` requires: + - `symbol: string` – Token symbol (e.g. "FLOW", "USDC") + - `name: string` – Full token name + - Either `vaultIdentifier: string` (for Cadence tokens) or `erc20Address: string` (for EVM tokens) +- `profileConfig?: ProfileConfig` – Optional configuration for the profile display: + - `scheduledTransactions.show?: boolean` – Whether to show the scheduled transactions tab (default: `false`) + - `scheduledTransactions.filterHandlerTypes?: string[]` – Optional array of handler type identifiers to filter displayed transactions +- `className?: string` – Optional custom CSS class +- `style?: React.CSSProperties` – Optional inline styles + +:::note WalletConnect Support + +To enable WalletConnect as a wallet option, add your registered project ID to the `walletconnectProjectId` field in your `FlowProvider` config. + +::: + +```tsx +import { Profile } from "@onflow/react-sdk" + + console.log("User disconnected")} +/> +``` + +--- + +### `TransactionButton` + +Button component for executing Flow transactions with built-in loading states and global transaction management. + +
+ +**Props:** + +- `transaction: Parameters[0]` – Flow transaction object to execute when clicked +- `label?: string` – Optional custom button label (default: `"Execute Transaction"`) +- `mutation?: UseMutationOptions[0]>` – Optional TanStack React Query mutation options +- `...buttonProps` – All other `ButtonProps` except `onClick` and `children` (includes `variant`, `disabled`, `className`, etc.) + +```tsx +import { TransactionButton } from "@onflow/react-sdk" + +const myTransaction = { + cadence: ` + transaction() { + prepare(acct: &Account) { + log("Hello from ", acct.address) + } + } + `, + args: (arg, t) => [], + limit: 100, +} + + console.log("Transaction sent:", txId), + onError: (error) => console.error("Transaction failed:", error), + }} +/> +``` + +#### Live Demo + + + [], + limit: 100, + }} + label="Demo Transaction" + /> + + +--- + +### `TransactionDialog` + +Dialog component for real-time transaction status updates. + +
+ +**Props:** + +- `open: boolean` – Whether the dialog is open +- `onOpenChange: (open: boolean) => void` – Callback to open/close dialog +- `txId?: string` – Optional Flow transaction ID or scheduled transaction ID to track +- `onSuccess?: () => void` – Optional callback when transaction is successful +- `pendingTitle?: string` – Optional custom pending state title +- `pendingDescription?: string` – Optional custom pending state description +- `successTitle?: string` – Optional custom success state title +- `successDescription?: string` – Optional custom success state description +- `closeOnSuccess?: boolean` – If `true`, closes the dialog automatically after success + +```tsx +import { TransactionDialog } from "@onflow/react-sdk" + + + +``` + +#### Live Demo + + + +--- + +### `TransactionLink` + +Link to the block explorer with the appropriate network scoped to transaction ID or scheduled transaction ID. + +
+ +**Props:** + +- `txId: string` – The transaction ID or scheduled transaction ID to link to +- `variant?: ButtonProps["variant"]` – Optional button variant (defaults to `"link"`) + +```tsx +import { TransactionLink } from "@onflow/react-sdk" + + +``` + +#### Live Demo + + + + + +--- + +### `NftCard` + +A component for rendering a NFT with image, name, description, collection details, traits and external links. Features include loading states, error handling, dark mode support and optional custom actions. + +
+ +**Props:** + +- `accountAddress: string` – The Flow account address that owns the NFT +- `tokenId: string | number` – The ID of the NFT +- `publicPathIdentifier: string` – The public path identifier for the NFT collection (e.g., "A.0b2a3299cc857e29.TopShot.Collection") +- `showTraits?: boolean` – Whether to display NFT traits/attributes (default: `false`). Shows up to 4 traits with a button to view all +- `showExtra?: boolean` – Whether to display additional information like serial number, rarity, and external links (default: `false`) +- `actions?: NftCardAction[]` – Optional array of custom action buttons displayed in a dropdown menu. Each action requires: + - `title: string` – Display text for the action + - `onClick: () => Promise | void` – Handler function called when action is clicked +- `className?: string` – Optional custom CSS class +- `style?: React.CSSProperties` – Optional inline styles + +```tsx +import { NftCard } from "@onflow/react-sdk" + + { + // Handle transfer logic + } + }, + { + title: "List for Sale", + onClick: async () => { + // Handle listing logic + } + } + ]} +/> +``` + +--- + +### `ScheduledTransactionList` + +A component for displaying scheduled transactions for a Flow account. Shows transaction metadata including thumbnails, descriptions, priority, scheduled time, execution effort, fees and provides an optional transaction cancellation functionality. + +
+ +**Props:** + +- `address: string` – The Flow account address to fetch scheduled transactions for +- `filterHandlerTypes?: string[]` – Optional array of handler type identifiers to filter which transactions are displayed. Only transactions with matching `handlerTypeIdentifier` will be shown +- `cancelEnabled?: boolean` – Whether to show the cancel button for transactions (default: `true`) +- `className?: string` – Optional custom CSS class +- `style?: React.CSSProperties` – Optional inline styles +- `flowClient?: UseFlowScheduledTransactionListArgs["flowClient"]` – Optional custom Flow client instance + +```tsx +import { ScheduledTransactionList } from "@onflow/react-sdk" + + +``` + +--- + +## Theming + +### How Theming Works + +All UI components in `@onflow/react-sdk` are styled using [Tailwind CSS](https://tailwindcss.com/) utility classes. The kit supports both light and dark themes out of the box, using Tailwind's `dark:` variant for dark mode styling. + +You can customize the look and feel of the kit by providing a custom theme to the `FlowProvider` via the `theme` prop. This allows you to override default colors and styles to better match your app's branding. + +### Theme Colors + +The theme object accepts a `colors` property with the following options: + +| Property | Description | Default | +|----------|-------------|---------| +| `primary` | Primary action color (CTAs, main buttons) | `flow-bg-slate-900 dark:flow-bg-white` | +| `primaryForeground` | Text color on primary backgrounds | `flow-text-white dark:flow-text-slate-900` | +| `secondary` | Secondary action color (secondary buttons) | `flow-bg-slate-100 dark:flow-bg-slate-800` | +| `secondaryForeground` | Text color on secondary backgrounds | `flow-text-slate-900 dark:flow-text-slate-100` | +| `accent` | Accent color for highlights, selected states | `flow-bg-slate-800 dark:flow-bg-slate-200` | +| `background` | Default background color (cards, modals) | `flow-bg-white dark:flow-bg-slate-800` | +| `foreground` | Default text color | `flow-text-slate-900 dark:flow-text-slate-100` | +| `muted` | Muted/subtle background color | `flow-bg-slate-100 dark:flow-bg-slate-700` | +| `mutedForeground` | Muted text color | `flow-text-slate-500 dark:flow-text-slate-400` | +| `border` | Border color | `flow-border-slate-200 dark:flow-border-slate-700` | +| `success` | Success state color | `flow-text-green-600 dark:flow-text-green-400` | +| `error` | Error state color | `flow-text-red-600 dark:flow-text-red-400` | +| `link` | Link text color | `flow-text-slate-900 dark:flow-text-slate-100` | + +### Example + +```tsx +import { FlowProvider } from "@onflow/react-sdk" + +const customTheme = { + colors: { + primary: "flow-bg-purple-600 dark:flow-bg-purple-400", + primaryForeground: "flow-text-white dark:flow-text-purple-900", + secondary: "flow-bg-emerald-500 dark:flow-bg-emerald-400", + secondaryForeground: "flow-text-white dark:flow-text-emerald-900", + accent: "flow-bg-purple-700 dark:flow-bg-purple-300", + border: "flow-border-purple-200 dark:flow-border-purple-700", + } +} + +function App() { + return ( + + + + ) +} +``` + +You only need to specify the colors you want to override—any unspecified colors will use the default values. + +--- + +## Dark Mode + +### How Dark Mode Works + +Dark mode is **fully controlled by the parent app** using the `darkMode` prop on `FlowProvider`. The kit does not manage dark mode state internally—this gives you full control and ensures the kit always matches your app's theme. + +- `darkMode={false}` (default): Forces all kit components to use light mode styles. +- `darkMode={true}`: Forces all kit components to use dark mode styles. +- You can dynamically change the `darkMode` prop to switch themes at runtime. + +**Example:** + +```tsx +function App() { + // Parent app manages dark mode state + const [isDark, setIsDark] = useState(false) + + return ( + + + + ) +} +``` + +**Accessing Dark Mode State in Components:** + +You can use the `useDarkMode` hook to check the current mode inside your components: + +```tsx +import { useDarkMode } from "@onflow/react-sdk" + +function MyComponent() { + // useDarkMode only returns the current state, no setter + const { isDark } = useDarkMode() + return
{isDark ? "Dark mode" : "Light mode"}
+} +``` + +#### Notes + +- The kit does **not** automatically follow system preferences or save user choices. You are responsible for managing and passing the correct `darkMode` value. +- All kit components will automatically apply the correct Tailwind `dark:` classes based on the `darkMode` prop. +- For best results, ensure your app's global theme and the kit's `darkMode` prop are always in sync. diff --git a/docs/tools/react-sdk/index.mdx b/docs/build/tools/react-sdk/hooks.md similarity index 50% rename from docs/tools/react-sdk/index.mdx rename to docs/build/tools/react-sdk/hooks.md index d9b895de6e..870855f9db 100644 --- a/docs/tools/react-sdk/index.mdx +++ b/docs/build/tools/react-sdk/hooks.md @@ -1,343 +1,30 @@ --- -title: '@onflow/react-sdk' +title: 'Hooks' description: React hooks for interacting with the Flow blockchain. -sidebar_position: 1 +sidebar_position: 2 --- -import { Connect, TransactionDialog, TransactionLink, TransactionButton } from "@onflow/react-sdk" -import { FlowProvider } from "@onflow/react-sdk" -import FlowProviderDemo from '@site/src/components/FlowProviderDemo'; -import TransactionDialogDemo from '@site/src/components/TransactionDialogDemo'; +import PlaygroundButton from '@site/src/components/PlaygroundButton'; -# @onflow/react-sdk - -`@onflow/react-sdk` is a lightweight React utility library that simplifies interacting with the Flow blockchain. It provides a collection of hooks and components designed to make authentication, script execution, transactions, event subscriptions, and network configuration seamless in React apps. - -## What's Included - -### Cadence Hooks - -Hooks for interacting with native Flow Cadence runtime: - -- [`useFlowCurrentUser`](#useflowcurrentuser) – Authenticate and manage the current Flow user -- [`useFlowAccount`](#useflowaccount) – Fetch Flow account details by address -- [`useFlowBlock`](#useflowblock) – Query latest or specific Flow blocks -- [`useFlowChainId`](#useflowchainid) – Retrieve the current Flow chain ID -- [`useFlowConfig`](#useflowconfig) – Access the current Flow configuration -- [`useFlowEvents`](#useflowevents) – Subscribe to Flow events in real-time -- [`useFlowQuery`](#useflowquery) – Execute Cadence scripts with optional arguments -- [`useFlowQueryRaw`](#useflowqueryraw) – Execute Cadence scripts with optional arguments returning non-decoded data -- [`useFlowMutate`](#useflowmutate) – Send transactions to the Flow blockchain -- [`useFlowRevertibleRandom`](#useflowrevertiblerandom) – Generate pseudorandom values tied to block height -- [`useFlowTransaction`](#useflowtransaction) – Fetch a Flow transaction by ID -- [`useFlowTransactionStatus`](#useflowtransactionstatus) – Track transaction status updates -- [`useDarkMode`](#usedarkmode) – Get current dark mode state - -### Cross-VM (Flow EVM ↔ Cadence) Hooks - -- [`useCrossVmBatchTransaction`](#usecrossvmbatchtransaction) – Execute mutliple EVM transactions in a single atomic Cadence transaction -- [`useCrossVmTokenBalance`](#usecrossvmtokenbalance) – Query fungible token balances across Cadence and Flow EVM -- [`useCrossVmSpendNft`](#usecrossvmspendnft) – Bridge NFTs from Cadence to Flow EVM and execute arbitrary EVM transactions to atomically spend them -- [`useCrossVmSpendToken`](#usecrossvmspendtoken) – Bridge fungible tokens from Cadence to Flow EVM and execute arbitrary EVM transactions -- [`useCrossVmTransactionStatus`](#usecrossvmtransactionstatus) – Track Cross-VM transaction status and EVM call results - -### Components - -Reusable UI components: - -- [``](#connect) - A wallet authentication button -- [``](#transactionbutton) - Context-aware button for executing Flow transactions -- [``](#transactiondialog) - A dialog modal that tracks a Flow transaction's lifecycle -- [``](#transactionlink) - A button that links to the block explorer based on network - -## Installation - -```bash -npm install @onflow/react-sdk -``` - -## Usage - -### Wrapping Your App With `FlowProvider` - -Begin by wrapping your application with the `FlowProvider` to initialize FCL configuration. This sets up FCL and maps its configuration keys to a strictly typed format for your hooks. - -```tsx -import React from "react" -import App from "./App" -import { FlowProvider } from "@onflow/react-sdk" -import flowJSON from "../flow.json" - -function Root() { - return ( - - - - ) -} - -export default Root -``` - -If you're using **Next.js**, place the `FlowProvider` inside your `layout.tsx`. Since React hooks must run on the client, you may need to wrap the provider in a separate file that begins with `'use client'` to avoid issues with server-side rendering. Adjust this setup as needed for other frontend frameworks. - -👉 Learn more about configuring `flow.json` in the [Configuration Guide]. - ---- - -## 🎨 Theming - -### How Theming Works - -All UI components in `@onflow/react-sdk` are styled using [Tailwind CSS](https://tailwindcss.com/) utility classes. The kit supports both light and dark themes out of the box, using Tailwind's `dark:` variant for dark mode styling. - -You can customize the look and feel of the kit by providing a custom theme to the `FlowProvider` via the `theme` prop. This allows you to override default colors and styles to better match your app's branding. - -```tsx -import { FlowProvider } from "@onflow/react-sdk" - - - - -``` - ---- - -## 🌙 Dark Mode - -### How Dark Mode Works - -Dark mode is **fully controlled by the parent app** using the `darkMode` prop on `FlowProvider`. The kit does not manage dark mode state internally—this gives you full control and ensures the kit always matches your app's theme. - -- `darkMode={false}` (default): Forces all kit components to use light mode styles. -- `darkMode={true}`: Forces all kit components to use dark mode styles. -- You can dynamically change the `darkMode` prop to switch themes at runtime. - -**Example:** - -```tsx -function App() { - // Parent app manages dark mode state - const [isDark, setIsDark] = useState(false) - - return ( - - - - ) -} -``` - -**Accessing Dark Mode State in Components:** - -You can use the `useDarkMode` hook to check the current mode inside your components: - -```tsx -import { useDarkMode } from "@onflow/react-sdk" - -function MyComponent() { - // useDarkMode only returns the current state, no setter - const { isDark } = useDarkMode() - return
{isDark ? "Dark mode" : "Light mode"}
-} -``` - -### Notes - -- The kit does **not** automatically follow system preferences or save user choices. You are responsible for managing and passing the correct `darkMode` value. -- All kit components will automatically apply the correct Tailwind `dark:` classes based on the `darkMode` prop. -- For best results, ensure your app's global theme and the kit's `darkMode` prop are always in sync. - ---- - -## Components - -### `Connect` - -A drop-in wallet connection component with UI for copy address, logout, and balance display. - -**Props:** - -- `variant?: ButtonProps["variant"]` – Optional button style variant (default: `"primary"`) -- `onConnect?: () => void` – Callback triggered after successful authentication -- `onDisconnect?: () => void` – Callback triggered after logout -- `balanceType?: "cadence" | "evm" | "combined"` – Specifies which balance to display (default: `"cadence"`). Options: - - `"cadence"`: Shows the FLOW token balance from the Cadence side - - `"evm"`: Shows the FLOW token balance from the Flow EVM side - - `"combined"`: Shows the total combined FLOW token balance from both sides - -```tsx -import { Connect } from "@onflow/react-sdk" - - console.log("Connected!")} - onDisconnect={() => console.log("Logged out")} -/> -``` - -### Live Demo - - - console.log("Connected!")} - onDisconnect={() => console.log("Logged out")} - /> - - ---- - -### `TransactionButton` - -Button component for executing Flow transactions with built-in loading states and global transaction management. - -**Props:** - -- `transaction: Parameters[0]` – Flow transaction object to execute when clicked -- `label?: string` – Optional custom button label (default: `"Execute Transaction"`) -- `mutation?: UseMutationOptions[0]>` – Optional TanStack React Query mutation options -- `...buttonProps` – All other `ButtonProps` except `onClick` and `children` (includes `variant`, `disabled`, `className`, etc.) - -```tsx -import { TransactionButton } from "@onflow/react-sdk" - -const myTransaction = { - cadence: ` - transaction() { - prepare(acct: &Account) { - log("Hello from ", acct.address) - } - } - `, - args: (arg, t) => [], - limit: 100, -} - - console.log("Transaction sent:", txId), - onError: (error) => console.error("Transaction failed:", error), - }} -/> -``` - -### Live Demo - - - [], - limit: 100, - }} - label="Demo Transaction" - /> - - ---- - -### `TransactionDialog` - -Dialog component for real-time transaction status updates. - -**Props:** - -- `open: boolean` – Whether the dialog is open -- `onOpenChange: (open: boolean) => void` – Callback to open/close dialog -- `txId?: string` – Optional Flow transaction ID to track -- `onSuccess?: () => void` – Optional callback when transaction is successful -- `pendingTitle?: string` – Optional custom pending state title -- `pendingDescription?: string` – Optional custom pending state description -- `successTitle?: string` – Optional custom success state title -- `successDescription?: string` – Optional custom success state description -- `closeOnSuccess?: boolean` – If `true`, closes the dialog automatically after success - -```tsx -import { TransactionDialog } from "@onflow/react-sdk" - - - -``` - -### Live Demo - - - ---- - -### `TransactionLink` - -Link to the block explorer with the appropriate network scoped to transaction ID. - -**Props:** - -- `txId: string` – The transaction ID to link to -- `variant?: ButtonProps["variant"]` – Optional button variant (defaults to `"link"`) - -```tsx -import { TransactionLink } from "@onflow/react-sdk" - - -``` - -### Live Demo - - - - - ---- - -## Hooks +# React SDK Hooks :::info -Many of these hooks are built using [`@tanstack/react-query`](https://tanstack.com/query/latest), which provides powerful caching, revalidation, and background refetching features. As a result, you’ll see return types like `UseQueryResult` and `UseMutationResult` throughout this section. Other types—such as `Account`, `Block`, and `CurrentUser`—are from the [Flow Client Library (FCL) TypeDefs](https://github.com/onflow/fcl-js/blob/master/packages/typedefs/src/index.ts). Refer to their respective documentation for full type definitions and usage patterns. +Many of these hooks are built using [`@tanstack/react-query`](https://tanstack.com/query/latest), which provides powerful caching, revalidation, and background refetching features. As a result, you'll see return types like `UseQueryResult` and `UseMutationResult` throughout this section. Other types—such as `Account`, `Block`, and `CurrentUser`—are from the [Flow Client Library (FCL) TypeDefs](https://github.com/onflow/fcl-js/blob/master/packages/typedefs/src/index.ts). Refer to their respective documentation for full type definitions and usage patterns. ::: +## Cadence Hooks + ### `useFlowCurrentUser` + + ```tsx import { useFlowCurrentUser } from "@onflow/react-sdk" ``` -### Parameters +#### Parameters - `flowClient?: FlowClient` - Optional `FlowClient` instance @@ -347,6 +34,12 @@ import { useFlowCurrentUser } from "@onflow/react-sdk" - `authenticate: () => Promise` – Triggers wallet authentication - `unauthenticate: () => void` – Logs the user out +:::note WalletConnect Support + +To enable WalletConnect as a wallet option, add your registered project ID to the `walletconnectProjectId` field in your `FlowProvider` config. + +::: + ```tsx function AuthComponent() { const { user, authenticate, unauthenticate } = useFlowCurrentUser() @@ -370,6 +63,8 @@ function AuthComponent() { ### `useFlowAccount` + + ```tsx import { useFlowAccount } from "@onflow/react-sdk" ``` @@ -408,6 +103,8 @@ function AccountDetails() { ### `useFlowBlock` + + ```tsx import { useFlowBlock } from "@onflow/react-sdk" ``` @@ -445,6 +142,8 @@ function LatestBlock() { ### `useFlowChainId` + + ```tsx import { useFlowChainId } from "@onflow/react-sdk" ``` @@ -477,6 +176,8 @@ function ChainIdExample() { ### `useFlowClient` + + This hook returns the `FlowClient` for the current `` context. #### Parameters: @@ -487,6 +188,8 @@ This hook returns the `FlowClient` for the current `` context. ### `useFlowConfig` + + ```tsx import { useFlowConfig } from "@onflow/react-sdk" ``` @@ -510,6 +213,8 @@ function MyComponent() { ### `useFlowEvents` + + ```tsx import { useFlowEvents } from "@onflow/react-sdk" ``` @@ -544,6 +249,8 @@ function EventListener() { ### `useFlowQuery` + + ```tsx import { useFlowQuery } from "@onflow/react-sdk" ``` @@ -586,6 +293,8 @@ function QueryExample() { ### `useFlowQueryRaw` + + ```tsx import { useFlowQueryRaw } from "@onflow/react-sdk" ``` @@ -632,6 +341,8 @@ function QueryRawExample() { ### `useFlowMutate` + + ```tsx import { useFlowMutate } from "@onflow/react-sdk" ``` @@ -683,6 +394,8 @@ function CreatePage() { ### `useFlowRevertibleRandom` + + ```tsx import { useFlowRevertibleRandom } from "@onflow/react-sdk" ``` @@ -733,17 +446,21 @@ function RandomValues() { #### Notes: -* Randomness is generated using the **on-chain `revertibleRandom`** function on Flow, producing pseudorandom values tied to block and script execution. +* Randomness is generated using the **onchain `revertibleRandom`** function on Flow, producing pseudorandom values tied to block and script execution. * Values are **deterministic**: The values returned for identical calls within the same block will be identical. * If `count ` is larger than one, the returned values are distinct. * This hook is designed for simple use cases that don't require unpredictability, such as randomized UIs. Since the hook uses script executions on existing blocks, the random source is already public and the randoms are predictable. -* For **more advanced use cases** that **do** require on-chain randomness logic via transactions, Flow provides built-in support using Cadence's `revertibleRandom` and [commit-reveal scheme]. +* For **more advanced use cases** that **do** require onchain randomness logic via transactions, Flow provides built-in support using Cadence's `revertibleRandom` and [commit-reveal scheme]. + +[commit-reveal scheme]: ../../cadence/advanced-concepts/randomness#commit-reveal-scheme --- ### `useFlowTransaction` + + ```tsx import { useFlowTransaction } from "@onflow/react-sdk" ``` @@ -752,7 +469,7 @@ Fetches a Flow transaction by ID and returns the decoded transaction object. #### Parameters: -* `txId?: string` – The Flow transaction ID to fetch. +* `txId?: string` – The Flow transaction ID or scheduled transaction ID to fetch. * `query?: Omit, "queryKey" | "queryFn">` – Optional TanStack Query options like `staleTime`, `enabled`, etc. * `flowClient?: FlowClient` - Optional `FlowClient` instance @@ -784,13 +501,15 @@ function TransactionDetails({ txId }: { txId: string }) { ### `useFlowTransactionStatus` + + ```tsx import { useFlowTransactionStatus } from "@onflow/react-sdk" ``` #### Parameters: -- `id: string` – Transaction ID to subscribe to +- `id: string` – Transaction ID or scheduled transaction ID to subscribe to - `flowClient?: FlowClient` - Optional `FlowClient` instance #### Returns: @@ -813,6 +532,8 @@ function TransactionStatusComponent() { ### `useDarkMode` + + ```tsx import { useDarkMode } from "@onflow/react-sdk" ``` @@ -838,161 +559,269 @@ function ThemeAwareComponent() { --- -## Cross-VM Hooks +### `useFlowNftMetadata` -### `useCrossVmBatchTransaction` + ```tsx -import { useCrossVmBatchTransaction } from "@onflow/react-sdk" +import { useFlowNftMetadata } from "@onflow/react-sdk" ``` -This hook allows you to execute multiple EVM transactions in a single atomic Cadence transaction. It is useful for batch processing EVM calls while ensuring they are executed together, either all succeeding or allowing for some to fail without affecting the others. +This hook fetches NFT metadata including display information, traits, rarity, and collection details. #### Parameters: -- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `accountAddress?: string` – Flow address of the account holding the NFT +- `tokenId?: string | number` – The NFT token ID +- `publicPathIdentifier?: string` – Public path identifier for the collection +- `query?: UseQueryOptions` – Optional TanStack Query options - `flowClient?: FlowClient` - Optional `FlowClient` instance -#### Returns: `UseCrossVmBatchTransactionResult` +#### Returns: `UseQueryResult` -Where `UseCrossVmBatchTransactionResult` is defined as: +Where `NftViewResult` is defined as: ```typescript -interface UseCrossVmBatchTransactionResult extends Omit< - UseMutationResult, - "mutate" | "mutateAsync" -> { - mutate: (calls: UseCrossVmBatchTransactionMutateArgs) => void - mutateAsync: (calls: UseCrossVmBatchTransactionMutateArgs) => Promise +interface NftViewResult { + name: string + description: string + thumbnailUrl: string + externalUrl?: string + collectionName?: string + collectionExternalUrl?: string + tokenID: string + traits?: Record + rarity?: string + serialNumber?: string } ``` -Where `UseCrossVmBatchTransactionMutateArgs` is defined as: +```tsx +function NftMetadataExample() { + const { data: nft, isLoading, error } = useFlowNftMetadata({ + accountAddress: "0x1cf0e2f2f715450", + tokenId: "123", + publicPathIdentifier: "exampleNFTCollection", + query: { staleTime: 60000 }, + }) -```typescript -interface UseCrossVmBatchTransactionMutateArgs { - calls: EvmBatchCall[] - mustPass?: boolean + if (isLoading) return

Loading NFT metadata...

+ if (error) return

Error: {error.message}

+ if (!nft) return

NFT not found

+ + return ( +
+

{nft.name}

+ {nft.name} +

{nft.description}

+ {nft.collectionName &&

Collection: {nft.collectionName}

} + {nft.rarity &&

Rarity: {nft.rarity}

} + {nft.traits && ( +
+

Traits:

+
    + {Object.entries(nft.traits).map(([key, value]) => ( +
  • {key}: {value}
  • + ))} +
+
+ )} +
+ ) } ``` -Where `EvmBatchCall` is defined as: +--- + +### `useFlowAuthz` + +```tsx +import { useFlowAuthz } from "@onflow/react-sdk" +``` + +A React hook that returns an authorization function for Flow transactions. If no custom authorization is provided, it returns the current user's wallet authorization. + +#### Parameters: + +- `authz?: AuthorizationFunction` – Optional custom authorization function +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +Where `AuthorizationFunction` is defined as: ```typescript -interface EvmBatchCall { - // The target EVM contract address (as a string) - address: string - // The contract ABI fragment - abi: Abi - // The name of the function to call - functionName: string - // The function arguments - args?: readonly unknown[] - // The gas limit for the call - gasLimit?: bigint - // The value to send with the call - value?: bigint +type AuthorizationFunction = ( + account: Partial +) => Partial | Promise> +``` + +#### Returns: `AuthorizationFunction` + +The authorization function is compatible with Flow transactions' authorizations parameter. + +```tsx +// Example 1: Using current user authorization +function CurrentUserAuthExample() { + const authorization = useFlowAuthz() + + const sendTransaction = async () => { + const txId = await fcl.mutate({ + cadence: ` + transaction { + prepare(signer: auth(Storage) &Account) { + log(signer.address) + } + } + `, + authorizations: [authorization], + limit: 100, + }) + console.log("Transaction ID:", txId) + } + + return } ``` ```tsx -function CrossVmBatchTransactionExample() { - const { sendBatchTransaction, isPending, error, data: txId } = useCrossVmBatchTransaction({ - mutation: { - onSuccess: (txId) => console.log("TX ID:", txId), - }, +// Example 2: Using custom authorization function +function CustomAuthExample() { + const customAuthz = (account) => ({ + ...account, + addr: "0xCUSTOMOADDRESS", + keyId: 0, + signingFunction: async (signable) => ({ + signature: "0x...", + }), }) - const sendTransaction = () => { - const calls = [ - { - address: "0x1234567890abcdef", - abi: { - // ABI definition for the contract - }, - functionName: "transfer", - args: ["0xabcdef1234567890", 100n], // Example arguments - gasLimit: 21000n, // Example gas limit - }, - // Add more calls as needed - ] + const authorization = useFlowAuthz({ authz: customAuthz }) - sendBatchTransaction({calls}) + const sendTransaction = async () => { + const txId = await fcl.mutate({ + cadence: ` + transaction { + prepare(signer: auth(Storage) &Account) { + log(signer.address) + } + } + `, + authorizations: [authorization], + limit: 100, + }) + console.log("Transaction ID:", txId) } - return ( -
- - {isPending &&

Sending transaction...

} - {error &&

Error: {error.message}

} - {txId &&

Transaction ID: {txId}

} -
- ) + return } ``` --- -### `useCrossVmTokenBalance` +### `useFlowScheduledTransaction` + + ```tsx -import { useCrossVmTokenBalance } from "@onflow/react-sdk" +import { useFlowScheduledTransaction } from "@onflow/react-sdk" ``` -Fetch the balance of a token balance for a given user across both Cadence and EVM environments. +Fetches a scheduled transaction by ID. #### Parameters: -- `owner: string` – Cadence address of the account whose token balances you want. -- `vaultIdentifier?: string` – Optional Cadence resource identifier (e.g. "0x1cf0e2f2f715450.FlowToken.Vault") for on-chain balance -- `erc20AddressHexArg?: string` – Optional bridged ERC-20 contract address (hex) for EVM/COA balance -- `query?: Omit, "queryKey" | "queryFn">` – Optional TanStack Query config (e.g. staleTime, enabled) +- `txId?: string` – Scheduled transaction ID +- `includeHandlerData?: boolean` – Include handler data (default: false) +- `query?: UseQueryOptions` – Optional TanStack Query options - `flowClient?: FlowClient` - Optional `FlowClient` instance -> **Note:** You must pass `owner`, and one of `vaultIdentifier` or `erc20AddressHexArg`. - -#### Returns: `UseQueryResult` +#### Returns: `UseQueryResult` -Where `UseCrossVmTokenBalanceData` is defined as: +Where `ScheduledTransaction` is defined as: ```typescript -interface UseCrossVmTokenBalanceData { - cadence: TokenBalance // Token balance of Cadence vault - evm: TokenBalance // Token balance of EVM (COA stored in /storage/coa) - combined: TokenBalance // Combined balance of both Cadence and EVM +interface ScheduledTransaction { + id: string + priority: ScheduledTransactionPriority // 0 = Low, 1 = Medium, 2 = High + executionEffort: bigint + status: ScheduledTransactionStatus // 0 = Pending, 1 = Processing, 2 = Completed, 3 = Failed, 4 = Cancelled + fees: { + value: bigint + formatted: string + } + scheduledTimestamp: number + handlerTypeIdentifier: string + handlerAddress: string + handlerUUID?: string // Only included if includeHandlerData is true + handlerResolvedViews?: {[viewType: string]: any} // Only included if includeHandlerData is true } ``` -Where `TokenBalance` is defined as: +```tsx +function ScheduledTransactionDetails({ txId }: { txId: string }) { + const { data: transaction, isLoading, error } = useFlowScheduledTransaction({ + txId, + query: { staleTime: 10000 }, + }) -```typescript -interface TokenBalance { - value: bigint // Balance value in smallest unit - formatted: string // Formatted balance string (e.g. "123.45") - precision: number // Number of decimal places for the token + if (isLoading) return

Loading scheduled transaction...

+ if (error) return

Error: {error.message}

+ if (!transaction) return

Transaction not found

+ + return ( +
+

Scheduled Transaction #{transaction.id}

+

Status: {transaction.status}

+

Priority: {transaction.priority}

+

Fees: {transaction.fees.formatted} FLOW

+

Handler: {transaction.handlerTypeIdentifier}

+
+ ) } ``` +--- + +### `useFlowScheduledTransactionList` + + + ```tsx -function UseCrossVmTokenBalanceExample() { - const { data, isLoading, error, refetch } = useCrossVmTokenBalance({ - owner: '0x1e4aa0b87d10b141', - vaultIdentifier: 'A.1654653399040a61.FlowToken.Vault', +import { useFlowScheduledTransactionList } from "@onflow/react-sdk" +``` + +Lists all scheduled transactions for an account. + +#### Parameters: + +- `account?: string` – Flow address to query +- `includeHandlerData?: boolean` – Include handler data (default: false) +- `query?: UseQueryOptions` – Optional TanStack Query options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseQueryResult` + +```tsx +function ScheduledTransactionsList({ account }: { account: string }) { + const { data: transactions, isLoading, error, refetch } = useFlowScheduledTransactionList({ + account, query: { staleTime: 10000 }, - }); + }) - if (isLoading) return

Loading token balance...

; - if (error) return

Error fetching token balance: {error.message}

; + if (isLoading) return

Loading scheduled transactions...

+ if (error) return

Error: {error.message}

+ if (!transactions || transactions.length === 0) return

No scheduled transactions

return (
-

Token Balances

-

Cadence Balance: {data.cadence.formatted} (Value: {data.cadence.value})

-

EVM Balance: {data.evm.formatted} (Value: {data.evm.value})

-

Combined Balance: {data.combined.formatted} (Value: {data.combined.value})

- +

Scheduled Transactions for {account}

+ +
    + {transactions.map((tx) => ( +
  • + Transaction #{tx.id} - Status: {tx.status} - Fees: {tx.fees.formatted} FLOW +
  • + ))} +
) } @@ -1000,72 +829,121 @@ function UseCrossVmTokenBalanceExample() { --- -### `useCrossVmSpendNft` +### `useFlowScheduledTransactionCancel` + + ```tsx -import { useCrossVmSpendNft } from "@onflow/react-sdk" +import { useFlowScheduledTransactionCancel } from "@onflow/react-sdk" ``` -Bridge NFTs from Cadence to Flow EVM and execute arbitrary EVM transactions to atomically spend them. +Cancels a scheduled transaction and refunds fees. #### Parameters: -- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `mutation?: UseMutationOptions` – Optional TanStack Query mutation options - `flowClient?: FlowClient` - Optional `FlowClient` instance -Where `UseCrossVmSpendFtMutateArgs` is defined as: +#### Returns: `UseFlowScheduledTransactionCancelResult` + +Where `UseFlowScheduledTransactionCancelResult` is defined as: ```typescript -interface UseCrossVmSpendFtMutateArgs { - nftIdentifier: string // Cadence NFT identifier (e.g. "0x1cf0e2f2f715450.FlowNFT") - nftIds: string[] // Array of NFT IDs to bridge - calls: EVMBatchCall[] // Array of EVM calls to execute atomically +interface UseFlowScheduledTransactionCancelResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + cancelTransaction: (txId: string) => void + cancelTransactionAsync: (txId: string) => Promise +} +``` + +```tsx +function CancelScheduledTransaction() { + const { cancelTransactionAsync, isPending, error, data: txId } = useFlowScheduledTransactionCancel({ + mutation: { + onSuccess: (txId) => console.log("Cancel transaction ID:", txId), + }, + }) + + const handleCancel = async (scheduledTxId: string) => { + try { + const resultTxId = await cancelTransactionAsync(scheduledTxId) + console.log("Successfully canceled scheduled transaction:", resultTxId) + } catch (error) { + console.error("Failed to cancel:", error) + } + } + + return ( +
+ + {isPending &&

Canceling transaction...

} + {error &&

Error: {error.message}

} + {txId &&

Cancel Transaction ID: {txId}

} +
+ ) } ``` -#### Returns: `UseCrossVmSpendNftResult` +--- + +### `useFlowScheduledTransactionSetup` -Where `UseCrossVmSpendNftResult` is defined as: + + +```tsx +import { useFlowScheduledTransactionSetup } from "@onflow/react-sdk" +``` + +Sets up the Transaction Scheduler Manager resource. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStack Query mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseFlowScheduledTransactionSetupResult` + +Where `UseFlowScheduledTransactionSetupResult` is defined as: ```typescript -interface UseCrossVmSpendNftResult extends Omit< - UseMutationResult, +interface UseFlowScheduledTransactionSetupResult extends Omit< + UseMutationResult, "mutate" | "mutateAsync" > { - spendNft: (params: CrossVmSpendNftParams) => Promise - spendNftAsync: (params: CrossVmSpendNftParams) => Promise + setup: () => void + setupAsync: () => Promise } ``` ```tsx -function CrossVmSpendNftExample() { - const { spendNft, isPending, error, data: txId } = useCrossVmSpendNft() +function SchedulerSetup() { + const { setupAsync, isPending, error, data: txId } = useFlowScheduledTransactionSetup({ + mutation: { + onSuccess: (txId) => console.log("Setup transaction ID:", txId), + }, + }) - const handleSpendNft = () => { - spendNft({ - nftIdentifier: "0x1cf0e2f2f715450.FlowNFT", // Cadence NFT identifier - nftIds: ["1"], // Array of NFT IDs to bridge - calls: [ - { - abi: contractAbi, // ABI of the EVM contract - contractAddress: "0x1234567890abcdef1234567890abcdef12345678", // EVM contract address - functionName: "transferNFT", - args: ["123"], // Example args - value: "1000000000000000000", // Amount in wei (if applicable) - gasLimit: "21000", // Gas limit for the EVM call - }, - ], - }) + const handleSetup = async () => { + try { + const resultTxId = await setupAsync() + console.log("Scheduler setup successful:", resultTxId) + } catch (error) { + console.error("Setup failed:", error) + } } return (
- - {isPending &&

Sending transaction...

} + {isPending &&

Setting up scheduler...

} {error &&

Error: {error.message}

} - {txId &&

Transaction ID: {txId}

} + {txId &&

Setup Transaction ID: {txId}

}
) } @@ -1073,72 +951,165 @@ function CrossVmSpendNftExample() { --- -### `useCrossVmSpendToken` +## Cross-VM Hooks + +### `useCrossVmBatchTransaction` + + ```tsx -import { useCrossVmSpendToken } from "@onflow/react-sdk" +import { useCrossVmBatchTransaction } from "@onflow/react-sdk" ``` -Bridge FTs from Cadence to Flow EVM and execute arbitrary EVM transactions to atomically spend them. +This hook allows you to execute multiple EVM transactions in a single atomic Cadence transaction. It is useful for batch processing EVM calls while ensuring they are executed together, either all succeeding or allowing for some to fail without affecting the others. #### Parameters: -- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options - `flowClient?: FlowClient` - Optional `FlowClient` instance -Where `UseCrossVmSpendTokenMutateArgs` is defined as: +#### Returns: `UseCrossVmBatchTransactionResult` + +Where `UseCrossVmBatchTransactionResult` is defined as: ```typescript -interface UseCrossVmSpendTokenMutateArgs { - vaultIdentifier: string; // Cadence vault identifier (e.g. "0x1cf0e2f2f715450.ExampleToken.Vault") - amount: string; // Amount of tokens to bridge, as a decimal string (e.g. "1.23") - calls: EVMBatchCall[]; // Array of EVM calls to execute after bridging +interface UseCrossVmBatchTransactionResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + mutate: (calls: UseCrossVmBatchTransactionMutateArgs) => void + mutateAsync: (calls: UseCrossVmBatchTransactionMutateArgs) => Promise } ``` -#### Returns: `UseCrossVmSpendTokenResult` +Where `UseCrossVmBatchTransactionMutateArgs` is defined as: + +```typescript +interface UseCrossVmBatchTransactionMutateArgs { + calls: EvmBatchCall[] + mustPass?: boolean +} +``` -Where `UseCrossVmSpendTokenResult` is defined as: +Where `EvmBatchCall` is defined as: ```typescript -interface UseCrossVmSpendTokenResult extends Omit< - UseMutationResult, - "mutate" | "mutateAsync" -> { - spendToken: (args: UseCrossVmSpendTokenMutateArgs) => void; // Function to trigger the FT bridging and EVM calls - spendTokenAsync: (args: UseCrossVmSpendTokenMutateArgs) => Promise; // Async version of spendToken +interface EvmBatchCall { + // The target EVM contract address (as a string) + address: string + // The contract ABI fragment + abi: Abi + // The name of the function to call + functionName: string + // The function arguments + args?: readonly unknown[] + // The gas limit for the call + gasLimit?: bigint + // The value to send with the call + value?: bigint } ``` ```tsx -function CrossVmSpendTokenExample() { - const { spendToken, isPending, error, data: txId } = useCrossVmSpendToken() +function CrossVmBatchTransactionExample() { + const { sendBatchTransaction, isPending, error, data: txId } = useCrossVmBatchTransaction({ + mutation: { + onSuccess: (txId) => console.log("TX ID:", txId), + }, + }) - const handleSpendToken = () => { - spendToken({ - vaultIdentifier: "0x1cf0e2f2f715450.ExampleToken.Vault", // Cadence vault identifier - amount: "1.23", // Amount of tokens to bridge to EVM - calls: [ - { - abi: myEvmContractAbi, // EVM contract ABI - address: "0x01234567890abcdef01234567890abcdef", // EVM contract address - function: "transfer", // EVM function to call - args: [ - "0xabcdef01234567890abcdef01234567890abcdef", // Recipient address - ], + const sendTransaction = () => { + const calls = [ + { + address: "0x1234567890abcdef", + abi: { + // ABI definition for the contract }, - ], - }) + functionName: "transfer", + args: ["0xabcdef1234567890", 100n], // Example arguments + gasLimit: 21000n, // Example gas limit + }, + // Add more calls as needed + ] + + sendBatchTransaction({calls}) } return (
- {isPending &&

Sending transaction...

} {error &&

Error: {error.message}

} - {txId &&

Cadence Transaction ID: {txId}

} + {txId &&

Transaction ID: {txId}

} +
+ ) +} +``` + +--- + +### `useCrossVmTokenBalance` + + + +```tsx +import { useCrossVmTokenBalance } from "@onflow/react-sdk" +``` + +Fetch the balance of a token balance for a given user across both Cadence and EVM environments. + +#### Parameters: + +- `owner: string` – Cadence address of the account whose token balances you want. +- `vaultIdentifier?: string` – Optional Cadence resource identifier (e.g. "0x1cf0e2f2f715450.FlowToken.Vault") for onchain balance +- `erc20AddressHexArg?: string` – Optional bridged ERC-20 contract address (hex) for EVM/COA balance +- `query?: Omit, "queryKey" | "queryFn">` – Optional TanStack Query config (e.g. staleTime, enabled) +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +> **Note:** You must pass `owner`, and one of `vaultIdentifier` or `erc20AddressHexArg`. + +#### Returns: `UseQueryResult` + +Where `UseCrossVmTokenBalanceData` is defined as: + +```typescript +interface UseCrossVmTokenBalanceData { + cadence: TokenBalance // Token balance of Cadence vault + evm: TokenBalance // Token balance of EVM (COA stored in /storage/coa) + combined: TokenBalance // Combined balance of both Cadence and EVM +} +``` + +Where `TokenBalance` is defined as: + +```typescript +interface TokenBalance { + value: bigint // Balance value in smallest unit + formatted: string // Formatted balance string (e.g. "123.45") + precision: number // Number of decimal places for the token +} +``` + +```tsx +function UseCrossVmTokenBalanceExample() { + const { data, isLoading, error, refetch } = useCrossVmTokenBalance({ + owner: '0x1e4aa0b87d10b141', + vaultIdentifier: 'A.1654653399040a61.FlowToken.Vault', + query: { staleTime: 10000 }, + }); + + if (isLoading) return

Loading token balance...

; + if (error) return

Error fetching token balance: {error.message}

; + + return ( +
+

Token Balances

+

Cadence Balance: {data.cadence.formatted} (Value: {data.cadence.value})

+

EVM Balance: {data.evm.formatted} (Value: {data.evm.value})

+

Combined Balance: {data.combined.formatted} (Value: {data.combined.value})

+
) } @@ -1148,6 +1119,8 @@ function CrossVmSpendTokenExample() { ### `useCrossVmTransactionStatus` + + ```tsx import { useCrossVmTransactionStatus } from "@onflow/react-sdk" ``` @@ -1210,5 +1183,294 @@ function CrossVmTransactionStatusComponent() { } ``` -[commit-reveal scheme]: ../../build/advanced-concepts/randomness#commit-reveal-scheme -[Configuration Guide]: ../flow-cli/flow.json/configuration.md +--- + +### `useCrossVmBridgeNftFromEvm` + + + +```tsx +import { useCrossVmBridgeNftFromEvm } from "@onflow/react-sdk" +``` + +This hook bridges NFTs from Flow EVM to Cadence. It withdraws an NFT from the signer's COA (Cadence Owned Account) in EVM and deposits it into their Cadence collection. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeNftFromEvmTxResult` + +Where `UseCrossVmBridgeNftFromEvmTxResult` is defined as: + +```typescript +interface UseCrossVmBridgeNftFromEvmTxResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeNftFromEvm: (args: UseCrossVmBridgeNftFromEvmTxMutateArgs) => void + crossVmBridgeNftFromEvmAsync: (args: UseCrossVmBridgeNftFromEvmTxMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeNftFromEvmTxMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeNftFromEvmTxMutateArgs { + nftIdentifier: string // Cadence type identifier (e.g., "A.0x123.MyNFT.NFT") + nftId: string // EVM NFT ID as string representation of UInt256 +} +``` + +```tsx +function BridgeNftFromEvmExample() { + const { crossVmBridgeNftFromEvm, isPending, error, data: txId } = useCrossVmBridgeNftFromEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeNftFromEvm({ + nftIdentifier: "A.0x1cf0e2f2f715450.ExampleNFT.NFT", + nftId: "123", + }) + } + + return ( +
+ + {isPending &&

Bridging NFT...

} + {error &&

Error: {error.message}

} + {txId &&

Transaction ID: {txId}

} +
+ ) +} +``` + +--- + +### `useCrossVmBridgeNftToEvm` + + + +```tsx +import { useCrossVmBridgeNftToEvm } from "@onflow/react-sdk" +``` + +This hook bridges NFTs from Cadence to Flow EVM and executes arbitrary EVM transactions atomically. It withdraws NFTs from the signer's Cadence collection and deposits them into their COA in EVM, then executes the provided EVM calls. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeNftToEvmTxResult` + +Where `UseCrossVmBridgeNftToEvmTxResult` is defined as: + +```typescript +interface UseCrossVmBridgeNftToEvmTxResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeNftToEvm: (args: UseCrossVmBridgeNftToEvmTxMutateArgs) => void + crossVmBridgeNftToEvmAsync: (args: UseCrossVmBridgeNftToEvmTxMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeNftToEvmTxMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeNftToEvmTxMutateArgs { + nftIdentifier: string // Cadence NFT type identifier + nftIds: string[] // Array of NFT IDs to bridge + calls: EvmBatchCall[] // Array of EVM calls to execute after bridging +} +``` + +```tsx +function BridgeNftToEvmExample() { + const { crossVmBridgeNftToEvm, isPending, error, data: txId } = useCrossVmBridgeNftToEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeNftToEvm({ + nftIdentifier: "A.0x1cf0e2f2f715450.ExampleNFT.NFT", + nftIds: ["1", "2", "3"], + calls: [ + { + address: "0x1234567890abcdef1234567890abcdef12345678", + abi: myContractAbi, + functionName: "transferNFT", + args: ["0xRecipient", 1n], + gasLimit: 100000n, + }, + ], + }) + } + + return ( +
+ + {isPending &&

Bridging NFTs...

} + {error &&

Error: {error.message}

} + {txId &&

Transaction ID: {txId}

} +
+ ) +} +``` + +--- + +### `useCrossVmBridgeTokenFromEvm` + + + +```tsx +import { useCrossVmBridgeTokenFromEvm } from "@onflow/react-sdk" +``` + +This hook bridges fungible tokens from Flow EVM to Cadence. It withdraws tokens from the signer's COA in EVM and deposits them into their Cadence vault. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeTokenFromEvmResult` + +Where `UseCrossVmBridgeTokenFromEvmResult` is defined as: + +```typescript +interface UseCrossVmBridgeTokenFromEvmResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeTokenFromEvm: (args: UseCrossVmBridgeTokenFromEvmMutateArgs) => void + crossVmBridgeTokenFromEvmAsync: (args: UseCrossVmBridgeTokenFromEvmMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeTokenFromEvmMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeTokenFromEvmMutateArgs { + vaultIdentifier: string // Cadence vault type identifier (e.g., "A.0x123.FlowToken.Vault") + amount: string // Amount as UInt256 string representation +} +``` + +```tsx +function BridgeTokenFromEvmExample() { + const { crossVmBridgeTokenFromEvm, isPending, error, data: txId } = useCrossVmBridgeTokenFromEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeTokenFromEvm({ + vaultIdentifier: "A.0x1654653399040a61.FlowToken.Vault", + amount: "1000000000", // Amount in smallest unit + }) + } + + return ( +
+ + {isPending &&

Bridging tokens...

} + {error &&

Error: {error.message}

} + {txId &&

Transaction ID: {txId}

} +
+ ) +} +``` + +--- + +### `useCrossVmBridgeTokenToEvm` + + + +```tsx +import { useCrossVmBridgeTokenToEvm } from "@onflow/react-sdk" +``` + +This hook bridges fungible tokens from Cadence to Flow EVM and executes arbitrary EVM transactions atomically. It withdraws tokens from the signer's Cadence vault and deposits them into their COA in EVM, then executes the provided EVM calls. + +#### Parameters: + +- `mutation?: UseMutationOptions` – Optional TanStackQuery mutation options +- `flowClient?: FlowClient` - Optional `FlowClient` instance + +#### Returns: `UseCrossVmBridgeTokenToEvmResult` + +Where `UseCrossVmBridgeTokenToEvmResult` is defined as: + +```typescript +interface UseCrossVmBridgeTokenToEvmResult extends Omit< + UseMutationResult, + "mutate" | "mutateAsync" +> { + crossVmBridgeTokenToEvm: (args: UseCrossVmBridgeTokenToEvmMutateArgs) => void + crossVmBridgeTokenToEvmAsync: (args: UseCrossVmBridgeTokenToEvmMutateArgs) => Promise +} +``` + +Where `UseCrossVmBridgeTokenToEvmMutateArgs` is defined as: + +```typescript +interface UseCrossVmBridgeTokenToEvmMutateArgs { + vaultIdentifier: string // Cadence vault type identifier + amount: string // Amount as decimal string (e.g., "1.5") + calls: EvmBatchCall[] // Array of EVM calls to execute after bridging +} +``` + +```tsx +function BridgeTokenToEvmExample() { + const { crossVmBridgeTokenToEvm, isPending, error, data: txId } = useCrossVmBridgeTokenToEvm({ + mutation: { + onSuccess: (txId) => console.log("Transaction ID:", txId), + }, + }) + + const handleBridge = () => { + crossVmBridgeTokenToEvm({ + vaultIdentifier: "A.0x1654653399040a61.FlowToken.Vault", + amount: "10.5", + calls: [ + { + address: "0x1234567890abcdef1234567890abcdef12345678", + abi: erc20Abi, + functionName: "transfer", + args: ["0xRecipient", 1000000n], + gasLimit: 100000n, + }, + ], + }) + } + + return ( +
+ + {isPending &&

Bridging tokens...

} + {error &&

Error: {error.message}

} + {txId &&

Transaction ID: {txId}

} +
+ ) +} +``` diff --git a/docs/build/tools/react-sdk/index.mdx b/docs/build/tools/react-sdk/index.mdx new file mode 100644 index 0000000000..8484ab97df --- /dev/null +++ b/docs/build/tools/react-sdk/index.mdx @@ -0,0 +1,185 @@ +--- +title: 'Flow React SDK' +description: React hooks and components for interacting with the Flow blockchain. +sidebar_position: 1 +--- + +import ReactSDKOverview from '@site/src/components/ReactSDKOverview'; +import FlowProviderDemo from '@site/src/components/FlowProviderDemo'; +import { Connect } from '@onflow/react-sdk'; + +# Flow React SDK + +**The easiest way to build React apps on Flow.** A lightweight, TypeScript-first library that makes Flow blockchain interactions feel native to React development. + + + +## Quick Start + +### 1. Install + +```bash +npm install @onflow/react-sdk +``` + +### 2. Wrap Your App + +```tsx +import React from 'react'; +import App from './App'; +import { FlowProvider } from '@onflow/react-sdk'; +import flowJSON from '../flow.json'; + +function Root() { + return ( + + + + ); +} + +export default Root; +``` + +:::tip Next.js Users +Create a client component wrapper for the `FlowProvider`: + +```tsx title="components/FlowProviderWrapper.tsx" +'use client'; + +import { FlowProvider } from '@onflow/react-sdk'; +import flowJSON from '../flow.json'; + +export default function FlowProviderWrapper({ children }) { + return ( + + {children} + + ); +} +``` + +Then use it in your `layout.tsx`: + +```tsx title="app/layout.tsx" +import FlowProviderWrapper from '@/components/FlowProviderWrapper'; + +export default function RootLayout({ children }) { + return ( + + + {children} + + + ); +} +``` + +::: + +### 3. Start Building + +```tsx +import { useFlowCurrentUser, Connect, useFlowQuery } from '@onflow/react-sdk'; + +function MyApp() { + const { user } = useFlowCurrentUser(); + + const { data: greeting } = useFlowQuery({ + cadence: `access(all) fun main(): String { return "Hello, Flow!" }`, + args: (arg, t) => [], + }); + + return ( +
+ + {user?.loggedIn &&

Welcome, {user.addr}!

} +

{greeting}

+
+ ); +} +``` + +--- + +## 🎣 [Hooks](./hooks.md) + +**Cadence Hooks** for native Flow interactions: + +- Authentication & user management +- Account details & balances +- Block & transaction queries +- Real-time event subscriptions +- Script execution & mutations + +**Cross-VM Hooks** for bridging Cadence ↔ Flow EVM: + +- Atomic batch transactions +- Token & NFT bridging +- Cross-chain balance queries + +[→ View all hooks](./hooks.md) + +--- + +## 🎨 [Components](./components.md) + +Beautiful, accessible UI components: + +- `` – Wallet authentication with balance display +- `` – Smart transaction execution +- `` – Real-time transaction tracking +- `` – Network-aware block explorer links + +[→ View all components](./components.md) + +--- + +## Why Choose React SDK? + +**Developer Experience First** + +- TypeScript-native with full type safety +- Familiar React patterns and conventions +- Comprehensive error handling and loading states + +**Production Ready** + +- Built on battle-tested libraries (TanStack Query, Tailwind CSS) +- Automatic retries, caching, and background updates +- Cross-VM support for hybrid Cadence/EVM applications + +**Customizable** + +- Theme system for brand consistency +- Composable hooks for custom UI +- Dark mode support out of the box + +--- + +## Need Help? + +- 📖 **[Hooks Documentation](./hooks.md)** – Detailed API reference for all hooks +- 🎨 **[Components Documentation](./components.md)** – UI components and theming guide +- 🔗 **[Configuration Guide](../flow-cli/flow.json/configuration.md)** – Learn about configuring `flow.json` diff --git a/docs/tools/vscode-extension/index.md b/docs/build/tools/vscode-extension/index.md similarity index 100% rename from docs/tools/vscode-extension/index.md rename to docs/build/tools/vscode-extension/index.md diff --git a/docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v1.excalidraw b/docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v1.excalidraw similarity index 100% rename from docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v1.excalidraw rename to docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v1.excalidraw diff --git a/docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v1.png b/docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v1.png similarity index 100% rename from docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v1.png rename to docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v1.png diff --git a/docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v2.excalidraw b/docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v2.excalidraw similarity index 100% rename from docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v2.excalidraw rename to docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v2.excalidraw diff --git a/docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v2.png b/docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v2.png similarity index 100% rename from docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v2.png rename to docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v2.png diff --git a/docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.1.excalidraw b/docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.1.excalidraw similarity index 100% rename from docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.1.excalidraw rename to docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.1.excalidraw diff --git a/docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.1.png b/docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.1.png similarity index 100% rename from docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.1.png rename to docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.1.png diff --git a/docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.2.excalidraw b/docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.2.excalidraw similarity index 100% rename from docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.2.excalidraw rename to docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.2.excalidraw diff --git a/docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.2.png b/docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.2.png similarity index 100% rename from docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.2.png rename to docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.2.png diff --git a/docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.excalidraw b/docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.excalidraw similarity index 100% rename from docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.excalidraw rename to docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.excalidraw diff --git a/docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.png b/docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.png similarity index 100% rename from docs/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.png rename to docs/build/tools/wallet-provider-spec/assets/fcl-ars-auth-v3.png diff --git a/docs/tools/wallet-provider-spec/authorization-function.md b/docs/build/tools/wallet-provider-spec/authorization-function.md similarity index 100% rename from docs/tools/wallet-provider-spec/authorization-function.md rename to docs/build/tools/wallet-provider-spec/authorization-function.md diff --git a/docs/tools/wallet-provider-spec/custodial.md b/docs/build/tools/wallet-provider-spec/custodial.md similarity index 94% rename from docs/tools/wallet-provider-spec/custodial.md rename to docs/build/tools/wallet-provider-spec/custodial.md index 9b3b544211..e2be12e13d 100644 --- a/docs/tools/wallet-provider-spec/custodial.md +++ b/docs/build/tools/wallet-provider-spec/custodial.md @@ -15,13 +15,13 @@ Public identity will be stored on chain as a resource, it will be publicly avail In FCL getting a users public identity will be as easy as: ```javascript -import {user} from "@onflow/fcl" +import { user } from '@onflow/fcl'; -const identity = await user(flowAddress).snapshot() +const identity = await user(flowAddress).snapshot(); // ^ // `------ The public identity for `flowAddress` -const unsub = user(flowAddress).subscribe(identity => console.log(identity)) +const unsub = user(flowAddress).subscribe((identity) => console.log(identity)); // ^ // `------- The public identity for `flowAddress` ``` @@ -36,15 +36,15 @@ We highly recommend Wallet Providers let the user see what scopes are being requ Consumers of identities in FCL should always assume all data is optional, and should store as little as possible, FCL will make sure the users always see the latest. ```javascript -import {config, currentUser, authenticate} from "@onflow/fcl" +import { config, currentUser, authenticate } from '@onflow/fcl'; -config.put("challenge.scope", "email") // request the email scope +config.put('challenge.scope', 'email'); // request the email scope -const unsub = currentUser().subscribe(identity => console.log(identity)) +const unsub = currentUser().subscribe((identity) => console.log(identity)); // ^ // `------- The private identity for the currentUser -authenticate() // trigger the challenge step (authenticate the user via a wallet provider) +authenticate(); // trigger the challenge step (authenticate the user via a wallet provider) ``` # Identity Data @@ -66,7 +66,7 @@ If we can give dapp developers a solid foundation of usable information that is Private data on the other hand has more use cases than general data. It is pretty easy to imagine ordering something and needing information like contact details and where to ship something. -Eventually we would love to see that sort of thing handled completely on-chain, securely, privately and safely, but in the interm it probably means storing a copy of data in a database when its needed, and allowed by a user. +Eventually we would love to see that sort of thing handled completely onchain, securely, privately and safely, but in the interm it probably means storing a copy of data in a database when its needed, and allowed by a user. The process of a dapp receiving private data is as follows: @@ -141,17 +141,17 @@ Iframe will look like this: ```javascript parent.postMessage( { - type: "FCL::CHALLENGE::RESPONSE", // used by FCL to know what kind of message this is - addr: "0xab4U9KMf", - paddr: "0xhMgqTff86", - code: "afseasdfsadf", + type: 'FCL::CHALLENGE::RESPONSE', // used by FCL to know what kind of message this is + addr: '0xab4U9KMf', + paddr: '0xhMgqTff86', + code: 'afseasdfsadf', exp: 1650400809517, - hks: "https://provider.com/hooks", - nonce: "asdfasdfasdf", + hks: 'https://provider.com/hooks', + nonce: 'asdfasdfasdf', l6n: decodeURIComponent(l6n), }, - decodeURIComponent(l6n) -) + decodeURIComponent(l6n), +); ``` FCL should now have everything it needs to collect the Public, Private and Wallet Provider Info. diff --git a/docs/tools/wallet-provider-spec/index.md b/docs/build/tools/wallet-provider-spec/index.md similarity index 100% rename from docs/tools/wallet-provider-spec/index.md rename to docs/build/tools/wallet-provider-spec/index.md diff --git a/docs/tools/wallet-provider-spec/provable-authn.md b/docs/build/tools/wallet-provider-spec/provable-authn.md similarity index 100% rename from docs/tools/wallet-provider-spec/provable-authn.md rename to docs/build/tools/wallet-provider-spec/provable-authn.md diff --git a/docs/tools/wallet-provider-spec/user-signature.md b/docs/build/tools/wallet-provider-spec/user-signature.md similarity index 100% rename from docs/tools/wallet-provider-spec/user-signature.md rename to docs/build/tools/wallet-provider-spec/user-signature.md diff --git a/docs/ecosystem/defi-liquidity/add-token-to-metamask.md b/docs/defi/add-token-to-metamask.md similarity index 97% rename from docs/ecosystem/defi-liquidity/add-token-to-metamask.md rename to docs/defi/add-token-to-metamask.md index 7aec96d720..efea180cd5 100644 --- a/docs/ecosystem/defi-liquidity/add-token-to-metamask.md +++ b/docs/defi/add-token-to-metamask.md @@ -2,7 +2,7 @@ title: How To Add Token To MetaMask description: How to import a Flow token in MetaMask sidebar_label: Add Token To MetaMask -sidebar_position: 3 +sidebar_position: 6 keywords: - add token to MetaMask - MetaMask Flow EVM @@ -88,7 +88,7 @@ You can find token contract addresses on: If you're unsure, check the Flow EVM block explorer at [evm.flowscan.io][5] [1]: https://evm.flowscan.io/tokens -[2]: /docs/ecosystem/defi-liquidity/defi-contracts.md +[2]: /defi/defi-contracts-mainnet [3]: https://dexscreener.com/flowevm [4]: https://www.geckoterminal.com/flow-evm/pools [5]: https://evm.flowscan.io diff --git a/docs/ecosystem/defi-liquidity/add_custom_token_metamask.gif b/docs/defi/add_custom_token_metamask.gif similarity index 100% rename from docs/ecosystem/defi-liquidity/add_custom_token_metamask.gif rename to docs/defi/add_custom_token_metamask.gif diff --git a/docs/ecosystem/defi-liquidity/add_wrapped_flow_to_metamask.jpg b/docs/defi/add_wrapped_flow_to_metamask.jpg similarity index 100% rename from docs/ecosystem/defi-liquidity/add_wrapped_flow_to_metamask.jpg rename to docs/defi/add_wrapped_flow_to_metamask.jpg diff --git a/docs/ecosystem/defi-liquidity/add_wrapped_flow_to_metamask_2.png b/docs/defi/add_wrapped_flow_to_metamask_2.png similarity index 100% rename from docs/ecosystem/defi-liquidity/add_wrapped_flow_to_metamask_2.png rename to docs/defi/add_wrapped_flow_to_metamask_2.png diff --git a/docs/defi/band-oracle.md b/docs/defi/band-oracle.md new file mode 100644 index 0000000000..d86e692e84 --- /dev/null +++ b/docs/defi/band-oracle.md @@ -0,0 +1,289 @@ +--- +id: band-oracle +title: Band Oracle on Flow +description: Band Protocol provides decentralized oracle services on Flow, delivering real-time price feeds and data for DeFi applications. +keywords: + - Band Oracle + - Band Protocol + - oracle + - price feeds + - data feeds + - DeFi + - Flow blockchain + - Flow Cadence + - smart contracts +sidebar_position: 7 +sidebar_label: Band Oracle +--- + +import CopyButton from '@site/src/components/CopyButton'; + +# Band Oracle with Cadence + +The Band Protocol Oracle contract enables Flow blockchain applications to access real-time price data from the [Band Protocol Oracle network](https://faq.bandprotocol.com/). The oracle provides a comprehensive set of cryptocurrency and fiat currency price quotes from the Band Standard Dataset, making them available to any Cadence application, contract, or transaction. + +## Contract Addresses + +| Network | Address | [CLI](https://developers.flow.com/build/tools/flow-cli/dependency-manager) | Explorer | +| ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- | +| Testnet | `0x9fb6606c300b5051` | | [View Contract](https://testnet.flowscan.io/contract/A.9fb6606c300b5051.BandOracle) | +| Mainnet | `0x6801a6222ebf784a` | | [View Contract](https://flowscan.io/contract/A.6801a6222ebf784a.BandOracle) | + +## Supported Symbols + +### Cryptocurrency Pairs (against USD) + +- **Major**: ETH, FLOW, USDC, USDT, WBTC, BNB, XRP, ADA, DOGE, POL (MATIC) +- **Layer 1**: SOL, DOT, AVAX, ATOM, XLM, TRX, SUI +- **DeFi**: AAVE, LINK, CRV, OP, UNI, SUSHI, CAKE, DYDX, 1INCH, BAT +- **Others**: LTC, SHIB, DAI, FTM + +### Fiat Currency Pairs (against USD) + +- **Asian**: KRW, INR, HKD, TWD, THB, JPY, MYR, PHP, CNY, SGD +- **European**: PLN, CZK, EUR, GBP, CHF, RUB, SEK, TRY +- **Americas**: BRL, CAD +- **Oceanic**: AUD, NZD + +## How It Works + +### Architecture + +The Band Oracle contract maintains a decentralized price feed system with three key components: + +1. **Data Storage**: Price data is stored in a contract-level dictionary `symbolsRefData: {String: RefData}` where each symbol maps to its latest price information. + +2. **Data Updates**: Authorized BandChain relayers continuously update price data from the Band Protocol network to keep prices current. + +3. **Data Access**: Any user or contract can query the latest price data through public functions, enabling real-time price integrations. + +### Data Structure + +Price data is stored using the `RefData` struct: + +```cadence +access(all) struct RefData { + // USD-rate, multiplied by 1e9 + access(all) var rate: UInt64 + // UNIX epoch when data was last resolved + access(all) var timestamp: UInt64 + // BandChain request identifier for this data + access(all) var requestID: UInt64 +} +``` + +When querying prices, you receive a `ReferenceData` struct: + +```cadence +access(all) struct ReferenceData { + // Rate as integer multiplied by 1e18 + access(all) var integerE18Rate: UInt256 + // Rate as a fixed-point decimal + access(all) var fixedPointRate: UFix64 + // Timestamp of base symbol data + access(all) var baseTimestamp: UInt64 + // Timestamp of quote symbol data + access(all) var quoteTimestamp: UInt64 +} +``` + +### Data Normalization + +All price data is stored with a USD conversion rate. When you query for price conversions between two non-USD symbols, the contract derives the rate from their respective USD rates. For example, to get ETH/EUR, the contract calculates: `(ETH/USD) / (EUR/USD)`. + +## Features + +### Price Queries + +- Query any supported symbol pair in real-time +- Get both integer (e18 precision) and fixed-point decimal rates +- Access timestamp information to verify data freshness +- Track BandChain request IDs for transparency + +### Fee Structure + +- Configurable fee system for oracle usage (currently set to zero) +- Fee collected in FLOW tokens +- Query current fee using `BandOracle.getFee()` + +### Event Monitoring + +The contract emits events to notify applications of updates: + +```cadence +// Emitted when symbol prices are updated +access(all) event BandOracleSymbolsUpdated( + symbols: [String], + relayerID: UInt64, + requestID: UInt64 +) + +// Emitted when a symbol is removed +access(all) event BandOracleSymbolRemoved(symbol: String) +``` + +## Usage Guide + +### Basic Price Query (Transaction) + +To query price data from a transaction: + +```cadence +import "BandOracle" +import "FlowToken" +import "FungibleToken" + +transaction(baseSymbol: String, quoteSymbol: String) { + + let payment: @{FungibleToken.Vault} + + prepare(acct: auth(BorrowValue) &Account) { + // Borrow reference to user's FLOW vault + let vaultRef = acct.storage.borrow( + from: /storage/flowTokenVault + ) ?? panic("Cannot borrow reference to signer's FLOW vault") + + // Withdraw payment for oracle fee + self.payment <- vaultRef.withdraw(amount: BandOracle.getFee()) + } + + execute { + // Get reference data + let priceData = BandOracle.getReferenceData( + baseSymbol: baseSymbol, + quoteSymbol: quoteSymbol, + payment: <- self.payment + ) + + log("Rate (fixed-point): ".concat(priceData.fixedPointRate.toString())) + log("Rate (integer e18): ".concat(priceData.integerE18Rate.toString())) + log("Base timestamp: ".concat(priceData.baseTimestamp.toString())) + log("Quote timestamp: ".concat(priceData.quoteTimestamp.toString())) + } +} +``` + +### Example: ETH/USD Price + +```cadence +// Get ETH price in USD +let priceData = BandOracle.getReferenceData( + baseSymbol: "ETH", + quoteSymbol: "USD", + payment: <- flowPayment +) +// priceData.fixedPointRate contains ETH price in USD +``` + +### Example: Cross-Currency Conversion + +```cadence +// Get EUR price in JPY +let priceData = BandOracle.getReferenceData( + baseSymbol: "EUR", + quoteSymbol: "JPY", + payment: <- flowPayment +) +// priceData.fixedPointRate contains EUR/JPY exchange rate +``` + +### Contract Integration + +Here's how to integrate the oracle into your smart contract: + +```cadence +import "BandOracle" +import "FlowToken" +import "FungibleToken" + +access(all) contract MyDeFiContract { + + // Store a vault to pay for oracle fees + access(self) let oracleFeeVault: @{FungibleToken.Vault} + + access(all) fun getTokenPriceInUSD(tokenSymbol: String): UFix64 { + // Withdraw payment for oracle + let payment <- self.oracleFeeVault.withdraw( + amount: BandOracle.getFee() + ) + + // Query the oracle + let priceData = BandOracle.getReferenceData( + baseSymbol: tokenSymbol, + quoteSymbol: "USD", + payment: <- payment + ) + + return priceData.fixedPointRate + } + + access(all) fun swapTokens(amount: UFix64, maxPrice: UFix64) { + // Get current price + let currentPrice = self.getTokenPriceInUSD(tokenSymbol: "ETH") + + // Verify price is acceptable + if currentPrice > maxPrice { + panic("Price too high") + } + + // Proceed with swap logic... + } + + init() { + // Initialize vault for oracle fees + self.oracleFeeVault <- FlowToken.createEmptyVault( + vaultType: Type<@FlowToken.Vault>() + ) + } +} +``` + +## Best Practices + +### 1. Listen for Price Updates + +Monitor the `BandOracleSymbolsUpdated` event to keep your contract's stored prices up-to-date: + +```cadence +// Listen for this event in your application +access(all) event BandOracleSymbolsUpdated( + symbols: [String], + relayerID: UInt64, + requestID: UInt64 +) +``` + +When you detect an update for symbols your app uses, trigger a transaction to refresh your stored prices. + +## Advanced Features + +### Converting Between Number Formats + +The contract provides a utility function to convert between integer and fixed-point representations: + +```cadence +// Convert e18 integer to fixed-point decimal +let fixedPoint = BandOracle.e18ToFixedPoint(rate: integerE18Rate) +``` + +### Fee Management + +For contract administrators, the oracle supports dynamic fee configuration: + +```cadence +// Query current fee +let currentFee = BandOracle.getFee() + +// Fee can be updated by the fee collector (admin only) +// feeCollector.setFee(fee: 0.001) // 0.001 FLOW per query +``` + +## Resources + +- [Band Protocol FAQ](https://faq.bandprotocol.com/) +- [Band Standard Dataset](https://data.bandprotocol.com/) +- [Cadence Language Reference](https://cadence-lang.org/) + +--- + +**Note**: The oracle currently charges no fees for usage, but this may change in the future. Always check `BandOracle.getFee()` before querying to ensure your contract has sufficient FLOW tokens allocated. diff --git a/docs/ecosystem/defi-liquidity/cross-chain-swaps.md b/docs/defi/cross-chain-swaps.md similarity index 90% rename from docs/ecosystem/defi-liquidity/cross-chain-swaps.md rename to docs/defi/cross-chain-swaps.md index b16e5004ec..a0f99ed111 100644 --- a/docs/ecosystem/defi-liquidity/cross-chain-swaps.md +++ b/docs/defi/cross-chain-swaps.md @@ -16,24 +16,24 @@ keywords: - Stargate - LayerZero - Celer -sidebar_position: 2 +sidebar_position: 5 sidebar_label: Cross-chain swaps on Flow EVM --- import Details from '@theme/Details'; -The following bridges offer cross-chain swaps (token bridging including swap) to or from Flow EVM. +The following bridges offer cross-chain swaps (token bridging including swap) to or from Flow EVM. -## Liquidity Pool Based Cross-chain Swaps +## Liquidity Pool Based Cross-chain Swaps ### Stargate -[Stargate](https://stargate.finance) employs unified liquidity pools shared across multiple chains to enable native asset transfers and cross-chain swaps +[Stargate](https://stargate.finance) employs unified liquidity pools shared across multiple chains to enable native asset transfers and cross-chain swaps without wrapped tokens. It is built on LayerZero's cross-chain messaging protocol. ### Celer -[Celer](https://cbridge.celer.network) is a hybrid liquidity network bridge that combines multiple bridging models and is based on the Celer +[Celer](https://cbridge.celer.network) is a hybrid liquidity network bridge that combines multiple bridging models and is based on the Celer Inter-Chain Messaging Framework. ## Intent Based Cross-chain Swaps @@ -46,7 +46,5 @@ Intent based bridges do not depend on pre-funded liquidity pools which can impro ### DeBridge -[DeBridge](https://app.debridge.finance/) achieves efficient cross-chain swaps with minimal slippage in a decentralized environment +[DeBridge](https://app.debridge.finance/) achieves efficient cross-chain swaps with minimal slippage in a decentralized environment through a peer-to-peer transaction mechanism. - - diff --git a/docs/defi/defi-contracts-mainnet.md b/docs/defi/defi-contracts-mainnet.md new file mode 100644 index 0000000000..1971cd5aa5 --- /dev/null +++ b/docs/defi/defi-contracts-mainnet.md @@ -0,0 +1,204 @@ +--- +id: defi-contracts-mainnet +title: DeFi Contracts on Flow Mainnet +description: A reference table of frequently used DeFi contracts on Flow, including their addresses for both Flow EVM and Flow Cadence. +keywords: + - DeFi contracts + - Flow blockchain + - Flow EVM + - Flow Cadence + - Flow EVM Mainnet + - Flow Cadence Mainnet + - stablecoins + - wrapped assets + - AMMs + - DEXs + - KittyPunch + - PunchSwap +sidebar_position: 3 +sidebar_label: DeFi Contracts Mainnet +--- + +import StablecoinsWrappedAssetsTable from '@site/src/components/defi-contracts/StablecoinsWrappedAssetsTable'; +import CopyButton from '@site/src/components/CopyButton'; + +Flow is a Layer 1 blockchain that supports EVM equivalency, offering two environments Flow EVM and Flow Cadence. Fungible and non-fungible tokens can seamlessly transfer between these environments via the native VM token bridge. As a result, many tokens have both a Flow EVM mainnet contract address and a Flow Cadence mainnet contract address, allowing developers to choose their preferred environment. + +Below is a list of commonly used DeFi contracts on Flow Mainnet: + +[Switch to DeFi Contracts on Testnet](./defi-contracts-testnet.md) + +## Stablecoins & Wrapped Assets + +#### Flow EVM Mainnet + + + +#### Flow Cadence Mainnet + + + +## AMMs & DEXs + +#### Flow EVM Mainnet FlowSwap + +| Contract | EVM Mainnet Address | +| --------------------------------------------- | -------------------------------------------- | +| [UniswapV2Factory (FlowSwap)][38] | `0x681D1bFE03522e0727730Ba02a05CD3C0a08fa30` | +| [UniswapV2Router02 (FlowSwap)][39] | `0x2B30D97457d44dE9fb0329D9a2C1DF6B7ae1401d` | +| [UniswapV2Pair (FlowSwap)][40] | `0x48d63C4E4481fd0A01Fb82A3B191C6685c361f02` | +| [UniswapV3Factory (FlowSwap)][41] | `0xca6d7Bb03334bBf135902e1d919a5feccb461632` | +| [NonfungiblePositionManager (FlowSwap)][42] | `0xf7F20a346E3097C7d38afDDA65c7C802950195C7` | +| [SwapRouter02 (FlowSwap)][43] | `0xeEDC6Ff75e1b10B903D9013c358e446a73d35341` | +| [QuoterV2 (FlowSwap)][44] | `0x370A8DF17742867a44e56223EC20D82092242C85` | +| [V3Migrator (FlowSwap)][45] | `0x5C65D5C7E0154f519B7dC4558915A7016F41aa50` | +| [UniswapV3Staker (FlowSwap)][46] | `0x990A0564B7d90656494Ba7A7E1e874038cc35f5d` | +| [TickLens (FlowSwap)][47] | `0x513A58591c8E502543D629748076857a71C6079D` | +| [NFTDescriptor (FlowSwap)][48] | `0x99187C0a0AF166b40C393FAE5FDaC688ed5b6989` | +| [v3_nft_position_descriptor (FlowSwap)][49] | `0x36D8296B9B73dE9d5Ec09ACc6a7c02cC40Ad9780` | +| [TransparentUpgradeableProxy (FlowSwap)][50] | `0xB231Aa6F8636373f5233eeaD13FFEB199659d484` | +| [UniswapV3Pool (FlowSwap)][51] | `0xd21C58aDaf1d1119FE40413b45A5f43d23d58DF3` | +| [UniversalRouter (FlowSwap)][52] | `0x5fE87847fe20a6C30921620F52B06a4A3740aa61` | +| [Permit2 (FlowSwap)][53] | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | +| [FusionXInterfaceMulticall (FlowSwap)][54] | `0x8B5eB800B8d9cF702ff3DD0047ac31bBD411B82a` | +| [proxy_admin (FlowSwap)][55] | `0x026932f97995201527B4c9Bc2ea6854C02BB0AdC` | + +#### Flow EVM Mainnet KittyPunch + +| Contract Name | Flow EVM Mainnet Address | Docs | +| -------------------------------------------- | -------------------------------------------- | ---------------------- | +| [StableKittyFactoryNG (KittyPunch)][1] | `0x4412140D52C1F5834469a061927811Abb6026dB7` | [Docs][kittypunch-doc] | +| [TwoKittyFactory (KittyPunch)][2] | `0xf0E48dC92f66E246244dd9F33b02f57b0E69fBa9` | [Docs][kittypunch-doc] | +| [TriKittyFactory (KittyPunch)][3] | `0xebd098c60b1089f362AC9cfAd9134CBD29408226` | [Docs][kittypunch-doc] | +| [KittyRouterNgPoolsOnly (KittyPunch)][4] | `0x87048a97526c4B66b71004927D24F61DEFcD6375` | [Docs][kittypunch-doc] | +| [PunchSwapV2Router02 (KittyPunch)][5] | `0xf45AFe28fd5519d5f8C1d4787a4D5f724C0eFa4d` | [Docs][kittypunch-doc] | +| [PunchSwapV2Factory (KittyPunch)][6] | `0x29372c22459a4e373851798bFd6808e71EA34A71` | [Docs][kittypunch-doc] | +| [TrenchesTokensBuyer (KittyPunch)][7] | `0x6D0e081Acc28eA9ee6b7fD293eC03F97147b026d` | [Docs][kittypunch-doc] | + +#### Flow Cadence Mainnet + +| Contract Name | Flow Cadence Mainnet Address | [CLI](https://developers.flow.com/build/tools/flow-cli/dependency-manager) | Docs | +| ---------------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| [SwapFactory (IncrementFi)][22] | `0xb063c16cac85dbd1` | | [Docs][incrementfi-doc] | +| [SwapPair (IncrementFi)][23] | `0xecbda466e7f191c7` | | [Docs][incrementfi-doc] | +| [SwapError (IncrementFi)][24] | `0xb78ef7afa52ff906` | | [Docs][incrementfi-doc] | +| [SwapInterfaces (IncrementFi)][25] | `0xb78ef7afa52ff906` | | [Docs][incrementfi-doc] | +| [SwapConfig (IncrementFi)][26] | `0xb78ef7afa52ff906` | | [Docs][incrementfi-doc] | +| [SwapRouter (IncrementFi)][27] | `0xa6850776a94e6551` | | [Docs][incrementfi-doc] | + +## Bridges & Cross-Chain Messaging + +| Bridge / Protocol | Reference Docs | +| -------------------------------------------- | ------------------------ | +| Stargate Bridge ([stargate.finance][8]) | [Mainnet Contracts][9] | +| Hyperlane Bridge ([trump.hyperlane.xyz][10]) | [Mainnet Contracts][11] | +| Flow Bridge ([bridge.flow.com][12]) | [Superbridge Docs][13] | +| Celer cBridge ([cbridge.celer.network][14]) | [Celer cBridge Docs][15] | +| DeBridge ([app.debridge.finance][34]) | [DeBridge Contracts][35] | +| Relay ([relay.link][36]) | [Relay Contracts][37] | +| LayerZero | [Mainnet Contracts][16] | +| Axelar | [Axelar Docs][17] | + +## Omni Fungible Tokens (PYUSD → USDF) + +#### Solana Mainnet + +| Contract Name | Contract Address | +| -------------------- | ---------------------------------------------- | +| PYUSD Program ID | `28EyPNAi9BMTvGuCaQrptMXjpWUi7wx8SxAFVoSZxSXe` | +| PYUSD Mint | `2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo` | +| PYUSD Mint Authority | `22mKJkKjGEQ3rampp5YKaSsaYZ52BUkcnUN6evXGsXzz` | +| PYUSD Escrow | `6z3QyVS36nQ9fk2YvToxqJqXqtAFsSijqgHxpzKyG5xn` | +| PYUSD OFT Store | `2KUb8dcZR9LyrSg4RdkQx91xX6mPQLpS1MEo6gwfvLZk` | + +#### Ethereum Mainnet + +| Contract Name | Contract Address | +| ------------- | -------------------------------------------- | +| PYUSD Token | `0x6c3ea9036406852006290770BEdFcAbA0e23A0e8` | +| PYUSD Locker | `0xFA0e06B54986ad96DE87a8c56Fea76FBD8d493F8` | + +## Oracles + +#### Flow EVM Mainnet + +| Contract Name | Flow EVM Mainnet Address | +| ------------------------------ | -------------------------------------------- | +| [ERC1967Proxy (Pyth)][18] | `0x2880aB155794e7179c9eE2e38200202908C17B43` | +| [ERC1967Proxy (Stork)][28] | `0xacC0a0cF13571d30B4b8637996F5D6D774d4fd62` | + +#### Flow Cadence Mainnet + +| Contract Name | Flow Cadence Mainnet Address | [CLI](https://developers.flow.com/build/tools/flow-cli/dependency-manager) | Docs | +| ----------------------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| [PublicPriceOracle (IncrementFi)][19] | `0xec67451f8a58216a` | | [Docs][incrementfi-doc] | +| [BandOracle (Band) Protocol][33] | `0x6801a6222ebf784a` | | [Docs][band-oracle-doc] | + +## Ethereum Attestation Service + +More information can be found on the Credora docs site for [EAS on Flow](https://credora.gitbook.io/eas-for-flow). + +| Contract Name | Flow EVM Mainnet Address | +| ------------------------------------------------------- | -------------------------------------------- | +| [SchemaRegistry (Ethereum Attestation Service)][20] | `0xB0cF748a05AEA8D59e15834446CFC95bcFF510F0` | +| [EAS (Ethereum Attestation Service)][21] | `0xc6376222F6E009A705a34dbF1dF72fEf8efB3964` | + +[1]: https://evm.flowscan.io/address/0x4412140D52C1F5834469a061927811Abb6026dB7?tab=contract +[2]: https://evm.flowscan.io/address/0xf0E48dC92f66E246244dd9F33b02f57b0E69fBa9?tab=contract +[3]: https://evm.flowscan.io/address/0xebd098c60b1089f362AC9cfAd9134CBD29408226?tab=contract +[4]: https://evm.flowscan.io/address/0x87048a97526c4B66b71004927D24F61DEFcD6375?tab=contract +[5]: https://evm.flowscan.io/address/0xf45AFe28fd5519d5f8C1d4787a4D5f724C0eFa4d?tab=contract +[6]: https://evm.flowscan.io/address/0x29372c22459a4e373851798bFd6808e71EA34A71?tab=contract +[7]: https://evm.flowscan.io/address/0x6D0e081Acc28eA9ee6b7fD293eC03F97147b026d?tab=contract +[8]: https://stargate.finance/bridge?srcChain=ethereum&srcToken=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&dstChain=flow&dstToken=0xF1815bd50389c46847f0Bda824eC8da914045D14 +[9]: https://stargateprotocol.gitbook.io/stargate/v2-developer-docs/technical-reference/mainnet-contracts#flow +[10]: https://trump.hyperlane.xyz/ +[11]: https://docs.hyperlane.xyz/docs/reference/addresses/mailbox-addresses +[12]: https://bridge.flow.com/ +[13]: https://docs.superbridge.app/ +[14]: https://cbridge.celer.network/1/747/USDC-intermediary +[15]: https://cbridge-docs.celer.network/tutorial/flow-cadence-bridging-guide +[16]: https://docs.layerzero.network/v1/developers/evm/technical-reference/deployed-contracts?chains=flow +[17]: https://docs.axelar.dev/validator/external-chains/flow/ +[18]: https://evm.flowscan.io/address/0x2880aB155794e7179c9eE2e38200202908C17B43?tab=contract +[19]: https://flowscan.io/contract/A.ec67451f8a58216a.PublicPriceOracle +[20]: https://evm.flowscan.io/address/0xB0cF748a05AEA8D59e15834446CFC95bcFF510F0?tab=contract +[21]: https://evm.flowscan.io/address/0xc6376222F6E009A705a34dbF1dF72fEf8efB3964?tab=contract +[22]: https://flowscan.io/contract/A.b063c16cac85dbd1.SwapFactory +[23]: https://flowscan.io/contract/A.ecbda466e7f191c7.SwapPair +[24]: https://flowscan.io/contract/A.b78ef7afa52ff906.SwapError +[25]: https://flowscan.io/contract/A.b78ef7afa52ff906.SwapInterfaces +[26]: https://flowscan.io/contract/A.b78ef7afa52ff906.SwapConfig +[27]: https://flowscan.io/contract/A.a6850776a94e6551.SwapRouter +[28]: https://evm.flowscan.io/address/0xacC0a0cF13571d30B4b8637996F5D6D774d4fd62?tab=contract +[29]: https://evm-testnet.flowscan.io/address/0x97900F59828Da4187607Cb8F84f49e3944199d18?tab=contract +[30]: https://evm-testnet.flowscan.io/address/0xBCF2dA8f82fb032A2474c92Ec5b70C95A83fc0cc?tab=contract +[31]: https://testnet.flowscan.io/contract/A.8232ce4a3aff4e94.PublicPriceOracle +[32]: https://testnet.flowscan.io/contract/A.9fb6606c300b5051.BandOracle +[33]: https://flowscan.io/contract/A.6801a6222ebf784a.BandOracle +[34]: https://app.debridge.finance/ +[35]: https://docs.debridge.finance/dln-the-debridge-liquidity-network-protocol/deployed-contracts +[36]: https://relay.link/bridge +[37]: https://docs.relay.link/resources/contract-addresses +[band-oracle-doc]: ./band-oracle +[incrementfi-doc]: https://docs.increment.fi/ +[kittypunch-doc]: https://kittypunch.gitbook.io/kittypunch-docs +[38]: https://www.flowscan.io/evm/contract/0x681D1bFE03522e0727730Ba02a05CD3C0a08fa30 +[39]: https://www.flowscan.io/evm/contract/0x2B30D97457d44dE9fb0329D9a2C1DF6B7ae1401d +[40]: https://www.flowscan.io/evm/contract/0x48d63C4E4481fd0A01Fb82A3B191C6685c361f02 +[41]: https://www.flowscan.io/evm/contract/0xca6d7Bb03334bBf135902e1d919a5feccb461632 +[42]: https://www.flowscan.io/evm/contract/0xf7F20a346E3097C7d38afDDA65c7C802950195C7 +[43]: https://www.flowscan.io/evm/contract/0xeEDC6Ff75e1b10B903D9013c358e446a73d35341 +[44]: https://www.flowscan.io/evm/contract/0x370A8DF17742867a44e56223EC20D82092242C85 +[45]: https://www.flowscan.io/evm/contract/0x5C65D5C7E0154f519B7dC4558915A7016F41aa50 +[46]: https://www.flowscan.io/evm/contract/0x990A0564B7d90656494Ba7A7E1e874038cc35f5d +[47]: https://www.flowscan.io/evm/contract/0x513A58591c8E502543D629748076857a71C6079D +[48]: https://www.flowscan.io/evm/contract/0x99187C0a0AF166b40C393FAE5FDaC688ed5b6989 +[49]: https://www.flowscan.io/evm/contract/0x36D8296B9B73dE9d5Ec09ACc6a7c02cC40Ad9780 +[50]: https://www.flowscan.io/evm/contract/0xB231Aa6F8636373f5233eeaD13FFEB199659d484 +[51]: https://www.flowscan.io/evm/contract/0xd21C58aDaf1d1119FE40413b45A5f43d23d58DF3 +[52]: https://www.flowscan.io/evm/contract/0x5fE87847fe20a6C30921620F52B06a4A3740aa61 +[53]: https://www.flowscan.io/evm/contract/0x000000000022D473030F116dDEE9F6B43aC78BA3 +[54]: https://www.flowscan.io/evm/contract/0x8B5eB800B8d9cF702ff3DD0047ac31bBD411B82a +[55]: https://www.flowscan.io/evm/contract/0x026932f97995201527B4c9Bc2ea6854C02BB0AdC + diff --git a/docs/defi/defi-contracts-testnet.md b/docs/defi/defi-contracts-testnet.md new file mode 100644 index 0000000000..0dcf9eda81 --- /dev/null +++ b/docs/defi/defi-contracts-testnet.md @@ -0,0 +1,246 @@ +--- +id: defi-contracts-testnet +title: DeFi Contracts on Flow Testnet +description: Frequently used DeFi contracts and resources on Flow **Testnet**, covering Flow EVM and Flow Cadence with addresses, explorers, and faucets. +keywords: + - Flow Testnet + - Flow EVM Testnet + - Flow Cadence Testnet + - DeFi contracts + - stablecoins + - wrapped assets + - AMMs + - DEXs + - oracles + - EAS +sidebar_position: 4 +sidebar_label: DeFi Contracts Testnet +--- + +import CopyButton from '@site/src/components/CopyButton'; + +Flow is a Layer 1 blockchain that supports EVM equivalency, offering two environments Flow EVM and Flow Cadence. Fungible and non-fungible tokens can seamlessly transfer between these environments via the native VM token bridge. As a result, many tokens have both a Flow EVM mainnet contract address and a Flow Cadence mainnet contract address, allowing developers to choose their preferred environment. + +Below is a list of commonly used DeFi contracts on Flow Testnet: + +[Switch to DeFi Contracts on Mainnet](./defi-contracts-mainnet.md) + +## Stablecoins & Wrapped Assets + +#### Flow EVM Testnet + +| Token | EVM Testnet Address | How to Get | +| ------------------------ | -------------------------------------------- | ----------- | +| FLOW (native, non-erc20) | — | [Faucet][1] | +| [WFLOW][2] | `0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e` | [Swap][28] | +| [MOET][3] | `0x51f5cc5f50afb81e8f23c926080fa38c3024b238` | [Swap][29] | +| [MockUSDC][4] | `0xd431955D55a99EF69BEb96BA34718d0f9fBc91b1` | [Swap][30] | +| [mUSDC][5] | `0x4154d5B0E2931a0A1E5b733f19161aa7D2fc4b95` | [Swap][31] | +| [PYUSD0][6] | `0xd7d43ab7b365f0d0789aE83F4385fA710FfdC98F` | [Swap][32] | +| [USD Flow][7] | `0xf2E5A325f7D678DA511E66B1c0Ad7D5ba4dF93D3` | — | +| [USDC.e][8] | `0x9B7550D337bB449b89C6f9C926C3b976b6f4095b` | — | +| [ankrFLOW][9] | `0xe132751AB5A14ac0bD3Cb40571a9248Ee7a2a9EA` | — | +| [ankrFLOWEVM][10] | `0x8E3DC6E937B560ce6a1Aaa78AfC775228969D16c` | — | +| [ETHf][11] | `0x059A77239daFa770977DD9f1E98632C3E4559848` | [Mint][14] | +| [BTCf][12] | `0x208d09d2a6Dd176e3e95b3F0DE172A7471C5B2d6` | [Mint][15] | +| [cbBTC][13] | `0x30F44C64725727F2001E6C1eF6e6CE9c7aB91dC3` | [Mint][16] | + +#### Flow Cadence Testnet + +| Token | Cadence Testnet Address | Cadence Contract Name | +| -------------------- | ----------------------- | ------------------------------------------------------------ | +| [FLOW][17] | `0x7e60df042a9c0868` | `FlowToken` | +| [MOET][18] | `0xd27920b6384e2a78` | `MOET` | +| [USDC][19] | `0xdfc20aee650fcbdf` | `EVMVMBridgedToken_d431955d55a99ef69beb96ba34718d0f9fbc91b1` | +| [mUSDC][20] | `0xdfc20aee650fcbdf` | `EVMVMBridgedToken_4154d5b0e2931a0a1e5b733f19161aa7d2fc4b95` | +| [USDF (Mock)][21] | `0xdfc20aee650fcbdf` | `EVMVMBridgedToken_d7d43ab7b365f0d0789ae83f4385fa710ffdc98f` | +| [USDF (PYUSD)][22] | `0xdfc20aee650fcbdf` | `EVMVMBridgedToken_f2e5a325f7d678da511e66b1c0ad7d5ba4df93d3` | +| [USDC.e (Celer)][23] | `0xdfc20aee650fcbdf` | `EVMVMBridgedToken_9b7550d337bb449b89c6f9c926c3b976b6f4095b` | +| [ankrFLOWEVM][24] | `0xdfc20aee650fcbdf` | `EVMVMBridgedToken_8e3dc6e937b560ce6a1aaa78afc775228969d16c` | +| [WETH][25] | `0xdfc20aee650fcbdf` | `EVMVMBridgedToken_059a77239dafa770977dd9f1e98632c3e4559848` | +| [WBTC][26] | `0xdfc20aee650fcbdf` | `EVMVMBridgedToken_208d09d2a6dd176e3e95b3f0de172a7471c5b2d6` | +| [cbBTC][27] | `0xdfc20aee650fcbdf` | `EVMVMBridgedToken_30f44c64725727f2001e6c1ef6e6ce9c7ab91dc3` | + +## Vaults + +#### Flow EVM Testnet + +| Contract | Address | +| -------------------- | -------------------------------------------- | +| [MockTauVault][69] | `0x72104434BEc686B47a72bCa9b998624238BD2Ffb` | +| [MockYieldVault][70] | `0x217aAC9594EcB6d3f6667A214CF579dd29ce78dd` | + +## AMMs & DEXs + +#### Flow EVM Testnet + +| Contract | EVM Testnet Address | +| -------------------------------------------- | -------------------------------------------- | +| [UniswapV2Factory (FlowSwap)][33] | `0x7d726261FB76B264fc20eA1f19D900D760136566` | +| [UniswapV2Router02 (FlowSwap)][34] | `0x524E1291c109BE27FDE48De97cAf0B3c0F02A68f` | +| [UniswapV2Pair (FlowSwap)][35] | `0x21E3aa01561d7D869785aAedB14130C5807C5A12` | +| [UniswapV3Factory (FlowSwap)][36] | `0x92657b195e22b69E4779BBD09Fa3CD46F0CF8e39` | +| [NonfungiblePositionManager (FlowSwap)][37] | `0x8b9F96390EC35d5859937c7c5D68Ff6D5CFC312f` | +| [SwapRouter02 (FlowSwap)][38] | `0x2Db6468229F6fB1a77d248Dbb1c386760C257804` | +| [QuoterV2 (FlowSwap)][39] | `0xA1e0E4CCACA34a738f03cFB1EAbAb16331FA3E2c` | +| [V3Migrator (FlowSwap)][40] | `0x00a101726ff770cd8ed53E8376b9440Bad40CAd9` | +| [UniswapV3Staker (FlowSwap)][41] | `0x04400857ad69EaA7dd6fEF1C329E80E50BD30b76` | +| [TickLens (FlowSwap)][42] | `0x36D9bDCbA840F5bcb95EE7bD54a86808aef6581F` | +| [NFTDescriptor (FlowSwap)][43] | `0x6982D5Cb80Cd7E2cb7C0d0B8452841471Bc84Bc2` | +| [v3_nft_position_descriptor (FlowSwap)][44] | `0x61f4e983A72d9BD8429154982A3d9fCF3A1D98d0` | +| [TransparentUpgradeableProxy (FlowSwap)][45] | `0xE0895150a7c84e8fB9fecCE72F4C80c130C80fDa` | +| [UniswapV3Pool (FlowSwap)][46] | `0xa4Db57e3d3c6674FA02a2f3a667d3C22Fe17efF4` | +| [UniversalRouter (FlowSwap)][47] | `0xB685ab04Dfef74c135A2ed4003441fF124AFF9a0` | +| [Permit2 (FlowSwap)][48] | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | +| [FusionXInterfaceMulticall (FlowSwap)][49] | `0x02b9B840CDCEe84510a02cc85f351CAaD41f46CE` | +| [proxy_admin (FlowSwap)][50] | `0xf4011F45A666dC7eC54445a710c3aae735F7E890` | +| [StableKittyFactoryNG (KittyPunch)][51] | `0x0699C35C0104e478f510531F5Dfc3F9313ae49D1` | +| [TwoKittyFactory (KittyPunch)][52] | `0xeaa5949471C7B31ae97D3a52483028aE595E8e83` | +| [TriKittyFactory (KittyPunch)][53] | `0x62aC6e05Bac04702bF744106499F72f200297121` | +| [KittyRouterNgPoolsOnly (KittyPunch)][54] | `0x70e8C797f698De61787A7275628713077723694` | +| [PunchSwapV2Router02 (KittyPunch)][55] | `0xeD53235cC3E9d2d464E9c408B95948836648870B` | +| [PunchSwapV2Factory (KittyPunch)][56] | `0x0f6C2EF40FA42B2F0E0a9f5987b2f3F8Af3C173f` | + +#### Flow Cadence Testnet + +| Contract | Cadence Testnet Address | [CLI](https://developers.flow.com/build/tools/flow-cli/dependency-manager) | +| ------------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| [StableSwapFactory (IncrementFi)][57] | `0x6ca93d49c45a249f` | | +| [SwapFactory (IncrementFi)][58] | `0x6ca93d49c45a249f` | | +| [SwapPair (IncrementFi)][59] | `0x7afd587a5d5e2efe` | | +| [SwapConfig (IncrementFi)][60] | `0x8d5b9dd833e176da` | | +| [SwapError (IncrementFi)][61] | `0x8d5b9dd833e176da` | | +| [SwapInterfaces (IncrementFi)][62] | `0x8d5b9dd833e176da` | | + +## Bridges & Cross-Chain Messaging + +| Bridge / Protocol | Reference Docs | +| ----------------------------- | ----------------- | +| PYUSD -> USDF (LayerZero OFT) | [GitHub Repo][63] | + +## Omni Fungible Tokens (PYUSD → USDF) + +#### Solana Devnet/Testnet + +| Contract Name | Contract Address | +| -------------------- | ---------------------------------------------- | +| PYUSD Program ID | `D6RHLYN7x69Cb5Y7dFj9T9uJrJCVT9Bt1LT71xHf7QqK` | +| PYUSD Mint | `CXk2AMBfi3TwaEL2468s6zP8xq9NxTXjp9gjMgzeUynM` | +| PYUSD Mint Authority | `A6v157j6XFJXwtT5VWXX7uLYTUrxcYGXB8R6rxrgr9hQ` | +| PYUSD Escrow | `FKt7QuGTkFWHVt7RVgtEsh3rVRZMaeCdQBseyQ9Vf1PN` | +| PYUSD OFT Store | `CFVgSccTEXbs3hN7gnCHx3FAa1L5j5StsKABTPuMaAYo` | + +#### Sepolia Testnet + +| Contract Name | Contract Address | +| ------------- | -------------------------------------------- | +| MyOFTAdapter | `0x9D6e122780974a917952D70646dD50D2C4f906ae` | +| PYUSDLocker | `0xb077Ef2833Fd7b426146839a86100708c37bfa65` | +| MyFungi | `0x39dBc26413e6eEe40265E4a7ddc5abDC64849781` | + +#### Arbitrum Sepolia Testnet + +| Contract Name | Contract Address | +| ------------- | -------------------------------------------- | +| MyOFTAdapter | `0xDD3BFfb358eF34C2964CB9ce29013D071d59094C` | +| PYUSDLocker | `0x4e2dCCAfe86719B7BFfAc3b1041031dDd07aF5fF` | +| MyFungi | `0x1605B1067Ce0D294786A09368f38063Df50C0e92` | + +## Oracles + +#### Flow EVM Testnet + +| Contract | EVM Testnet Address | +| ------------------------- | -------------------------------------------- | +| [Pyth (ERC1967Proxy)][68] | `0x2880aB155794e7179c9eE2e38200202908C17B43` | + +#### Flow Cadence Testnet + +| Contract Name | Flow Cadence Testnet Address | [CLI](https://developers.flow.com/build/tools/flow-cli/dependency-manager) | Docs | +| ----------------------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| [PublicPriceOracle.cdc (IncrementFi)][66] | `0x8232ce4a3aff4e94` | | [Docs][incrementfi-doc] | +| [BandOracle.cdc (Band)][67] | `0x9fb6606c300b5051` | | [Docs][band-oracle-doc] | + +## Ethereum Attestation Service + +More information can be found on the Credora docs site for [EAS on Flow](https://credora.gitbook.io/eas-for-flow). + +Testnet EAS Explorer: [https://flow-testnet.easscan.credora.io](https://flow-testnet.easscan.credora.io) + +| Contract Name | Flow EVM Testnet Address | +| ------------------------------------------------------- | -------------------------------------------- | +| [SchemaRegistry.sol (Ethereum Attestation Service)][64] | `0x97900F59828Da4187607Cb8F84f49e3944199d18` | +| [EAS.sol (Ethereum Attestation Service)][65] | `0xBCF2dA8f82fb032A2474c92Ec5b70C95A83fc0cc` | + +[1]: https://faucet.flow.com/fund-account +[2]: https://evm-testnet.flowscan.io/address/0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e +[3]: https://evm-testnet.flowscan.io/address/0x51f5cc5f50afb81e8f23c926080fa38c3024b238 +[4]: https://evm-testnet.flowscan.io/address/0xd431955D55a99EF69BEb96BA34718d0f9fBc91b1 +[5]: https://evm-testnet.flowscan.io/address/0x4154d5B0E2931a0A1E5b733f19161aa7D2fc4b95 +[6]: https://evm-testnet.flowscan.io/address/0xd7d43ab7b365f0d0789aE83F4385fA710FfdC98F +[7]: https://evm-testnet.flowscan.io/address/0xf2E5A325f7D678DA511E66B1c0Ad7D5ba4dF93D3 +[8]: https://evm-testnet.flowscan.io/address/0x9B7550D337bB449b89C6f9C926C3b976b6f4095b +[9]: https://evm-testnet.flowscan.io/address/0xe132751AB5A14ac0bD3Cb40571a9248Ee7a2a9EA +[10]: https://evm-testnet.flowscan.io/address/0x8E3DC6E937B560ce6a1Aaa78AfC775228969D16c +[11]: https://evm-testnet.flowscan.io/address/0x059A77239daFa770977DD9f1E98632C3E4559848 +[12]: https://evm-testnet.flowscan.io/address/0x208d09d2a6Dd176e3e95b3F0DE172A7471C5B2d6 +[13]: https://evm-testnet.flowscan.io/address/0x30F44C64725727F2001E6C1eF6e6CE9c7aB91dC3 +[14]: https://evm-testnet.flowscan.io/address/0x059A77239daFa770977DD9f1E98632C3E4559848?tab=read_write_contract#0x40c10f19 +[15]: https://evm-testnet.flowscan.io/address/0x208d09d2a6Dd176e3e95b3F0DE172A7471C5B2d6?tab=read_write_contract#0x40c10f19 +[16]: https://evm-testnet.flowscan.io/address/0x30F44C64725727F2001E6C1eF6e6CE9c7aB91dC3?tab=read_write_contract#0x40c10f19 +[17]: https://testnet.flowscan.io/contract/A.7e60df042a9c0868.FlowToken?tab=deployments +[18]: https://testnet.flowscan.io/contract/A.d27920b6384e2a78.MOET?tab=deployments +[19]: https://testnet.flowscan.io/contract/A.dfc20aee650fcbdf.EVMVMBridgedToken_d431955d55a99ef69beb96ba34718d0f9fbc91b1?tab=deployments +[20]: https://testnet.flowscan.io/contract/A.dfc20aee650fcbdf.EVMVMBridgedToken_4154d5b0e2931a0a1e5b733f19161aa7d2fc4b95?tab=deployments +[21]: https://testnet.flowscan.io/contract/A.dfc20aee650fcbdf.EVMVMBridgedToken_d7d43ab7b365f0d0789ae83f4385fa710ffdc98f?tab=deployments +[22]: https://testnet.flowscan.io/contract/A.dfc20aee650fcbdf.EVMVMBridgedToken_f2e5a325f7d678da511e66b1c0ad7d5ba4df93d3?tab=deployments +[23]: https://testnet.flowscan.io/contract/A.dfc20aee650fcbdf.EVMVMBridgedToken_9b7550d337bb449b89c6f9c926c3b976b6f4095b?tab=deployments +[24]: https://testnet.flowscan.io/contract/A.dfc20aee650fcbdf.EVMVMBridgedToken_8e3dc6e937b560ce6a1aaa78afc775228969d16c?tab=deployments +[25]: https://testnet.flowscan.io/contract/A.dfc20aee650fcbdf.EVMVMBridgedToken_059a77239dafa770977dd9f1e98632c3e4559848?tab=deployments +[26]: https://testnet.flowscan.io/contract/A.dfc20aee650fcbdf.EVMVMBridgedToken_208d09d2a6dd176e3e95b3f0de172a7471c5b2d6?tab=deployments +[27]: https://testnet.flowscan.io/contract/A.dfc20aee650fcbdf.EVMVMBridgedToken_30f44c64725727f2001e6c1ef6e6ce9c7ab91dc3?tab=deployments +[28]: https://flowswap.io/swap?chain=flow-testnet&inputCurrency=NATIVE&outputCurrency=0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e +[29]: https://flowswap.io/swap?chain=flow-testnet&inputCurrency=NATIVE&outputCurrency=0x51F5cC5f50afB81e8F23C926080FA38C3024b238 +[30]: https://flowswap.io/swap?chain=flow-testnet&inputCurrency=NATIVE&outputCurrency=0xd431955D55a99EF69BEb96BA34718d0f9fBc91b1 +[31]: https://flowswap.io/swap?chain=flow-testnet&inputCurrency=NATIVE&outputCurrency=0x4154d5B0E2931a0A1E5b733f19161aa7D2fc4b95 +[32]: https://flowswap.io/swap?chain=flow-testnet&inputCurrency=NATIVE&outputCurrency=0xd7d43ab7b365f0d0789aE83F4385fA710FfdC98F +[33]: https://testnet.flowscan.io/evm/contract/0x7d726261FB76B264fc20eA1f19D900D760136566 +[34]: https://testnet.flowscan.io/evm/contract/0x524E1291c109BE27FDE48De97cAf0B3c0F02A68f +[35]: https://testnet.flowscan.io/evm/contract/0x21E3aa01561d7D869785aAedB14130C5807C5A12 +[36]: https://testnet.flowscan.io/evm/contract/0x92657b195e22b69E4779BBD09Fa3CD46F0CF8e39 +[37]: https://testnet.flowscan.io/evm/contract/0x8b9F96390EC35d5859937c7c5D68Ff6D5CFC312f +[38]: https://testnet.flowscan.io/evm/contract/0x2Db6468229F6fB1a77d248Dbb1c386760C257804 +[39]: https://testnet.flowscan.io/evm/contract/0xA1e0E4CCACA34a738f03cFB1EAbAb16331FA3E2c +[40]: https://testnet.flowscan.io/evm/contract/0x00a101726ff770cd8ed53E8376b9440Bad40CAd9 +[41]: https://testnet.flowscan.io/evm/contract/0x04400857ad69EaA7dd6fEF1C329E80E50BD30b76 +[42]: https://testnet.flowscan.io/evm/contract/0x36D9bDCbA840F5bcb95EE7bD54a86808aef6581F +[43]: https://testnet.flowscan.io/evm/contract/0x6982D5Cb80Cd7E2cb7C0d0B8452841471Bc84Bc2 +[44]: https://testnet.flowscan.io/evm/contract/0x61f4e983A72d9BD8429154982A3d9fCF3A1D98d0 +[45]: https://testnet.flowscan.io/evm/contract/0xE0895150a7c84e8fB9fecCE72F4C80c130C80fDa +[46]: https://testnet.flowscan.io/evm/contract/0xa4Db57e3d3c6674FA02a2f3a667d3C22Fe17efF4 +[47]: https://testnet.flowscan.io/evm/contract/0xB685ab04Dfef74c135A2ed4003441fF124AFF9a0 +[48]: https://testnet.flowscan.io/evm/contract/0x000000000022D473030F116dDEE9F6B43aC78BA3 +[49]: https://testnet.flowscan.io/evm/contract/0x02b9B840CDCEe84510a02cc85f351CAaD41f46CE +[50]: https://testnet.flowscan.io/evm/contract/0xf4011F45A666dC7eC54445a710c3aae735F7E890 +[51]: https://evm-testnet.flowscan.io/address/0x0699C35C0104e478f510531F5Dfc3F9313ae49D1 +[52]: https://evm-testnet.flowscan.io/address/0xeaa5949471C7B31ae97D3a52483028aE595E8e83 +[53]: https://evm-testnet.flowscan.io/address/0x62aC6e05Bac04702bF744106499F72f200297121 +[54]: https://evm-testnet.flowscan.io/address/0x70e8C797f698De61787A7275628713077723694 +[55]: https://evm-testnet.flowscan.io/address/0xeD53235cC3E9d2d464E9c408B95948836648870B +[56]: https://evm-testnet.flowscan.io/address/0x0f6C2EF40FA42B2F0E0a9f5987b2f3F8Af3C173f +[57]: https://testnet.flowscan.io/contract/A.6ca93d49c45a249f.StableSwapFactory?tab=deployments +[58]: https://testnet.flowscan.io/contract/A.6ca93d49c45a249f.SwapFactory?tab=deployments +[59]: https://testnet.flowscan.io/contract/A.7afd587a5d5e2efe.SwapPair?tab=deployments +[60]: https://testnet.flowscan.io/contract/A.8d5b9dd833e176da.SwapConfig?tab=deployments +[61]: https://testnet.flowscan.io/contract/A.8d5b9dd833e176da.SwapError?tab=deployments +[62]: https://testnet.flowscan.io/contract/A.8d5b9dd833e176da.SwapInterfaces?tab=deployments +[63]: https://github.com/onflow/flow-bridge-app?tab=readme-ov-file#evm-testnets +[64]: https://evm-testnet.flowscan.io/address/0x97900F59828Da4187607Cb8F84f49e3944199d18?tab=contract +[65]: https://evm-testnet.flowscan.io/address/0xBCF2dA8f82fb032A2474c92Ec5b70C95A83fc0cc?tab=contract +[66]: https://flowscan.io/contract/A.ec67451f8a58216a.PublicPriceOracle +[67]: https://testnet.flowscan.io/contract/A.9fb6606c300b5051.BandOracle +[68]: https://evm-testnet.flowscan.io/address/0x2880aB155794e7179c9eE2e38200202908C17B43 +[69]: https://evm-testnet.flowscan.io/address/0x72104434BEc686B47a72bCa9b998624238BD2Ffb +[70]: https://evm-testnet.flowscan.io/address/0x217aAC9594EcB6d3f6667A214CF579dd29ce78dd +[band-oracle-doc]: ./band-oracle +[incrementfi-doc]: https://docs.increment.fi/ diff --git a/docs/ecosystem/defi-liquidity/faq.md b/docs/defi/faq.md similarity index 92% rename from docs/ecosystem/defi-liquidity/faq.md rename to docs/defi/faq.md index 7373b1378c..76e3a2a68c 100644 --- a/docs/ecosystem/defi-liquidity/faq.md +++ b/docs/defi/faq.md @@ -13,27 +13,28 @@ keywords: - DEX - yield farming - liquidity -sidebar_position: 3 +sidebar_position: 8 sidebar_label: Stablecoins & Bridges FAQ --- import Details from '@theme/Details'; -# DeFi & Liquidity FAQ +# Defi FAQ Below are common questions regarding stablecoins, liquidity, and bridging on Flow. Click on each question to expand and view the answer. ## Bridging and Gas
-No, Flow uses $FLOW as the gas token. [WETH](./defi-contracts#stablecoins--wrapped-assets) is supported on Flow EVM when [bridging](../bridges.md) from another chain. $WFLOW is used as an ERC20 in DeFi apps and not used for gas. +No, Flow uses $FLOW as the gas token. [WETH](./defi-contracts-mainnet#stablecoins--wrapped-assets) is supported on Flow EVM when [bridging](../ecosystem/bridges.md) from another chain. $WFLOW is used as an ERC20 in DeFi apps and not used for gas.
When using Flow EVM for the first time, your EOA will automatically be credited 0.05 FLOW to cover gas costs when bridging into Flow. -If further top-ups are required you can use [Gas.zip](https://www.gas.zip/). See [Fees](../../evm/fees) for information on gas pricing. +If further top-ups are required you can use [Gas.zip](https://www.gas.zip/). See [Fees](../../build/evm/fees) for information on gas pricing. + +Flow Wallet users do not pay for gas since the wallet subsidizes all transaction fees. -Flow Wallet users do not pay for gas since the wallet subsidizes all transaction fees.
## Stablecoins on Flow @@ -45,7 +46,6 @@ USDT (Tether USD) - Issued by Tether USDF (USD Flow) - Backed by PYUSD (PayPal USD) issued by PayPal -
@@ -65,7 +65,6 @@ You can earn yield through: - Lending Platforms - Supply stablecoins on [IncrementFi][3], [Sturdy Finance][19] & [MoreMarkets][4] to earn interest. - Liquidity Pools - Provide liquidity on [IncrementFi][5] or [KittyPunch][6] to earn trading fees and farm LP tokens. -- Yield Aggregators (Coming soon) - Use [KittyPunch][7] to automate stablecoin yield strategies.
@@ -177,12 +176,12 @@ You can use any EVM wallet such as Metamask, Coinbase Wallet, and Flow Wallet. You can see a full list of stablecoins here: [DeFi Contracts on Flow][0] -Trading pools for USDF and stgUSDC (USDC via Stargate) are already live and available for immediate use on Flow EVM and can be seamlessly transferred to any Flow Cadence address. +Trading pools for USDF and USDC (USDC via Stargate) are already live and available for immediate use on Flow EVM and can be seamlessly transferred to any Flow Cadence address.
-
-Cadence applications can use USDC.e as the default, but they now also have the option to support USDF or stgUSDC based on their needs. +
+Cadence applications can use USDC.e as the default, but they now also have the option to support USDF or USDC based on their needs. If you have questions you can join [Flow Discord][15] to get free technical support. @@ -206,7 +205,7 @@ If you have questions you can join [Flow Discord][15] to get free technical supp - **Flow Discord**: [https://discord.gg/flow][15]
-[0]: ./defi-contracts.md +[0]: ./defi-contracts-mainnet.md [1]: https://swap.kittypunch.xyz/ [2]: https://app.increment.fi/swap?in=A.1654653399040a61.FlowToken&out= [3]: https://app.increment.fi/dashboard @@ -225,4 +224,4 @@ If you have questions you can join [Flow Discord][15] to get free technical supp [16]: https://evm.flowscan.io [17]: https://discord.com/invite/9sFqx9U [19]: https://v2.sturdy.finance/overview -[20]: https://www.flowverse.co/?categories=defi \ No newline at end of file +[20]: https://www.flowverse.co/?categories=defi diff --git a/docs/defi/forte.md b/docs/defi/forte.md new file mode 100644 index 0000000000..6400e68d61 --- /dev/null +++ b/docs/defi/forte.md @@ -0,0 +1,12 @@ +--- +title: Build with Forte ↙ +sidebar_position: 2 +--- + +# Quickstart + +Go to [Forte](../../blockchain-development-tutorials/forte) + +import {Redirect} from '@docusaurus/router'; + +; diff --git a/docs/ecosystem/defi-liquidity/index.md b/docs/defi/index.md similarity index 68% rename from docs/ecosystem/defi-liquidity/index.md rename to docs/defi/index.md index bbeb7433a4..88421e67f1 100644 --- a/docs/ecosystem/defi-liquidity/index.md +++ b/docs/defi/index.md @@ -1,5 +1,5 @@ --- -title: DeFi & Liquidity +title: Defi description: Mechanisms that connect different blockchain networks, allowing secure and decentralized transfer of assets and data across platforms. keywords: - DeFi @@ -13,32 +13,48 @@ keywords: - lending platforms - stablecoin protocols - liquidity solutions -sidebar_position: 5 -sidebar_custom_props: - icon: 💧 + - Consumer DeFi + - Forte + - Flow Actions + - Scheduled Transactions +sidebar_position: 1 --- -# DeFi & Liquidity on Flow +# Defi on Flow **Fast, scalable, and capital-efficient DeFi.** Flow delivers a seamless DeFi experience without congestion, unlocking new possibilities for developers and users alike. -Flow is designed for **next-generation DeFi**, enabling developers to build high-performance **DEXs, lending platforms, stablecoin protocols, and liquidity solutions**—all without the friction of high fees or complex scaling layers. +Flow is a purpose-built L1 blockchain designed for large-scale consumer finance applications and automated DeFi. It enables developers to build high-performance **DEXs, lending platforms, stablecoin protocols, and liquidity solutions**—all without the friction of high fees or complex scaling layers. ## Why DeFi on Flow? -**Ultra-low fees** – Cost-efficient swaps, lending, and staking -**Fast finality** – Transactions are confirmed quickly with guaranteed execution -**Capital-efficient execution** – No MEV, no congestion, seamless scaling -**Composable DeFi** – Built-in interoperability between assets +**Ultra-low fees** - Cost-efficient swaps, lending, and staking +**Fast finality** - Transactions confirmed in seconds with guaranteed execution +**MEV resistance** - Equitable access without frontrunning or hidden fees +**Capital-efficient execution** - No congestion, seamless scaling +**Composable DeFi** - Built-in interoperability between assets and protocols +**Automated execution** - Native scheduling and autonomous workflows with Forte **Start integrating DeFi on Flow today.** -**[DeFi Contracts](./defi-contracts.md)** +**[DeFi Contracts](./defi-contracts-mainnet.md)** **[Cross-chain swaps](./cross-chain-swaps.md)** **[Read the FAQ](./faq.md)** Explore the [FlowVerse DeFi ecosystem](https://www.flowverse.co/?categories=defi) page for more information. +## Build with Forte + +The **Forte network upgrade** transforms Flow into an autonomous, intelligent network capable of executing complex DeFi workflows without external dependencies. Forte introduces native time scheduling, protocol-level composability, and precision financial calculations that enable entirely new categories of applications. + +**Flow Actions** enable protocol-native, composable operations that link together standardized DeFi primitives—sources, sinks, swappers, price oracles, and more—into atomic, protocol-agnostic workflows. A single transaction can claim rewards, swap assets, add liquidity, and restake LP tokens without any off-chain orchestration. + +**Scheduled Transactions** introduce the first truly onchain time scheduler, enabling recurring actions, deferred settlements, and autonomous portfolio management without external cron jobs or trusted servers. DeFi protocols can become self-maintaining: positions compound automatically, vaults adjust exposure based on time or events, and protocols enforce predictable behavior entirely onchain. + +Combined with **128-bit fixed-point arithmetic** for lossless financial calculations and **native WebAuthn support** for seedless user onboarding, Forte reduces development time for consumer finance applications from months to mere days. + +Learn more about building automated DeFi with [Flow Actions](../blockchain-development-tutorials/forte/flow-actions/index.md) and [Scheduled Transactions](../blockchain-development-tutorials/forte/scheduled-transactions/scheduled-transactions-introduction.md). + ## DeFi Partners
@@ -70,7 +86,7 @@ Explore the [FlowVerse DeFi ecosystem](https://www.flowverse.co/?categories=defi ## Sudocat -[Sudocat][7] offers a decentralized trading dashboard built for Flow. With tools for analytics, portfolio tracking, and execution, it enhances the trading experience for on-chain users and DeFi enthusiasts. Learn more [here][15]. +[Sudocat][7] offers a decentralized trading dashboard built for Flow. With tools for analytics, portfolio tracking, and execution, it enhances the trading experience for onchain users and DeFi enthusiasts. Learn more [here][15]. ## Hitdex diff --git a/docs/defi/pyusd0-integration-guide.md b/docs/defi/pyusd0-integration-guide.md new file mode 100644 index 0000000000..7e1a1e7a16 --- /dev/null +++ b/docs/defi/pyusd0-integration-guide.md @@ -0,0 +1,93 @@ +--- +id: pyusd0-integration-guide +title: PYUSD0 Integration Guide +description: A developer reference for integrating PYUSD0 on Flow, covering token architecture, contract addresses, bridging mechanics, and migration from USDF. +keywords: + - PYUSD0 + - PYUSD + - stablecoins + - Flow blockchain + - Flow EVM + - Flow Cadence + - Flow EVM Mainnet + - LayerZero + - OFT + - omnichain fungible token + - bridges + - stablecoin liquidity + - USDF migration + - decentralized exchanges + - DEX +sidebar_position: 9 +sidebar_label: PYUSD0 Integration +--- + +# PYUSD0 Integration Guide + +## Overview + +This guide is for developers and protocols integrating PYUSD0 on Flow. PYUSD0 is an OFT (Omnichain Fungible Token) and brings pre-native PayPal USD support to Flow with seamless cross-chain transfers across 140+ chains via Stargate. It replaces USDF as Flow's canonical USD stablecoin. For users please read the [migration guide.][6] + +## Contract Addresses + +### Flow EVM Mainnet + +| Contract | Address | +| --------------------------------- | -------------------------------------------- | +| [PYUSD0][2] | `0x99af3eea856556646c98c8b9b2548fe815240750` | +| [Migration Pool (USDF/PYUSD0)][3] | `0x6ddDFa511A940cA3fD5Ec7F6a4f23947cA30f030` | + +### Flow Cadence Mainnet + +| Token Name | Contract Address | Contract Name | +| ----------- | -------------------- | ------------------------------------------------------------ | +| [PYUSD0][1] | `0x1e4aa0b87d10b141` | `EVMVMBridgedToken_99af3eea856556646c98c8b9b2548fe815240750` | + +### Testnet + +| Contract | Address | +| ----------- | -------------------------------------------- | +| [PYUSD0][7] | `0xd7d43ab7b365f0d0789aE83F4385fA710FfdC98F` | + +This is a stand-in token for testing purposes only. Mainnet PYUSD0 requires real PYUSD locked via LayerZero. The testnet contract has a [mint function][8] and a [liquidity pool][9] so you can mint or swap tokens for development. + +### **Deprecated (USDF)** + +| Contract | Address | Status | +| -------- | -------------------------------------------- | ----------- | +| USDF | `0x2aaBea2058b5aC2D339b163C6Ab6f2b6d53aabED` | Deprecating | + +## **Token Specifications** + +``` +Name: PYUSD0 +Symbol: PYUSD0 +Decimals: 6 +Standard: ERC-20 + LayerZero OFT +Backing: 1:1 PYUSD (PayPal USD) +``` + +## About PYUSD0 + +PYUSD0 is a pre-native token deployed via LayerZero's Asset0 program, alongside other stablecoins like USDG0 (backed by Robinhood, Kraken, Mastercard) and AUSD0. It's fully backed 1:1 by PayPal USD. When Paxos later deploys native PYUSD directly on Flow, PYUSD0 balances will automatically upgrade with no user or developer action required. + +## **Code Examples** + +Visit [the GitHub Repository][5] for code examples on bridging PYUSD0 via LayerZero OFT. + +## **Migration Path for Existing USDF Integrations** + +1. **Add PYUSD0 support** alongside USDF +2. **Update defaults** to use PYUSD0 instead of USDF +3. **Communicate to users** about migration timeline +4. **Deprecate USDF** after grace period + +[1]: https://www.flowscan.io/contract/A.1e4aa0b87d10b141.EVMVMBridgedToken_99af3eea856556646c98c8b9b2548fe815240750 +[2]: https://evm.flowscan.io/token/0x99aF3EeA856556646C98c8B9b2548Fe815240750 +[3]: https://evm.flowscan.io/token/0x6ddDFa511A940cA3fD5Ec7F6a4f23947cA30f030?tab=contract +[4]: https://github.com/paxosglobal/paxos-token-contracts/blob/master/contracts/stablecoins/PYUSD.sol +[5]: https://github.com/onflow/flow-bridge-app/tree/main/ethereum-oapp +[6]: https://flow.com/post/pyusd0-migration-guide +[7]: https://evm-testnet.flowscan.io/address/0xd7d43ab7b365f0d0789aE83F4385fA710FfdC98F +[8]: https://evm-testnet.flowscan.io/token/0xd7d43ab7b365f0d0789aE83F4385fA710FfdC98F?tab=read_write_contract +[9]: https://flowswap.io/swap?chain=flow-testnet&inputCurrency=NATIVE&outputCurrency=0xd7d43ab7b365f0d0789aE83F4385fA710FfdC98F diff --git a/docs/ecosystem/Hackathons and Events/may-the-flow-be-with-you.md b/docs/ecosystem/Hackathons and Events/may-the-flow-be-with-you.md deleted file mode 100644 index 5eb9ac8257..0000000000 --- a/docs/ecosystem/Hackathons and Events/may-the-flow-be-with-you.md +++ /dev/null @@ -1,385 +0,0 @@ ---- -sidebar_position: 1 -title: May the Flow be with You -description: Daily coding rewards for Flow ecosystem contributors ---- - -import React from "react"; -import { useCurrentUser } from "@site/src/hooks/use-current-user"; -import { useProgress } from "@site/src/hooks/use-progress"; -import ProfileModal from "@site/src/components/ProfileModal"; - -export const ProfileLink = () => { - const [isProfileModalOpen, setIsProfileModalOpen] = React.useState(false); - const { user } = useCurrentUser(); - - return ( - <> -

setIsProfileModalOpen(true)} - > - Create Your Profile - - - -

- setIsProfileModalOpen(false)} - /> - - ); -}; - -# May the Flow be with You! - -Join us for a month-long vibe coding challenge on Flow! Starting May 4th, participate in our four themed weeks featuring randomness, games, DeFi, and killer apps. Submit your AI-enhanced projects to win weekly prizes from the 1750 FLOW weekly prize pool and compete for the end-of-month jackpot of 2500 FLOW. - - -## How to Participate - -
-
- -
-

Sign up for a Flow dev docs profile (top right of navigation bar)

-

Fill out your repository and deployer addresses

-

Note: The first listed address will receive FLOW rewards

-
-
- -
-

Create Project in Repo

-
-

Go to the campaign repo and fork it

-

Create a new folder in the submissions directory with your Flow address as the folder name

-

Add a README that describes your project, team, and motivation

-
-
- -
-

Build & Commit

-
-

Work on your Flow project based on the weekly themes

-

Make weekly submissions by creating project folders within each week's directory (e.g., any-project-name)

-

Each submission must include a README with key prompts used and source code

-

Note: You can submit multiple projects within each week's theme

-
-
- -
-

Win Rewards

-
-
- -

Weekly Rewards: 1750 FLOW distributed across 7 winners (~250 FLOW each) based on weekly themes

-
-
- -

Each day you participate in a week counts as an additional raffle entry, increasing your winning odds

-
-
- -

All submissions throughout May qualify for the 2500 FLOW end-of-month jackpot

-
-
- -

Build in public for bonus rewards (see guidelines below)

-
-
-
-
- -## Weekly Schedule - -
-
-

Week 1: The Randomness Revolution (May 4-10)

-

Leverage on-chain randomness to create unpredictable, emergent experiences on Flow. Think: generative art, dynamic NFTs, chance-based mechanics, and randomized gameplay elements.

- - -
- -
-

Week 2: Actually Fun Games (May 11-17)

-

Master the ingredients of creating fun and delightful experiences, from replayability, social dynamics and randomness to 'easy to play hard to master' mechanics.

- -
- -
-

Week 3: Generative Art and Worlds (May 18-24)

-

Utilize generative tools and AI to create evolving, autonomous and algorithmicartistic applications. This theme is broad and inclusive of creative domains, composibility and platforms/launchpads that are easy for others to build off of or extend.

- -
- -
-

Week 4: AI and LLMs (May 25 - June 1st)

-

How can LLMs make life easier for everyday people or enrich experiences? Experiment with the latest AI models or agentic frameworks to create new levels of depth in your existing projects or create new ones entirely.

-
    -
  • May 25: Week 4 starts
  • -
  • May 25 - June 1st: Build AI integrated apps (either completely new or continue building on your week 1, 2 or 3 projects)
  • -
  • June 1st: Final submission deadline
  • -
  • June 2nd: Week 4 winners and jackpot announced! Note, the jackpot will consist of shortlisted projects that are the most working end-to-end and complex, check the repo for the new leaderboard to see how your project ranks relative to others!
  • -
-
-
- -
-
-

Looking for a Team?

-
-

- Looking to form a team for one of the weekly challenges or stay on top of the latest? Join our Telegram chat. -

-
- -## Process of Committing to the Campaign Repo - -
-
-

1. Fork the Official Repository

-

Start by forking the official repository to your GitHub account.

-
- -
-

2. Follow the Repository Structure

-
-
-{`submissions/
-  ├── 0x1234...333/           # Your Flow address
-  │   ├── README.md           # Project overview
-  │   ├── week1/              # Week 1: Randomness Revolution
-  │   │   ├── my-random-project/    # Your project for week 1
-  │   │   │   ├── README.md   # Documentation with prompts used
-  │   │   │   └── src/        # Source code
-  │   │
-  │   ├── week2/              # Week 2: ...
-  │   ├── week3/              # Week 3: ...
-  │   └── week4/              # Week 4: ...`}
-      
-
-
- -
-

3. Create Your Project Directory

-
    -
  • Create a folder named with your Flow address under submissions
  • -
  • All your submissions should be placed under this folder
  • -
  • Create a folder for each week (week1, week2, week3, week4)
  • -
  • Each week will have a specific theme/topic for the raffle
  • -
-
- -
-

4. Make Weekly Submissions

-
    -
  • Daily commits lead to higher likelihood of winning!
  • -
  • Create your project folders with descriptive names inside each week's directory
  • -
  • Each project must include a README file and source code
  • -
  • Include any prompts used for development in the README
  • -
  • Send a pull request for each submission
  • -
  • Each project submission during a week counts as an entry for that week's raffle
  • -
  • All entries accumulate for the end-of-month jackpot raffle
  • -
-
-
- -:::tip -Your profile and GitHub information are used to verify commits and select winners. Make sure to keep them up to date! -::: - -### Submission Guidelines -- Each submission should demonstrate meaningful progress -- Weekly winners receive prizes from the 1750 FLOW pool (7 winners) -- More submissions in a week increase your chances of winning -- All participants are eligible for the 2500 FLOW end-of-month jackpot - -## How It Works - -### Weekly Rewards -- Build projects aligned with each week's theme: - - Week 1: The Randomness Revolution - - Week 2-4: Themes to be announced weekly -- Submit projects in the appropriate weekly folder -- Each submission during a week counts as an entry into that week's raffle -- More projects submitted in a week = higher chances of winning -- Projects that best embody the weekly theme receive additional consideration -- 1750 FLOW distributed to 7 winners each week (~250 FLOW each) -- Winners are chosen using [randoms.wtf](https://randoms.wtf/) -- Winners are announced from [@aliserag0](https://twitter.com/aliserag0) Twitter account -- FLOW prizes are sent to the top wallet address indicated in your profile - -### Weekly Building in Public Bonus -- Share your progress on Twitter with the hashtag #MayTheFlowBeWithYou -- Tag @flow_blockchain in your posts -- Top builders receive additional FLOW rewards -- Join our weekly Twitter Spaces to learn from experts and showcase your work - -## Building in Public - -Sharing your progress publicly unlocks extra rewards and increases your chances of winning! - -In addition to the weekly rewards, we will regularly give bonus FLOW to the top Building in Public posts on X. - -1. **Share your progress daily on X (Twitter)** - - Post screenshots, videos, or code snippets of what you're building - - Tag [@flow_blockchain](https://twitter.com/flow_blockchain) and include the hashtag **#MayTheFlowBeWithYou** - - Link to your repository - -2. **Engage with other builders** - - Like, comment, and share other participants' work - - Collaborate and provide feedback - - Build the Flow community together - -## List of Winners - -Check this section daily to see all winners announced so far! - -### Week 1: The Randomness Revolution -- Egg's Wisdom - 0x2ff409478f92e8bd -- ElementalStrikers - 0xc65395858a38d8ff -- Wheel of Fortune - 0xe712bbfbeeef1cfa -- Lucky Spinning Wheel - 0x0012a1ef98accd88 -- Ghibli—style Headshot Generator - 0xd362246ad3f7ca3c -- ChainRaffle - 0xbbdd20a9016cc1d9 -- Random Game (Phaser) - 0x9db94c9564243ba7 - -### Week 2: Actually Fun Games -- Ace Guessing Game - 0xa620a02c4cc2d20d -- ElementalStrikers - 0xc65395858a38d8ff -- Click to the Moon - 0xe712bbfbeeef1cfa -- The Doodles Memorizer - 0x9f7145728ef9ae10 -- Emoji Chain Reaction - 0x6c1b12e35dca8863 -- FrogDash - 0xe35f688520e4a2c3 -- FlowVerse - 0x1E78b3F3550889e90EcE152ab6bbCb8d9E7Dd221 - -### Week 3: Generative Art & Worlds -- Flow Craps - 0x9db94c9564243ba7 -- Doodles NFT Mutator - 0x9f7145728ef9ae10 -- Generative Tarot Card AI - 0xe712bbfbeeef1cfa -- FlowGating - 0x94b619cc671a3734 -- Evolving Creatures - 0xc65395858a38d8ff -- Flow Persona - 0x1E78b3F3550889e90EcE152ab6bbCb8d9E7Dd221 -- Game of Life - 0x0000000000000000000000021DD51488A93756E2 - -### Week 3: Generative Art and Worlds -Tasneem - 0x0000000000000000000000021DD51488A93756E2 -Zhixuan - 0x9f7145728ef9ae10 -Tobin - 0xe712bbfbeeef1cfa -NileDEX - 0x94b619cc671a3734 -Ccarnicle - 0x9db94c9564243ba7 -Claucondor - 0xc65395858a38d8ff -Pandit - 0x1E78b3F3550889e90EcE152ab6bbCb8d9E7Dd221 - - -### Week 4: AI & LLMs -Claucondor - 0xc65395858a38d8ff -AlexD-Great - 0x9701b128fd2017f8 -Pranav - 0x17b3b1e6b16965f3 -AltcoinDaddy - 0x6c1b12e35dca8863 -Tobin - 0xe712bbfbeeef1cfa -Pandit - 0x1E78b3F3550889e90EcE152ab6bbCb8d9E7Dd221 -Zhixuan - 0x9f7145728ef9ae10 - -:::note -Winners are announced on the [@flow_blockchain](https://x.com/flow_blockchain) Twitter account, and prizes are sent to the wallet addresses indicated in your submission name on GitHub. -::: - -## FAQ - -import { useState } from 'react'; - -export const FAQ = ({ question, children }) => { - const [isOpen, setIsOpen] = useState(false); - return ( -
- - {isOpen && ( -
{children}
- )} -
- ); -}; - - -Winners are chosen using [randoms.wtf](https://randoms.wtf/) to ensure fair and transparent selection. - - - -Any commit to a participating repository that shows meaningful progress. This includes: - -- New features -- Bug fixes -- Documentation updates -- Test additions -- Code improvements - - - -No, but it should leverage Flow in a significant way. This will be up to the discretion of the reviewers, but you can get in touch if you're unsure about your project's eligibility. - - - -No, but it should be heading for a launch eventually. We understand things take time and we want to reward you along the way for building. Reviewers have the discretion to eliminate an entry if a path toward being live and available to users is unclear. - - - -No, if you are already building something you can continue with that project. Your repository must be public to be eligible for rewards. - - - -Your project is still eligible for the May the Flow be with You rewards, regardless of funding status. - - - -Yes! Projects can have multiple developers. Each developer should create their own profile and list the same repository. Each developer will be eligible for rewards based on their individual commits. - - - -Make sure your GitHub account is linked to your Flow dev docs profile. We'll automatically track your commits to participating repositories. - - - - - Daily FLOW prizes are distributed within several days of the draw -- Weekly building in public rewards are announced every Monday - - -## Stay Connected - -- Follow [@flow_blockchain](https://twitter.com/flow_blockchain) for updates -- Join our [Discord](https://discord.gg/flow) for community support - -:::warning Disclaimer -Disclaimer: Individuals residing in jurisdictions where gaming or lottery participation is prohibited by law are not eligible to participate. -::: diff --git a/docs/ecosystem/block-explorers.md b/docs/ecosystem/block-explorers.md index 751d39e7e4..562d976671 100644 --- a/docs/ecosystem/block-explorers.md +++ b/docs/ecosystem/block-explorers.md @@ -20,7 +20,7 @@ Block explorers are user-friendly online tools that visually present blockchain - Transactions - Contracts - Network activity (transaction count) -- Transaction cost (gas fee) +- Transaction cost (compute unit/gas fee) - Validators information ### Supported networks: diff --git a/docs/ecosystem/bug-bounty.mdx b/docs/ecosystem/bug-bounty.mdx new file mode 100644 index 0000000000..796ca4e580 --- /dev/null +++ b/docs/ecosystem/bug-bounty.mdx @@ -0,0 +1,23 @@ +--- +sidebar_position: 13 +description: Report security vulnerabilities in Flow and earn rewards through the official bug bounty program. +sidebar_custom_props: + icon: 🐛 +--- + +import Icon from '@site/src/components/Icon'; +import { IconName } from '@site/src/types/icons'; + +# Bug Bounty Program + +
+ +
+

+ Discover Flow's bug bounty program, which rewards white hat hackers for finding vulnerabilities and helping keep the network secure. +

+ +[Submit a Vulnerability Report →](https://hackenproof.com/blog/for-hackers/flow-new-bounty-target) + +
+
diff --git a/docs/ecosystem/collectibles.md b/docs/ecosystem/collectibles.md index a70b0eceda..1ca07b507c 100644 --- a/docs/ecosystem/collectibles.md +++ b/docs/ecosystem/collectibles.md @@ -96,7 +96,7 @@ Flow's high-performance infrastructure enables seamless experiences for collecto ## Buildtree.io -[Buildtree.io][15] powers the next generation of advanced on-chain assets. The platform enables complex NFT functionality and innovative digital asset creation. +[Buildtree.io][15] powers the next generation of advanced onchain assets. The platform enables complex NFT functionality and innovative digital asset creation. ## Mintify.xyz diff --git a/docs/ecosystem/defi-liquidity/defi-contracts.md b/docs/ecosystem/defi-liquidity/defi-contracts.md deleted file mode 100644 index 854a3801b7..0000000000 --- a/docs/ecosystem/defi-liquidity/defi-contracts.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -id: defi-contracts -title: DeFi Contracts on Flow -description: A reference table of frequently used DeFi contracts on Flow, including their addresses for both Flow EVM and Flow Cadence. -keywords: - - DeFi contracts - - Flow blockchain - - Flow EVM - - Flow Cadence - - stablecoins - - wrapped assets - - AMMs - - DEXs - - KittyPunch - - PunchSwap -sidebar_position: 1 -sidebar_label: DeFi Contracts ---- - -import StablecoinsWrappedAssetsTable from '@site/src/components/defi-contracts/StablecoinsWrappedAssetsTable'; - -Flow is a Layer 1 blockchain that supports EVM equivalency, offering two environments Flow EVM and Flow Cadence. Fungible and non-fungible tokens can seamlessly transfer between these environments via the native VM token bridge. As a result, many tokens have both a Flow EVM mainnet contract address and a Flow Cadence mainnet contract address, allowing developers to choose their preferred environment. - -Below is a list of commonly used DeFi contracts on Flow: - -## Stablecoins & Wrapped Assets - -#### Flow EVM Mainnet - - - -#### Flow Cadence Mainnet - - - -## AMMs & DEXs - -#### Flow EVM Mainnet - -| Contract Name | Flow EVM Mainnet Address | -| -------------------------------------------- | -------------------------------------------- | -| [StableKittyFactoryNG.sol (KittyPunch)][1] | `0x4412140D52C1F5834469a061927811Abb6026dB7` | -| [TwoKittyFactory.sol (KittyPunch)][2] | `0xf0E48dC92f66E246244dd9F33b02f57b0E69fBa9` | -| [TriKittyFactory.sol (KittyPunch)][3] | `0xebd098c60b1089f362AC9cfAd9134CBD29408226` | -| [KittyRouterNgPoolsOnly.sol (KittyPunch)][4] | `0x87048a97526c4B66b71004927D24F61DEFcD6375` | -| [PunchSwapV2Router02.sol (KittyPunch)][5] | `0xf45AFe28fd5519d5f8C1d4787a4D5f724C0eFa4d` | -| [PunchSwapV2Factory.sol (KittyPunch)][6] | `0x29372c22459a4e373851798bFd6808e71EA34A71` | -| [TrenchesTokensBuyer.sol (KittyPunch)][7] | `0x6D0e081Acc28eA9ee6b7fD293eC03F97147b026d` | - -#### Flow Cadence Mainnet - -| Contract Name | Flow Cadence Mainnet Address | -| ----------------------------------- | ---------------------------- | -| [SwapFactory.cdc (IncrementFi)][22] | `0xb063c16cac85dbd1` | -| [SwapPair (IncrementFi)][23] | `0xecbda466e7f191c7` | -| [SwapError (IncrementFi)][24] | `0xb78ef7afa52ff906` | -| [SwapInterfaces (IncrementFi)][25] | `0xb78ef7afa52ff906` | -| [SwapConfig (IncrementFi)][26] | `0xb78ef7afa52ff906` | -| [SwapRouter (IncrementFi)][27] | `0xa6850776a94e6551` | - -## Bridges & Cross-Chain Messaging - -| Bridge / Protocol | Reference Docs | -|----------------------------------------------|--------------------------| -| Stargate Bridge ([stargate.finance][8]) | [Mainnet Contracts][9] | -| Hyperlane Bridge ([trump.hyperlane.xyz][10]) | [Mainnet Contracts][11] | -| Flow Bridge ([bridge.flow.com][12]) | [Superbridge Docs][13] | -| Celer cBridge ([cbridge.celer.network][14]) | [Celer cBridge Docs][15] | -| DeBridge ([app.debridge.finance][34]) | [DeBridge Contracts][35] | -| Relay ([relay.link][36]) | [Relay Contracts][37] | -| LayerZero | [Mainnet Contracts][16] | -| Axelar | [Axelar Docs][17] | - -## Omni Fungible Tokens (USD Flow - USDF) - -#### Solana Mainnet - -| Contract Name | Contract Address | -|------------------------------|--------------------------------------------| -| PYUSD Program ID | `28EyPNAi9BMTvGuCaQrptMXjpWUi7wx8SxAFVoSZxSXe` | -| PYUSD Mint | `2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo` | -| PYUSD Mint Authority | `22mKJkKjGEQ3rampp5YKaSsaYZ52BUkcnUN6evXGsXzz` | -| PYUSD Escrow | `6z3QyVS36nQ9fk2YvToxqJqXqtAFsSijqgHxpzKyG5xn` | -| PYUSD OFT Store | `2KUb8dcZR9LyrSg4RdkQx91xX6mPQLpS1MEo6gwfvLZk` | - -#### Ethereum Mainnet - -| Contract Name | Contract Address | -|------------------------------|--------------------------------------------| -| PYUSD Token | `0x6c3ea9036406852006290770BEdFcAbA0e23A0e8` | -| PYUSD Locker | `0xFA0e06B54986ad96DE87a8c56Fea76FBD8d493F8` | - -## Oracles - -#### Flow EVM Mainnet - -| Contract Name | Flow EVM Mainnet Address | -|--------------------------------| -------------------------------------------- | -| [ERC1967Proxy.sol (Pyth)][18] | `0x2880aB155794e7179c9eE2e38200202908C17B43` | -| [ERC1967Proxy.sol (Stork)][28] | `0xacC0a0cF13571d30B4b8637996F5D6D774d4fd62` | - - -#### Flow Cadence Testnet - -| Contract Name | Flow Cadence Testnet Address | -|-------------------------------------------|------------------------------| -| [PublicPriceOracle.cdc (IncrementFi)][31] | `0x8232ce4a3aff4e94` | -| [BandOracle.cdc (Band)][32] | `0x2c71de7af78d1adf` | - -#### Flow Cadence Mainnet - -| Contract Name | Flow Cadence Mainnet Address | -|-------------------------------------------| ---------------------------- | -| [PublicPriceOracle.cdc (IncrementFi)][19] | `0xec67451f8a58216a` | -| [BandOracle.cdc (Band) Protocol][33] | `0x6801a6222ebf784a` | - -## Ethereum Attestation Service - -More information can be found on the Credora docs site for [EAS on Flow](https://credora.gitbook.io/eas-for-flow). - -Testnet EAS Explorer: [https://flow-testnet.easscan.credora.io] (https://flow-testnet.easscan.credora.io) - -| Contract Name | Flow EVM Testnet Address | -|---------------------------------------------------------|----------------------------------------------| -| [SchemaRegistry.sol (Ethereum Attestation Service)][29] | `0x97900F59828Da4187607Cb8F84f49e3944199d18` | -| [EAS.sol (Ethereum Attestation Service)][30] | `0xBCF2dA8f82fb032A2474c92Ec5b70C95A83fc0cc` | - -Mainnet EAS Explorer: [https://flow.easscan.credora.io] (https://flow.easscan.credora.io) - -| Contract Name | Flow EVM Mainnet Address | -| ------------------------------------------------------- | -------------------------------------------- | -| [SchemaRegistry.sol (Ethereum Attestation Service)][20] | `0xB0cF748a05AEA8D59e15834446CFC95bcFF510F0` | -| [EAS.sol (Ethereum Attestation Service)][21] | `0xc6376222F6E009A705a34dbF1dF72fEf8efB3964` | - - -[1]: https://evm.flowscan.io/address/0x4412140D52C1F5834469a061927811Abb6026dB7?tab=contract -[2]: https://evm.flowscan.io/address/0xf0E48dC92f66E246244dd9F33b02f57b0E69fBa9?tab=contract -[3]: https://evm.flowscan.io/address/0xebd098c60b1089f362AC9cfAd9134CBD29408226?tab=contract -[4]: https://evm.flowscan.io/address/0x87048a97526c4B66b71004927D24F61DEFcD6375?tab=contract -[5]: https://evm.flowscan.io/address/0xf45AFe28fd5519d5f8C1d4787a4D5f724C0eFa4d?tab=contract -[6]: https://evm.flowscan.io/address/0x29372c22459a4e373851798bFd6808e71EA34A71?tab=contract -[7]: https://evm.flowscan.io/address/0x6D0e081Acc28eA9ee6b7fD293eC03F97147b026d?tab=contract -[8]: https://stargate.finance/bridge?srcChain=ethereum&srcToken=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&dstChain=flow&dstToken=0xF1815bd50389c46847f0Bda824eC8da914045D14 -[9]: https://stargateprotocol.gitbook.io/stargate/v2-developer-docs/technical-reference/mainnet-contracts#flow -[10]: https://trump.hyperlane.xyz/ -[11]: https://docs.hyperlane.xyz/docs/reference/addresses/mailbox-addresses -[12]: https://bridge.flow.com/ -[13]: https://docs.superbridge.app/ -[14]: https://cbridge.celer.network/1/747/USDC-intermediary -[15]: https://cbridge-docs.celer.network/tutorial/flow-cadence-bridging-guide -[16]: https://docs.layerzero.network/v1/developers/evm/technical-reference/deployed-contracts?chains=flow -[17]: https://docs.axelar.dev/validator/external-chains/flow/ -[18]: https://evm.flowscan.io/address/0x2880aB155794e7179c9eE2e38200202908C17B43?tab=contract -[19]: https://contractbrowser.com/A.ec67451f8a58216a.PublicPriceOracle -[20]: https://evm.flowscan.io/address/0xB0cF748a05AEA8D59e15834446CFC95bcFF510F0?tab=contract -[21]: https://evm.flowscan.io/address/0xc6376222F6E009A705a34dbF1dF72fEf8efB3964?tab=contract -[22]: https://contractbrowser.com/A.b063c16cac85dbd1.SwapFactory -[23]: https://contractbrowser.com/A.ecbda466e7f191c7.SwapPair -[24]: https://contractbrowser.com/A.b78ef7afa52ff906.SwapError -[25]: https://contractbrowser.com/A.b78ef7afa52ff906.SwapInterfaces -[26]: https://contractbrowser.com/A.b78ef7afa52ff906.SwapConfig -[27]: https://contractbrowser.com/A.a6850776a94e6551.SwapRouter -[28]: https://evm.flowscan.io/address/0xacC0a0cF13571d30B4b8637996F5D6D774d4fd62?tab=contract -[29]: https://evm-testnet.flowscan.io/address/0x97900F59828Da4187607Cb8F84f49e3944199d18?tab=contract -[30]: https://evm-testnet.flowscan.io/address/0xBCF2dA8f82fb032A2474c92Ec5b70C95A83fc0cc?tab=contract -[31]: https://contractbrowser.com/A.8232ce4a3aff4e94.PublicPriceOracle -[32]: https://contractbrowser.com/A.2c71de7af78d1adf.BandOracle -[33]: https://contractbrowser.com/A.6801a6222ebf784a.BandOracle -[34]: https://app.debridge.finance/ -[35]: https://docs.debridge.finance/dln-the-debridge-liquidity-network-protocol/deployed-contracts -[36]: https://relay.link/bridge -[37]: https://docs.relay.link/resources/contract-addresses diff --git a/docs/ecosystem/builder-perks.md b/docs/ecosystem/developer-support-hub/builder-perks.md similarity index 99% rename from docs/ecosystem/builder-perks.md rename to docs/ecosystem/developer-support-hub/builder-perks.md index fed7839ee9..be3a244ed6 100644 --- a/docs/ecosystem/builder-perks.md +++ b/docs/ecosystem/developer-support-hub/builder-perks.md @@ -1,7 +1,7 @@ --- title: Builder Perks description: Exclusive perks and benefits for Flow builders -sidebar_position: 8 +sidebar_position: 1 --- import Modal from "@site/src/ui/design-system/src/lib/Components/Modal"; diff --git a/docs/ecosystem/grants.md b/docs/ecosystem/developer-support-hub/grants.md similarity index 76% rename from docs/ecosystem/grants.md rename to docs/ecosystem/developer-support-hub/grants.md index 2722dfa663..6483814057 100644 --- a/docs/ecosystem/grants.md +++ b/docs/ecosystem/developer-support-hub/grants.md @@ -1,7 +1,7 @@ --- title: Grants description: Discover grant opportunities and funding programs available for Flow developers -sidebar_position: 10 +sidebar_position: 2 sidebar_custom_props: icon: 🌱 --- @@ -10,32 +10,44 @@ sidebar_custom_props: The Flow Foundation provides grants to support developers and teams building tools and products that enhance the Flow ecosystem. -## Focus Areas - -We are particularly interested in projects across these key areas: - -- 📈 **DeFi**: Innovative decentralized finance solutions -- 💡 **Cutting-Edge Innovation and Widespread Adoption**: Projects that push the boundaries of what's possible in the Flow ecosystem -- 💼 **Public Goods**: Projects that provide essential infrastructure or services to the Flow ecosystem - -## How to Apply - We have two grant programs for different types of projects: - 🌱 **GrantDAO Program**: For pre-startup or post-hackathon projects, with a focus on building on Flow. This is a community-driven program and the grantees are voted on by the community. - 💡 **Ecosystem Grants**: For startup projects that are looking for funding to support their growth. This is a top-down program and the Flow Foundation will evaluate the grant applications. -### GrantDAO Program +## GrantDAO Program + +The Flow GrantDAO is allocating over several million FLOW to ecosystem builders and gives teams an opportunity to secure funding while working on bringing their project to life and solving real problems. -The Flow GrantDAO is allocating over several million FLOW to ecosystem builders. Eligible projects can be awarded up to 50k FLOW per round. Flow GrantDAO gives teams an opportunity to secure funding while working on bringing their project to life and solving real problems. After completing an application and getting approved, projects are funded based on community MACI voting. Voting happens throughout the round and payouts occur at the end of the round period. +Each round we will set at least 50k FLOW as the prize pool. After completing an application and getting approved, projects are funded based on community MACI voting. Voting happens throughout the round and payouts occur at the end of the round period. Projects that graduate from this program and show strong signs of traction or utilization may be offered additional startup advisory support from the Flow Foundation as well as fundraising opportunities and training. +:::info + +Round 1 has been closed on August 16, 2025. Please stay tuned for the next round. + +::: + +### How to Apply + 1. Visit the [Flow GrantDAO](https://dorahacks.io/flow) website 2. Submit an application of your BUIDL 3. Wait for the results of the round. If selected, you will be funded -### Ecosystem Grants +### Focus Areas (Round 1) + +We are particularly interested in projects across these key areas: + +- 📈 **DeFi**: Innovative decentralized finance solutions +- 💡 **Cutting-Edge Innovation and Widespread Adoption**: Projects that push the boundaries of what's possible in the Flow ecosystem +- 💼 **Public Goods**: Projects that provide essential infrastructure or services to the Flow ecosystem + +### Voting Results + +- Round 1: [Voting Results](https://dorahacks.io/flow/result?round_seq=1) + +## Ecosystem Grants The ecosystem grants program is aimed at supporting the growth of Flow ecosystem projects. The Flow Foundation will evaluate the grant applications and select the grantees. diff --git a/docs/ecosystem/developer-support-hub/index.md b/docs/ecosystem/developer-support-hub/index.md new file mode 100644 index 0000000000..95da2af561 --- /dev/null +++ b/docs/ecosystem/developer-support-hub/index.md @@ -0,0 +1,113 @@ +--- +title: Developer Support Hub +description: Complete support ecosystem for Flow builders - perks, grants, funding, and expert guidance +sidebar_position: 2 +--- + +# Developer Support Hub + +We're builders supporting builders. Get everything you need to succeed on Flow - from launch perks to funding connections. + +## Your Journey: From Idea to Success + +Follow this roadmap to build and scale your Flow project. Each stage unlocks new support and opportunities. + +### Stage 1: Idea to MVP + +**Goal:** Turn your concept into working code + +
+ +
+

Your mission:

+
    +
  • Create pitch deck or design doc
  • +
  • Build your first prototype
  • +
  • Ship a demo or hackathon project
  • +
+
+ +
+

Support tools:

+ +
+ +
+ +--- + +### Stage 2: MVP to Live Product + +**Goal:** Get real users on mainnet + +
+ +
+

Your mission:

+
    +
  • Deploy to Flow mainnet
  • +
  • Integrate with ecosystem partners
  • +
  • Gather user feedback and iterate
  • +
  • Build core features users love
  • +
+
+ +
+

Support tools:

+
    +
  • Contact us at builders [at] flow.com for direct technical and marketing support
  • +
  • Apply for Grants with GrantDAO to access community-voted funding
  • +
+
+ +
+ +--- + +### Stage 3: Live Product to Revenue + +**Goal:** Generate sustainable revenue + +
+ +
+

Your mission:

+
    +
  • Acquire paying users/customers
  • +
  • Track key business metrics
  • +
  • Build revenue-generating features
  • +
+
+ +
+

Support tools:

+ +
+ +
+ +--- + +Follow the roadmap above based on your project stage to get the right support at the right time. + +:::tip Ready to build? + +The best support is a thriving project. Start building today and tap into our ecosystem when you need it. + +**[Start with Cadence]** + +**[Start with Solidity (EVM)]** + +::: + + + +[Start with Cadence]: ../../blockchain-development-tutorials/cadence/getting-started/index.md +[Start with Solidity (EVM)]: ../../build/evm/quickstart.md diff --git a/docs/ecosystem/vcs-and-funds.md b/docs/ecosystem/developer-support-hub/vcs-and-funds.md similarity index 98% rename from docs/ecosystem/vcs-and-funds.md rename to docs/ecosystem/developer-support-hub/vcs-and-funds.md index c884fd6a36..a37af1f1f7 100644 --- a/docs/ecosystem/vcs-and-funds.md +++ b/docs/ecosystem/developer-support-hub/vcs-and-funds.md @@ -1,7 +1,7 @@ --- title: VCs & Funds description: Connect with venture capital firms and investment funds supporting Flow projects -sidebar_position: 8 +sidebar_position: 3 sidebar_custom_props: icon: 💼 --- diff --git a/docs/ecosystem/faucets.md b/docs/ecosystem/faucets.md index c6d7596e74..b022990aeb 100644 --- a/docs/ecosystem/faucets.md +++ b/docs/ecosystem/faucets.md @@ -1,5 +1,5 @@ --- -sidebar_position: 9 +sidebar_position: 5 description: Get free Flow tokens for testing. Faucets are like taps for tokens, useful for trying Flow without buying tokens. sidebar_custom_props: icon: 💧 @@ -15,96 +15,4 @@ Network Faucets provide free Flow tokens for testing purposes, functioning like [Flow Faucet](https://faucet.flow.com/fund-account) is a dedicated tool that provides a seamless way to acquire small amounts of Flow tokens for testing and development purposes on the Flow blockchain's testnet environment. -### Supported Networks - -- [Testnet](https://faucet.flow.com/fund-account) - -## LearnWeb3 Flow Faucet - -[LearnWeb3 Flow Faucet](https://learnweb3.io/faucets/flow) is a community faucet tool that provides a seamless way to acquire small amounts of Flow tokens for testing and development purposes on the Flow blockchain's testnet environment. - -### Supported Networks - -- [Testnet](https://learnweb3.io/faucets/flow) -
- -## Using Flow Faucet - -### Funding Your Account - -If you already have a Flow account, you can fund it directly from the Faucet's landing page. Simply paste the address of the account you want to fund, complete the CAPTCHA, and click "Fund Your Account." - -![fund-your-account](./faucet-fund-account.png) - -After a few seconds, you'll see your account's FLOW balance as a confirmation. Note, the Faucet will automatically determine if the address you paste is a Flow or EVM address and will fund the account accordingly. - -### Creating a Flow Account - -#### Generate a Key Pair - -To create a Flow-native account, you'll need to generate a key pair. You can do this most easily [Flow CLI](../build/getting-started/flow-cli.md) with the [`keys generate` command](../tools/flow-cli/keys/generate-keys.md) - -```sh -flow keys generate -``` - -You'll receive a private key and a public key pair with default `ECDSA_P256` signature and `SHA3_256` hash algorithms. - -```sh -❯ flow keys generate - -🔴️ Store private key safely and don't share with anyone! -Private Key -Public Key -Mnemonic -Derivation Path m/44'/539'/0'/0/0 -Signature Algorithm ECDSA_P256 -``` - -You can then use the public key to create a new Flow account on the Faucet. Copy the resulting public key for the next step. - -#### Create a Flow-Native Account - -From the Faucet's landing page, click on the "Create Account" button. You'll be prompted to enter your public key. Paste the public key you generated using the Flow CLI and click "Create Account." - -:::tip - -Know that there is a distinction between Flow native accounts and EVM accounts. Native accounts allow you to interact with the Cadence runtime, while EVM accounts are used for interacting with Flow's EVM. To create an EVM account, you can use EVM tooling to generate an Ethereum Owned Account (EOA) and simply fund the associated address. Alternatively, you can create an EVM account controlled by your Flow native account - known as a Cadence Owned Account (COA) - in which case you'll need a Flow native account and should continue with the steps below. - -For more information interacting with EVM via COAs, see the [Interacting With COAs documentation](../tutorials/cross-vm-apps/interacting-with-coa.md). - -::: - -![create-flow-account](./faucet-create-account.png) - -You can then paste your public key into the input field, complete the CAPTCHA, and click "Create Account." - -![input-public-key](./faucet-input-public-key.png) - -You'll be met with a confirmation screen, showing your Flow account address and the funded balance. - -![account-created](./faucet-account-created.png) - -#### Using your Flow Account - -Once your account has been created, you can add the account to your `flow.json` configuration file under the `accounts` attribute, like so: - -```json -{ - "accounts": { - "testnet-dev-account": { - "address": "", - "key": "" - } - } -} -``` - -:::warning - -If you plan on using your flow.json in a production environment, you'll want to look at alternative methods to manage your keys more securely, at minimum using environment variables instead of storing your account private keys in plain text. See [How to Securely Use CLI](../tools/flow-cli/flow.json/security.md) for more information on alternate key management strategies and how to configure them in your `flow.json` file. - -::: - -After adding your account to your `flow.json` file, you're ready to use your account in your project. You can now deploy contracts, run transactions, and interact with the Flow blockchain using your new account. diff --git a/docs/ecosystem/Hackathons and Events/index.md b/docs/ecosystem/hackathons-and-events.md similarity index 96% rename from docs/ecosystem/Hackathons and Events/index.md rename to docs/ecosystem/hackathons-and-events.md index bf26658006..0520ae8c63 100644 --- a/docs/ecosystem/Hackathons and Events/index.md +++ b/docs/ecosystem/hackathons-and-events.md @@ -1,9 +1,7 @@ --- title: Hackathons and Events description: Participate in Flow hackathons to build, learn, and win prizes -sidebar_position: 11 -sidebar_custom_props: - icon: 🚀 +sidebar_position: 3 --- # Flow World Tour Hackathons diff --git a/docs/ecosystem/index.mdx b/docs/ecosystem/index.mdx index 6a4ecefe1a..1ff0d37243 100644 --- a/docs/ecosystem/index.mdx +++ b/docs/ecosystem/index.mdx @@ -1,6 +1,6 @@ --- sidebar_position: 1 -title: Ecosystem +title: Ecosystem Index description: Access essential tools, knowledge, and community connections for the Flow Blockchain ecosystem. --- diff --git a/docs/ecosystem/projects.mdx b/docs/ecosystem/projects.mdx index 8c4f21d041..f77172c3fe 100644 --- a/docs/ecosystem/projects.mdx +++ b/docs/ecosystem/projects.mdx @@ -17,7 +17,7 @@ Explore an array of exciting, grassroots initiatives, and projects that thrive w label: 'TokenList', href: 'https://token-list.fixes.world/', description: - 'Permissionless Fungible/Non-Fungible Tokens registration on Flow Blockchain with on-chain MetadataViews and API for Uniswap JSON file.', + 'Permissionless Fungible/Non-Fungible Tokens registration on Flow Blockchain with onchain MetadataViews and API for Uniswap JSON file.', customProps: { icon: '', author: { @@ -28,57 +28,6 @@ Explore an array of exciting, grassroots initiatives, and projects that thrive w githubLink: 'https://github.com/fixes-world/token-list', }, }, - { - type: 'link', - label: 'DEV.to', - href: 'https://dev.to/onflow', - description: - 'A constructive and inclusive social network for software developers where you can interact with others in the Flow community', - customProps: { - icon: 'https://dev-to-uploads.s3.amazonaws.com/uploads/logos/resized_logo_UQww2soKuUsjaOGNB38o.png', - author: { - name: 'Flow Blockchain', - profileImage: - 'https://avatars.githubusercontent.com/u/62387156?s=200&v=4', - }, - twitterLink: 'https://twitter.com/flow_blockchain', - githubLink: 'https://github.com/onflow', - }, - }, - { - type: 'link', - label: 'Emerald City', - href: 'https://www.ecdao.org/', - description: 'The first DAO built on the Flow Blockchain', - customProps: { - icon: 'https://academy.ecdao.org/ea-logo.png', - author: { - name: 'Emerald City DAO', - profileImage: - 'https://pbs.twimg.com/profile_images/1687225095557632005/tUCmv8_P_400x400.jpg', - }, - twitterLink: 'https://twitter.com/emerald_dao', - githubLink: 'https://github.com/emerald-dao', - }, - }, - { - type: 'link', - label: 'FLOAT', - href: 'https://floats.city/', - description: - 'A Flow enabled proof of attendance platform with over 2.2 million FLOATs claimed and 4600+ events created', - customProps: { - icon: 'https://floats.city/float-logo.svg', - author: { - name: 'Emerald City DAO', - profileImage: - 'https://pbs.twimg.com/profile_images/1687225095557632005/tUCmv8_P_400x400.jpg', - }, - numStars: 0, - twitterLink: 'https://twitter.com/emerald_dao', - githubLink: 'https://github.com/emerald-dao/float', - }, - }, { type: 'link', label: 'Flow Ecosystem Fund', @@ -96,41 +45,6 @@ Explore an array of exciting, grassroots initiatives, and projects that thrive w githubLink: 'https://github.com/onflow', }, }, - { - type: 'link', - label: 'Flow Bug Bounty Program', - href: 'https://flow.com/flow-responsible-disclosure', - description: - 'Get rewarded for finding security vulnerabilities in on of our products or platforms.', - customProps: { - icon: 'https://assets.website-files.com/5f734f4dbd95382f4fdfa0ea/62763e067575490bc83fe807_Group%20822.svg', - author: { - name: 'Flow', - profileImage: - 'https://avatars.githubusercontent.com/u/62387156?s=200&v=4', - }, - numStars: 0, - twitterLink: 'https://twitter.com/flow_blockchain', - }, - }, - { - type: 'link', - label: 'Buildspace', - href: 'https://buildspace.so/p/nfts-on-flow', - description: - 'Learn how to deploy your first Flow smart contract using Cadence and build a web3 React app to connect it together', - customProps: { - icon: '/images/content/buildspace.svg', - author: { - name: 'Buildspace', - profileImage: - 'https://img.api.cryptorank.io/coins/150x150.buildspace1668414728723.png', - }, - numStars: 0, - twitterLink: 'https://twitter.com/_buildspace', - githubLink: 'https://github.com/buildspace', - }, - }, { type: 'link', label: 'Flowverse', @@ -181,23 +95,6 @@ Explore an array of exciting, grassroots initiatives, and projects that thrive w twitterLink: 'https://twitter.com/flowty_io', }, }, - { - type: 'link', - label: 'Flowser', - href: 'https://flowser.dev/', - description: - 'Flowser combines all the tools for local development and gives you a clear UI to inspect the local Flow network.', - customProps: { - icon: 'https://flowser.dev/icon.png', - author: { - name: 'Flowser', - profileImage: 'https://flowser.dev/icon.png', - }, - numStars: 0, - twitterLink: 'https://twitter.com/onflowser', - githubLink: 'https://github.com/onflowser/flowser', - }, - }, { type: 'link', label: 'Overflow', @@ -232,23 +129,6 @@ Explore an array of exciting, grassroots initiatives, and projects that thrive w githubLink: 'https://github.com/findonflow/findlabs-api', }, }, - { - type: 'link', - label: 'Flooks', - href: 'https://www.flooks.io/', - description: - "React hooks to interact with Flow blockchain, making development easy and intuitive. It's wagmi for Flow!", - customProps: { - icon: '', - author: { - name: 'Doodles', - profileImage: - 'https://avatars.githubusercontent.com/u/96498387?s=200&v=4', - }, - twitterLink: 'https://twitter.com/doodles', - githubLink: 'https://github.com/doodles/flooks', - }, - }, { type: 'link', label: 'Stake & Eggs', diff --git a/docs/ecosystem/wallets.md b/docs/ecosystem/wallets.md index 2cc8127aab..6bf7b63551 100644 --- a/docs/ecosystem/wallets.md +++ b/docs/ecosystem/wallets.md @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 4 description: Store, manage, and interact securely with tokens and digital assets on Flow. Discover a range of wallets that offer convenient ways to handle and safeguard your cryptocurrency holdings, ensuring easy access and enhanced security for your transactions and assets. sidebar_custom_props: icon: 🔑 @@ -13,7 +13,7 @@ Store, manage, and interact securely with tokens and digital assets on Flow. Dis ## Flow Wallet -[Flow Wallet](https://wallet.flow.com/) - The is the most popular Flow-native wallet, it sponsors all gas fees for users and interacts seamlessly with both Cadence and EVM dApps in the ecosystem. +[Flow Wallet](https://wallet.flow.com/) - The is the most popular Flow-native wallet, it sponsors all compute unit (gas) fees for users and interacts seamlessly with both Cadence and EVM dApps in the ecosystem. ## Ledger @@ -25,11 +25,11 @@ Store, manage, and interact securely with tokens and digital assets on Flow. Dis ## NuFi -[NuFi](https://https://nu.fi/) allows you to securely manage tokens and NFTs, trade, stake, and use apps on multiple blockchains. Presently only supports Flow EVM and cannot access Cadence accounts. +[NuFi](https://nu.fi/) allows you to securely manage tokens and NFTs, trade, stake, and use apps on multiple blockchains. Presently only supports Flow EVM and cannot access Cadence accounts. ## Rabby -[Rabby](https://https://rabby.io/) - The game-changing wallet for Ethereum and all EVM chains. Presently only supports Flow EVM and cannot access Cadence accounts. +[Rabby](https://rabby.io/) - The game-changing wallet for Ethereum and all EVM chains. Presently only supports Flow EVM and cannot access Cadence accounts. ## Wallet Connect @@ -47,7 +47,7 @@ Store, manage, and interact securely with tokens and digital assets on Flow. Dis ## Flow Dev Wallet -[The Flow Dev Wallet](../tools/flow-dev-wallet/index.md) simulates the protocols used by [FCL](../tools/clients/fcl-js/index.md) to interact with the Flow blockchain on behalf of simulated user accounts. +[The Flow Dev Wallet](../build/tools/flow-dev-wallet/index.md) simulates the protocols used by [FCL](../build/tools/clients/fcl-js/index.md) to interact with the Flow blockchain on behalf of simulated user accounts. ## Magic.link diff --git a/docs/evm/about.md b/docs/evm/about.md deleted file mode 100644 index 968978c368..0000000000 --- a/docs/evm/about.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Flow – Fast EVM Equivalent Blockchain with Low Fees -sidebar_label: Why EVM on Flow -sidebar_position: 1 -description: Build on Flow, a fast EVM equivalent blockchain with low fees. An Ethereum alternative for apps with seamless onboarding, MEV resilience, and scalability. -keywords: - - Flow EVM - - Fast EVM - - EVM equivalency - - Ethereum developers - - Solidity - - Low GAS fees - - scalability - - MEV resistance - - account abstraction - - cross-vm transfers - - Cadence - - sponsored transactions - - developer experience ---- - -# Why EVM on Flow - -Flow is a [fast EVM equivalent blockchain with low fees], making it an ideal **Ethereum alternative for apps** that need both performance and affordability. With EVM equivalency, Solidity developers can deploy existing contracts on Flow without rewriting code, instantly gaining access to Flow’s ultra-fast transactions, low costs, and mainstream scalability. Builders can tap into Flow’s unique IPs and large user base with no implementation risk. - -## Seamless Integration for Ethereum Developers - -Flow EVM is designed to work out-of-the-box with the Ethereum toolchain or other clients. Native EVM transactions also continue to be supported when using Metamask and other EVM-compatible clients. -EVM-equivalency on Flow works behind-the-scenes by implementing a minimal transaction script in Cadence, Flow's smart contract language, to integrate Flow features with EVM. This is made possible because EVM transactions are composed and executed within Cadence transactions, enabling novel use-cases and patterns for integration. - -## Best-In-Class UX - -Flow allows for the creation of app on-boarding experiences that meet every type of user exactly where they are at, from web3 beginners to ecosystem veterans. This is possible through Account Linking, which utilizes the account abstraction model on Flow and enables users to immediately use an app without wallet authentication. On-chain accounts can be created as needed by the application which custodies their use for an anonymous user. At some later point these users may choose to link the custodied account to their self-custodial wallet taking full ownership of the account. EVM apps on Flow can also leverage Account Linking to handle creation of accounts and achieve a similarly smooth onboarding user experience. - -With Flow, builders can choose to expand EVM capabilities and transcend limitations using Cadence, which offers a powerful new account model, programmable resources, and hybrid ownership. - -## Instant Cross-VM Token Transfers - -EVM and Cadence environments both use FLOW as gas for transactions, sharing a singular token supply across both environments. Fungible and non-fungible tokens can also be seamlessly transferred between environments using the native VM token bridge, taking place instantly in a single atomic transaction. - -## Scalability, Performance and Low Gas Fees - -For sustainable user adoption, apps require the network they build on to be secure, efficient, affordable and fast. Gas fees are ultra-low cost on the network, but Flow goes a step further allowing for gasless experiences through sponsored transactions. Scalable performance is ensured with an innovative multi-node distributed consensus, flexible transaction model and horizontally scaled transaction linearization which solves proposer-builder separation, separation of compute, and settlement – all without sharding. - -Flow’s state space is extensible to the petabyte scale making it easy to store application data on-chain. This means contracts can maintain a full working dataset - including metadata - together with contract logic. - -Flow's transaction throughput peaked to 2M daily transactions during 2023 sustaining a similar average transaction volume as Ethereum. Unlike Ethereum, Flow has always operated well under its maximum throughput ceiling which is presently scalable to 5x more transactions with further performance optimizations to come when parallel execution is released. State scalability on Flow sets the foundations for further significant throughput optimization. - -## MEV Resilience - -The [MEV Resilient](../build/basics/mev-resistance.md) design on Flow offers DeFi builders improved market efficiency, fairness, trust and long-term viability for their apps. Since Flow EVM transactions are composed and executed within a Cadence transaction, block production is handled by Flow’s [multi-role architecture](https://flow.com/post/flow-blockchain-multi-node-architecture-advantages). This heterogeneity between node roles ensures that visibility into block proposal, assembly, asserting block validity and other correctness checks during the block production cycle exposes limited information to each node type on a need to know basis, observing the Principle of Least Privilege. These differences in node and consensus design results in strong economic disincentives for collusion because no individual node has full visibility into the state of block production for the chain. This robust MEV resilience is a significant difference from other EVM-compatible networks and results in reasonably priced, predictable gas fees. The impracticality of frontrunning or other attacks improves the user experience by eliminating failed transactions and invisible fees. - -## Join the Community - -Are you interested in launching an EVM project on Flow or partnering with us? Visit our weekly Flow [office hours](https://calendar.google.com/calendar/ical/c_47978f5cd9da636cadc6b8473102b5092c1a865dd010558393ecb7f9fd0c9ad0%40group.calendar.google.com/public/basic.ics) for discussions on project development and other opportunities for collaboration. You can also chat with us developers-chat in the Flow [Discord](https://discord.gg/flow). - -## Further Reading and Discussions - -- [Why EVM on Flow: Beyond Solidity](https://forum.flow.com/t/evm-on-flow-beyond-solidity/5260) -- [Path to EVM Equivalence on Flow](https://forum.flow.com/t/evm-equivalence-on-flow-proposal-and-path-forward/5478) - -## Flow Improvement Proposals (FLIPs) - -Those wishing to understand the technical specifics of how Flow EVM works we recommend reviewing the following improvement proposals. - -- Understanding [EVM Support on Flow](https://github.com/onflow/flips/pull/225) -- Exploring the [Flow VM Bridge](https://github.com/onflow/flips/pull/233/files/d5bc46c4b13f0b9b168a94f994c77a5a689f6b24..122e938b7acae7e774246b1b66aaf5979ca21444) -- Insights into the [Flow EVM Gateway](https://github.com/onflow/flips/pull/235/files) -- Integration of the [Cadence Interface](https://github.com/onflow/flips/blob/f646491ec895442dcccdb24d80080bab1c56188e/protocol/20231116-evm-support.md) - -## Build with Flow - -Whether you’re porting an existing Solidity dApp or building from scratch, Flow offers a **fast, EVM equivalent blockchain with low fees** and the tooling you already know. As a **scalable Ethereum alternative for apps**, Flow combines familiar development workflows with performance and UX enhancements you can’t get elsewhere. - - -[fast EVM equivalent blockchain with low fees]: https://flow.com/ \ No newline at end of file diff --git a/docs/evm/block-explorers.mdx b/docs/evm/block-explorers.mdx deleted file mode 100644 index 766e7768a5..0000000000 --- a/docs/evm/block-explorers.mdx +++ /dev/null @@ -1,14 +0,0 @@ ---- -slug: /evm/block-explorers -redirect: /ecosystem/block-explorers -title: Block Explorers ↙ -sidebar_position: 11 ---- - -# Faucets - -Go to [Block explorers](../ecosystem/block-explorers.md) - -import {Redirect} from '@docusaurus/router'; - -; diff --git a/docs/evm/cross-chain-bridges.mdx b/docs/evm/cross-chain-bridges.mdx deleted file mode 100644 index d0b6a4116a..0000000000 --- a/docs/evm/cross-chain-bridges.mdx +++ /dev/null @@ -1,14 +0,0 @@ ---- -slug: /evm/cross-chain-bridges -redirect: /ecosystem/bridges -title: Cross-chain Bridges ↙ -sidebar_position: 8 ---- - -# Cross-chain Bridges - -Go to [Bridges](../ecosystem/bridges.md) - -import {Redirect} from '@docusaurus/router'; - -; diff --git a/docs/evm/faucets.mdx b/docs/evm/faucets.mdx deleted file mode 100644 index 71a61ab89a..0000000000 --- a/docs/evm/faucets.mdx +++ /dev/null @@ -1,14 +0,0 @@ ---- -slug: /evm/faucets -redirect: /ecosystem/faucets -title: Faucets ↙ -sidebar_position: 10 ---- - -# Faucets - -Go to [Faucets](../ecosystem/faucets.md) - -import {Redirect} from '@docusaurus/router'; - -; diff --git a/docs/evm/fees.md b/docs/evm/fees.md deleted file mode 100644 index dfe8a61d3c..0000000000 --- a/docs/evm/fees.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: Fees -sidebar_label: Fees -sidebar_position: 6 ---- - -:::info - -Are you a Cadence developer looking for information about Fees on Cadence? If so, check out the Cadence specific documentation [here](../build/basics/fees.md) - -::: - -EVM transactions are ultra low-cost and use the native FLOW token as gas. [Externally Owned Accounts (EOAs)](https://developers.flow.com/evm/build/accounts) function the same on Flow as other EVM networks like Ethereum. - -
-

How Transaction Fees are Computed on EVM

- -With Flow EVM, EVM operations can now be called within Cadence transactions. EVM operations also have an associated effort measured in gas which needs to be factored into the execution effort calculation in addition to the Flow computation for any EVM transaction. - -``` -Transaction fee on EVM = surge x [inclusion fee + (execution effort * unit cost)] -``` - -- `Surge' factor` dynamically accounts for network pressure and market conditions. This is currently constant at 1.0 but subject to change with community approval. -- `Inclusion fee` accounts for the resources required to process a transaction due to its core properties (byte size, signatures). This is currently constant at 1E-6 FLOW, but subject to change with community approval. -- `Execution fee` The fee that accounts for the operational cost of running the transaction script, processing the results, sending results for verification, generating verification receipts, etc. and is calculated as a product of `execution effort units` and the `cost per unit`. - - `Execution Effort (computation)` is based on transaction type and operations that are called during the execution of a transaction. The weights determine how “costly” (time consuming) each operation is. - - `Execution Effort Unit Cost` = `2.49E-07 FLOW` (currently constant, but subject to change with community approval) - -

Calculation of Execution Effort

- -``` -Execution Effort (computation) = - 0.00478 * function_or_loop_call + - 0.00246 * GetValue + - 0.00234 * SetValue + - 8.65988 * CreateAccount + - EVMGasUsageCost * EVMGasUsage -``` - -where - -``` -`EVMGasUsage` is reported by EVM as the cost in gas for executing the transaction within the EVM, for instance, 21K gas for a simple send transaction. -``` - -``` -`EVMGasUsageCost` - The ratio that converts EVM gas into Flow computation units (execution effort) is currently set at `1/5000` but subject to revision by community approval -``` - -**Note**: The weights and unit cost mentioned above have been updated recently to accommodate an increased computation limit on Flow, which now supports the deployment of larger EVM contracts. For detailed information, refer to the relevant [FLIP](https://github.com/onflow/flips/blob/main/governance/20240508-computation-limit-hike.md) and join the ongoing discussion on the community [forum post](https://forum.flow.com/t/proposing-transaction-fee-changes-and-flow-evm-gas-charges-for-flow-crescendo-launch/5817). These values may be adjusted in the future based on community feedback and evolving requirements. - -
- -
-

Demonstration of Transaction Fees on EVM

- -Assume a simple NFT transfer transaction that makes 31 cadence loop calls, reads 5668 bytes from the storage register, and saves 1668 bytes to the storage register. - -- 'function_or_loop_call' = 31 -- 'GetValue' = 5688 -- 'SetValue' = 1668 -- 'CreateAccount' = 0 - -**Scenario 1 - Cadence-only Transaction** - -``` -Execution Effort = 0.00478 * (31) + 0.00246 * (5668) + 0.00234 *(1668) + 8.65988 *(0) + EVMGasUsageCost * EVMGasUsage -``` - -But since `EVMGasUsage` is 0 for a Cadence transaction, - -``` -Execution Effort = 18.04378 -``` - -Thus - -``` -Transaction fee = [1E-6 FLOW + (18.04378 * 2.49E-07 FLOW)] x 1 = 5.5E-06 FLOW -``` - -**Scenario 2 - EVM Transaction** -If the EVMGasUsage can be assumed to be 21,000 gas (typical for a simple transfer), - -``` -Execution Effort = 0.00478 * (31) + 0.00246 * (5668) + 0.00234 *(1668) + 8.65988 *(0) + 1/5000 * 21000 = 22.24378 -``` - -Thus - -``` -Transaction fee = [1E-6 FLOW + (110.97 * 2.49E-07 FLOW)] x 1 = 6.55E-06 FLOW -``` - -**Note**: Please be aware that this example serves solely for illustrative purposes to elucidate the calculations. Actual transaction fees may differ due to various factors, including the byte size of the transaction. - -
- -## Gasless Transactions - -Fees needed to execute transactions on a Web3 app are often a major challenge for new users and can be a barrier to adoption. Builders can easily extend their apps with Cadence to create ‘gasless’ experiences by specifying their app as the [sponsor](../build/advanced-concepts/account-abstraction.md#sponsored-transactions) instead of the user. - -To learn more about storage fee and transaction fee, visit [Flow Tokenomics page](https://flow.com/flow-tokenomics/technical-overview). diff --git a/docs/evm/guides/_category_.yml b/docs/evm/guides/_category_.yml deleted file mode 100644 index 0c03ef3d16..0000000000 --- a/docs/evm/guides/_category_.yml +++ /dev/null @@ -1,2 +0,0 @@ -label: Guides -position: 11 diff --git a/docs/evm/guides/index.md b/docs/evm/guides/index.md deleted file mode 100644 index 072bbb6b03..0000000000 --- a/docs/evm/guides/index.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Flow EVM Guides -description: Tutorials and guides for building on Flow EVM, integrating with popular Ethereum tools, and leveraging Flow's unique features. -sidebar_position: 1 -keywords: - - Flow EVM - - guides - - tutorials - - Ethereum - - Solidity - - Foundry - - Hardhat - - Remix - - wagmi - - RainbowKit - - web3.js - - ethers.js ---- - -# EVM Guides - -This section contains guides and tutorials for building on [Flow EVM], integrating with popular Ethereum tools, and leveraging Flow's unique features. - -## Guides - -- **[Integrating MetaMask]** - How to connect MetaMask to Flow EVM and interact with your dapps. -- **[Using ethers.js]** - Learn to use ethers.js with Flow EVM for contract interaction and account management. -- **[Using web3.js]** - Use web3.js to build and interact with Flow EVM smart contracts. -- **[Using wagmi]** - Integrate wagmi for React-based EVM dapps on Flow. -- **[Using RainbowKit]** - Add wallet connection and onboarding with RainbowKit in your Flow EVM dapp. -- **[Using Foundry]** - Develop, test, and deploy smart contracts on Flow EVM using Foundry. -- **[Using Hardhat]** - Build, test, and deploy Solidity contracts on Flow EVM with Hardhat. -- **[Using Remix]** - Write, deploy, and interact with contracts on Flow EVM using the Remix IDE. - -## More Coming Soon - -Stay tuned - more guides and advanced tutorials are on the way! - -[Flow EVM]: ../about.md -[Integrating MetaMask]: ./integrating-metamask.mdx -[Using ethers.js]: ./ethers.md -[Using web3.js]: ./web3-js.md -[Using wagmi]: ./wagmi.md -[Using RainbowKit]: ./rainbowkit.md -[Using Foundry]: ./foundry.md -[Using Hardhat]: ./hardhat.md -[Using Remix]: ./remix.md diff --git a/docs/evm/networks.md b/docs/evm/networks.md deleted file mode 100644 index 0a12969142..0000000000 --- a/docs/evm/networks.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Network Information -sidebar_label: Network Information -sidebar_position: 5 ---- - -# Network Information - -Flow EVM has the following public RPC nodes available: - -# Mainnet - -| Name | Value | -| --------------- | ------------------------------------ | -| Network Name | Flow EVM Mainnet | -| Description | The public RPC URL for Flow Mainnet | -| RPC Endpoint | https://mainnet.evm.nodes.onflow.org | -| Chain ID | 747 | -| Currency Symbol | FLOW | -| Block Explorer | https://evm.flowscan.io | - -# Testnet - -| Name | Value | -| --------------- | ------------------------------------ | -| Network Name | Flow EVM Testnet | -| Description | The public RPC URL for Flow Testnet | -| RPC Endpoint | https://testnet.evm.nodes.onflow.org | -| Chain ID | 545 | -| Currency Symbol | FLOW | -| Block Explorer | https://evm-testnet.flowscan.io | diff --git a/docs/growth/index.md b/docs/growth/index.md deleted file mode 100644 index 450259613f..0000000000 --- a/docs/growth/index.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -sidebar_position: 1 -title: Growth -description: Get advice, support, and resources for each stage of development for your project. ---- - -At each stage of your project, you can get advice, support, and resources from the Flow ecosystem. Here's a breakdown of _what you are doing_ and _what support we offer_ at each stage: - -## Product Idea - -You've got an **idea** for an app, game, or project that you want to build on Flow. - -### What you are doing - -* Developing the idea in a written format, such as a pitch deck, whitepaper, design doc, or business plan -* Writing software -* Joining a hackathon or buildathon - -### What support we offer - -* Technical support -* Product support -* Marketing support for your launch -* DevRel - -## MVP/Demo/Hackathon Project Complete - -You've got something that works in a place others can use it and experience key features of your product. - -### What you are doing - -* Writing software -* Integrating with service providers -* Getting user feedback and improving your product - -### What support we offer - -* Direct contact with Flow Foundation through a DevRel Lead. -* Feedback and Guidence from the Flow Foundation team - -## Live product on mainnet - -Real people are using your app regularly and doing the types of things that you are or will eventually generate revenue from (even if it's still a small number of users). - -### What you are doing - -* Acquiring users -* Tracking metrics -* Improving your product -* Raising funds -* Micro grants - -### What support we offer - -* BizDev Support (intros, etc) -* Dedicated slack or tg channel -* DevRel - -## Product market fit - -You've got an app and are meeting the needs of regular customers. Core features are implemented, edge cases are handled, and most of your asterisks are resolved. - -### What you are doing - -* Acquiring users -* Tracking metrics -* Improving your product - -### What support we offer - -* Fundraising support (intros to investor network) -* Grants tied to bigger ecosystem milestones -* DevRel diff --git a/docs/networks/flow-networks/index.md b/docs/networks/flow-networks/index.md deleted file mode 100644 index 57ff027c57..0000000000 --- a/docs/networks/flow-networks/index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Flow Networks -sidebar_position: 1 ---- - -## About Flow Networks - -:::note - -This page provides information on Flow network RPCs. Flow EVM network RPCs can be found [here](../evm/networks) - -::: - -In addition to Mainnet, developers have access to the Testnet environment, which serves as an essential testing ground for applications and smart contracts prior to their deployment on Mainnet. This ensures that any potential issues can be identified and resolved in a controlled setting, mitigating risks associated with live deployment. - -Furthermore, during network upgrades, Testnet receives updates ahead of Mainnet. This preemptive update process allows developers to comprehensively test their apps against the latest versions of the nodes, enhancements to the Cadence programming language, and core contract upgrades. This strategy guarantees that when these updates are eventually applied to Mainnet, applications and smart contracts will operate seamlessly, enhancing overall network stability and user experience. - -### How To Access These Networks? - -| Network | GRPC | Web GRPC | REST | -| ------- | -------------------------------------- | -------------------- | ------------------------- | -| Mainnet | `access.mainnet.nodes.onflow.org:9000` | `mainnet.onflow.org` | `rest-mainnet.onflow.org` | -| Testnet | `access.devnet.nodes.onflow.org:9000` | `testnet.onflow.org` | `rest-testnet.onflow.org` | - -For more information on how to access these networks, refer to the following guides: - -- [Flow Testnet](./accessing-testnet.md) -- [Flow Mainnet](./accessing-mainnet.md) - -### Network - -There are two primary ways to access on-chain data within the Flow network; Access Nodes and Light nodes. Access Nodes are the node type that are most useful for developers, as they provide access to the Flow network via the following API endpoints: - -- [Flow Access API](../access-onchain-data/index.md) - - [Mainnet](./accessing-mainnet.md): `access.mainnet.nodes.onflow.org:9000` - - [Testnet](./accessing-testnet.md): `access.devnet.nodes.onflow.org:9000` -- [Status Page](https://status.onflow.org/) - Network status page - -### Rate limits - -Rate limits for Flow Public Access nodes hosted by QuickNode are detailed [here](https://www.quicknode.com/docs/flow#endpoint-rate-limits). - -### Running Your Own Node - -If you’re getting started you don’t need to run your own node and you can use the above public nodes. The public access nodes are rate-limited, so as your product matures you might want to run your own node. There are multiple options available: - -- Start with a [Light (Observer) Node](../node-ops/light-nodes/observer-node.md). -- You can also use a third-party provider like [Quicknode](https://www.quicknode.com/docs/flow). - -Check out [Running a Node](../node-ops/light-nodes/observer-node.md) for more information. diff --git a/docs/networks/node-ops/node-operation/upcoming-sporks.md b/docs/networks/node-ops/node-operation/upcoming-sporks.md deleted file mode 100644 index 98a5d44d28..0000000000 --- a/docs/networks/node-ops/node-operation/upcoming-sporks.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Upcoming Sporks -description: Information about upcoming Mainnet & Testnet sporks -sidebar_position: 16 ---- - -The following are the upcoming Spork dates. These dates indicate the intention to Spork. Announcements will be made regarding any delays or changes to these dates in our developer [Discord server](https://discord.gg/flow). - -
- -| Mainnet Spork Date | Spork Info | Testnet Spork Date | Spork Info | -|:----------------------------|:---------------------------------------|------------------------------------------|------------| -| ~Q3 2024 (exact date tbd) | | Q3 2024 (exact date tbd) | | - | | | May 20, 2024 | Devnet50 | -| Nov 8, 2023 | Mainnet 24 | Nov 2, 2023 | Devnet49 | -| | | Aug 4, 2023 | Devnet48 | -| | | Aug 4, 2023 | Devnet47 | -| June 21, 2023 | Mainnet 23 | Jun 8, 2023 | Devnet46 | -| | | Jun 7, 2023 | Devnet45 | -| | | Apr 24, 2023 | Devnet44 | -| | | Apr 12, 2023 | Devnet43 | -| | | Apr 12, 2023 | Devnet42 | -| Feb 22, 2023 | Mainnet 22 | Jan 30, 2023 —> Feb 22, 2023 | Devnet41 | -| | | Jan 23, 2023 | Devnet40 | -| Jan 18, 2023 | Mainnet 21 | Jan 4, 2023 —> Jan 18, 2023 | Devnet39 | -| Nov 2, 2022 | Mainnet 20 | Oct 19, 2022 —> Nov 2, 2022 | Devnet38 | -| Aug 24, 2022 | Mainnet 19 | Aug 10, 2022 —> Aug 24, 2022 | Devnet37 | -| | | Jul 27, 2022 | Devnet36 | -| June 15, 2022 | [Mainnet 18](./past-upgrades#mainnet-18) | June 9, 2022 —> June 15, 2022 | Devnet35 | -| April 6, 2022 | [Mainnet 17](./past-upgrades#mainnet-17) | April 4, 2022 —> April 6, 2022 | Devnet34 | -| February 9, 2022 | [Mainnet 16](./past-upgrades#mainnet-16) | February 7, 2022 —> February 9, 2022 | Devnet33 | -| December 8, 2021 | [Mainnet 15](./past-upgrades#mainnet-15) | December 7, 2021 —> December 8, 2021 | Devnet32 | -| November 10, 2021 | Cancelled | November 9, 2021 —> November 10, 2021 | Devnet31 | -| October 6, 2021 | [Mainnet 14](./past-upgrades#mainnet-14) | October 5, 2021 —> October 6, 2021 | Devnet30 | -| September 15, 2021 | [Mainnet 13](./past-upgrades#mainnet-13) | September 14, 2021 —> September 15, 2021 | Devnet27 | -| August 18, 2021 | [Mainnet 12](./past-upgrades#mainnet-12) | August 12, 2021 —> August 18, 2021 | Devnet26 | -| July 21, 2021 | [Mainnet 11](./past-upgrades#mainnet-11) | July 20, 2021 —> July 21, 2021 | Devnet25 | -| June 23, 2021 | [Mainnet 10](./past-upgrades#mainnet-10) | June 22, 2021 —> June 23, 2021 | Devnet24 | -| May 26, 2021 | [Mainnet 9](./past-upgrades#mainnet-9) | May 25, 2021 —> May 26, 2021 | Devnet23 | -| April 28, 2021 | [Mainnet 8](./past-upgrades#mainnet-8) | April 27, 2021 —> April 28, 2021 | Devnet22 | -| April 7, 2021 | [Mainnet 7](./past-upgrades#mainnet-7) | March 30, 2021 —> March 31, 2021 | Devnet21 | -| March 10, 2021 | [Mainnet 6](./past-upgrades#mainnet-6) | March 9, 2021 —> March 10, 2021 | Devnet20 | - -
diff --git a/docs/networks/staking/15-staking-guide.md b/docs/networks/staking/15-staking-guide.md deleted file mode 100644 index 209f786e8d..0000000000 --- a/docs/networks/staking/15-staking-guide.md +++ /dev/null @@ -1,261 +0,0 @@ ---- -title: Basic Staking with FLOW -sidebar_label: Basic Staking Guide (Deprecated) ---- - -This document outlines the steps a token holder can take to stake and manage -a Flow node with FLOW using only the types defined in the `FlowIDTableStaking` contract. -It only supports having one node or delegator object per account and is not supported by ledger -and will likely not be supported by other wallets, so it is recommended to use the staking collection -instead. - - -This guide covers staking with **FLOW tokens**. - - -# Staking - -## Setup - -### Register a New Staked Node - -To register as a node operator with FLOW, the token holder can use the **Register Node** ([SC.11](../../build/core-contracts/06-staking-contract-reference.md#staking)) -transaction with the following arguments: - -| Argument | Type | Description | -|-----------------------|----------|-------------| -| **id** | `String` | The ID of the new node. It must be a 32 byte `String`. The operator is free to choose this value, but it must be unique across all nodes. A recommended process to generate this is to hash the staking public key. | -| **role** | `UInt8` | The role of the new node. (1: collection, 2: consensus, 3: execution, 4: verification, 5: access) | -| **networkingAddress** | `String` | The IP address of the new node. (Length must be less than 255 bytes (510 Hex characters)) | -| **networkingKey** | `String` | The networking public key as a 64 byte hex-encoded `String` (128 hex characters) | -| **stakingKey** | `String` | The staking public key as a 96 byte hex-encoded `String` (192 hex characters) | -| **amount** | `UFix64` | The number of FLOW tokens to stake. | - -This transaction registers the account as a node operator with the specified node information -and creates a public link to query the nodes ID from the account address. - ---- - -Once the token holder has registered their node, -their tokens and node information are committed to the central staking contract for the next epoch. - -At this point, the token holder now has access to various staking operations that they can perform, -assuming they have the correct number of tokens to perform the action. - -## Stake Tokens - -The token holder can stake additional tokens at any time. - -_Note: this transaction stakes additional tokens to the same node that was registered in the setup phase._ - -To stake tokens, the token holder can use the **Stake FLOW** ([SC.12](../../build/core-contracts/06-staking-contract-reference.md#staking)) -transaction with the following arguments: - -| Argument | Type | Description | -|------------|----------|-------------| -| **amount** | `UFix64` | The number of FLOW tokens to stake. | - -This transaction commits tokens to stake from the token holder's account. - -## Re-stake Unstaked Tokens - -After tokens become unstaked, the token holder can choose to re-stake the unstaked tokens to the same node. - -To staked unstaked tokens, the token holder can use the **Re-stake Unstaked FLOW** ([SC.13](../../build/core-contracts/06-staking-contract-reference.md#staking)) -transaction with the following arguments: - -| Argument | Type | Description | -|------------|----------|-------------| -| **amount** | `UFix64` | The number of unstaked FLOW tokens to stake. | - -## Re-stake Rewarded Tokens - -After earning rewards from staking, the token holder can choose to re-stake the rewarded tokens to the same node. - -To stake rewarded tokens, the token holder can use the **Re-stake Rewarded FLOW** ([SC.14](../../build/core-contracts/06-staking-contract-reference.md#staking)) -transaction with the following arguments: - -| Argument | Type | Description | -|------------|----------|-------------| -| **amount** | `UFix64` | The number of rewarded FLOW tokens to stake. | - -## Request Unstake Tokens - -The token holder can submit a request to unstake some of their tokens at any time. -If the tokens aren't staked yet, they will be uncommitted and available to withdraw. - -To request to unstake staked tokens, the token holder can use -the **Request Unstaking** ([SC.15](../../build/core-contracts/06-staking-contract-reference.md#staking)) transaction. - -| Argument | Type | Description | -|------------|----------|-------------| -| **amount** | `UFix64` | The number of rewarded FLOW tokens to request to un-stake. | - -_Note: this transaction will not succeed if the node operator has delegators and the request -would put the node operator below the minimum required tokens staked for their node type. -Use the `Unstake All` transaction instead, which will also unstake all delegators._ - -_Note: unstaked tokens will be held by the central staking contract until the end of the following epoch. -Once the tokens are released (unstaked), they can be claimed via the -[Withdraw Unstaked Tokens](#withdraw-unstaked-tokens) action below._ - -## Unstake All Tokens - -The token holder can submit a request to unstake all their tokens at any time. -If the tokens aren't staked yet, they will be uncommitted and available to withdraw. - -To unstake all staked tokens, the token holder can use -the **Unstake All FLOW** ([SC.16](../../build/core-contracts/06-staking-contract-reference.md#staking)) transaction. - -This transaction requires no arguments. - -**Warning: this will unstake all of the user's staked tokens and unstake all of the tokens -from users that are delegating FLOW to the node.** - -## Withdraw Unstaked Tokens - -After tokens become unstaked, the token holder can withdraw them from the central staking contract. - -To withdraw unstaked tokens, -the token holder can use the **Withdraw Unstaked FLOW** ([SC.17](../../build/core-contracts/06-staking-contract-reference.md#staking)) -transaction with the following arguments: - -| Argument | Type | Description | -|------------|----------|-------------| -| **amount** | `UFix64` | The number of unstaked FLOW tokens to withdraw. | - -This transaction moves the unstaked tokens back into the `FlowToken.Vault` owned by the token holder. - -## Withdraw Rewarded Tokens - -After earning rewards from staking, the token holder can withdraw them from the central staking contract. - -To withdraw rewarded tokens, -the token holder can use the **Withdraw Rewarded FLOW** ([SC.18](../../build/core-contracts/06-staking-contract-reference.md#staking)) -transaction with the following arguments: - -| Argument | Type | Description | -|------------|----------|-------------| -| **amount** | `UFix64` | The number of rewarded FLOW tokens to withdraw. | - -This transaction moves the rewarded tokens back into the `FlowToken.Vault` owned by the token holder. - -## Stake Multiple Nodes from the Same Account - -Currently, the default staking transactions can only be used as they are to stake one node per account. - -If a token holder wants to create a second staking relationship using the transactions as is, they must create a new account -and transfer their tokens to the new account. - -It is possible to have multiple nodes per account by storing the node objects at different storage paths, -but this would require small changes to these transactions to use the new storage paths. - - -# Delegating - -## Setup - -## Register as a Delegator - -To register as a delegator, the token holder can use the **Register Delegator** ([SC.19](../../build/core-contracts/06-staking-contract-reference.md#delegating)) -transaction with the following arguments: - -| Argument | Type | Description | -|------------|----------|-------------| -| **id** | `String` | The ID of the node to delegate to. | -| **amount** | `UFix64` | The number of FLOW tokens to delegate. | - -This transaction registers the account as a delegator to the node ID they specified. - ---- - -## Delegate New Tokens - -The token holder can delegate additional tokens after registering as a delegator. - -_Note: this transaction delegates additional tokens to the same node that was registered in the setup phase._ - -To delegate new tokens, -the token holder can use the **Delegate New FLOW** ([SC.20](../../build/core-contracts/06-staking-contract-reference.md#delegating)) -transaction with the following arguments: - -| Argument | Type | Description | -|------------|----------|-------------| -| **amount** | `UFix64` | The number of FLOW tokens to delegate. | - -## Re-delegate Unstaked Tokens - -After delegated tokens become unstaked, the token holder can choose to re-delegate the unstaked tokens to the same node. - -To delegate unstaked tokens, -the token holder can use the **Re-delegate Unstaked FLOW** ([SC.21](../../build/core-contracts/06-staking-contract-reference.md#delegating)) -transaction with the following arguments: - -| Argument | Type | Description | -|------------|----------|-------------| -| **amount** | `UFix64` | The number of unstaked FLOW tokens to delegate. | - -## Re-delegate Rewarded Tokens - -After earning rewards from delegation, the token holder can choose to re-delegate the rewarded tokens to the same node. - -To delegate rewarded tokens, -the token holder can use the **Re-delegate Rewarded FLOW** ([SC.22](../../build/core-contracts/06-staking-contract-reference.md#delegating)) -| Argument | Type | Description | -| **amount** | `UFix64` | The number of rewarded FLOW tokens to delegate. | - -## Unstake Delegated Tokens - -The token holder can submit a request to unstake their delegated tokens at any time. -If the tokens aren't staked yet, they will be uncommitted and available to withdraw. - -To unstake delegated tokens, -the token holder can use the **Unstake Delegated FOW** ([SC.23](../../build/core-contracts/06-staking-contract-reference.md#delegating)) - -| Argument | Type | Description | -|------------|----------|-------------| -| **amount** | `UFix64` | The number of FLOW tokens to unstake. | - -_Note: unstaked delegated tokens will be held by the central staking contract for a period of time -(the rest of the current epoch plus all of the next epoch) before they are -released to the token holder. Once the tokens are released (unstaked), -they can be claimed via the [Withdraw Unstaked Tokens](#withdraw-unstaked-tokens) action below._ - -## Withdraw Unstaked Tokens - -After delegated tokens become unstaked, the token holder can withdraw them from the central staking contract. - -To withdraw unstaked tokens, -the token holder can use the **Withdraw Unstaked FLOW** ([SC.24](../../build/core-contracts/06-staking-contract-reference.md#delegating)) -transaction with the following arguments: - -| Argument | Type | Description | -|------------|----------|-------------| -| **amount** | `UFix64` | The number of unstaked FLOW tokens to withdraw. | - -This transaction moves the unstaked tokens back into the `FlowToken.Vault` owned by the token holder. - -## Withdraw Rewarded Tokens - -After earning rewards from delegation, the token holder can withdraw them from the central staking contract. - -To withdraw rewarded tokens, -the token holder can use the **Withdraw Rewarded FLOW** ([SC.25](../../build/core-contracts/06-staking-contract-reference.md#delegating)) -transaction with the following arguments: - -| Argument | Type | Description | -|------------|----------|-------------| -| **amount** | `UFix64` | The number of rewarded FLOW tokens to withdraw. | - -This transaction moves the rewarded tokens back into the `FlowToken.Vault` owned by the token holder. - -## Delegate to Multiple Nodes from the Same Account - -Currently, the default delegating transactions can only be used as they are to stake one node per account. - -If a token holder wants to create a second delegating relationship using the transactions as is, they must create a new account -and transfer their tokens to the new account. - -It is possible to have multiple delegator objects per account -by storing the node objects at different storage paths, -but this would require small changes to these transactions to use the new storage paths. diff --git a/docs/networks/access-onchain-data/_category_.yml b/docs/protocol/access-onchain-data/_category_.yml similarity index 100% rename from docs/networks/access-onchain-data/_category_.yml rename to docs/protocol/access-onchain-data/_category_.yml diff --git a/docs/networks/access-onchain-data/access-http-api.md b/docs/protocol/access-onchain-data/access-http-api.md similarity index 100% rename from docs/networks/access-onchain-data/access-http-api.md rename to docs/protocol/access-onchain-data/access-http-api.md diff --git a/docs/networks/access-onchain-data/index.md b/docs/protocol/access-onchain-data/index.md similarity index 89% rename from docs/networks/access-onchain-data/index.md rename to docs/protocol/access-onchain-data/index.md index 69044949bd..1341d684a1 100644 --- a/docs/networks/access-onchain-data/index.md +++ b/docs/protocol/access-onchain-data/index.md @@ -311,9 +311,11 @@ message SendTransactionResponse { `GetTransaction` gets a [transaction](#transaction) by ID. +Any type of transaction - user submitted, scheduled transaction or a system transaction can be queried. + If the transaction is not found in the access node cache, the request is forwarded to a collection node. -_Currently, only transactions within the current epoch can be queried._ +_Currently, only transactions within the current network upgrade can be queried._ ```proto rpc GetTransaction (GetTransactionRequest) returns (TransactionResponse) @@ -347,6 +349,8 @@ message TransactionResponse { `GetTransactionsByBlockID` gets all the [transactions](#transaction) for a specified block. +The response includes user transactions, scheduled transactions, and system transactions. + ```proto rpc GetTransactionsByBlockID(GetTransactionsByBlockIDRequest) returns (TransactionsResponse); ``` @@ -373,6 +377,8 @@ message TransactionsResponse { `GetTransactionResult` gets the execution result of a transaction. +Any type of transaction - user submitted, scheduled transaction or a system transaction can be queried. + ```proto rpc GetTransactionResult (GetTransactionRequest) returns (TransactionResultResponse) ``` @@ -404,10 +410,13 @@ message TransactionResultResponse { uint64 computation_usage = 10; } ``` + ### GetTransactionResultByIndex `GetTransactionResultByIndex` gets a transaction's result at a specified block and index. +Any type of transaction - user submitted, scheduled transaction or a system transaction can be queried. + ```proto rpc GetTransactionResultByIndex(GetTransactionByIndexRequest) returns (TransactionResultResponse); ``` @@ -443,6 +452,8 @@ message TransactionResultResponse { `GetTransactionResultsByBlockID` gets all the transaction results for a specified block. +The response includes results for user transactions, scheduled transactions, and system transactions. + ```proto rpc GetTransactionResultsByBlockID(GetTransactionsByBlockIDRequest) returns (TransactionResultsResponse); ``` @@ -465,10 +476,66 @@ message TransactionResultsResponse { } ``` +### GetScheduledTransaction + +`GetScheduledTransaction` gets the scheduled transaction body for a given scheduled transaction ID. + +```proto +rpc GetScheduledTransaction(GetScheduledTransactionRequest) returns (TransactionResponse); +``` + +#### Request + +```proto +message GetScheduledTransactionRequest { + uint64 id = 1; + entities.ExecutionStateQuery execution_state_query = 2; +} +``` + +#### Response + +```proto +message TransactionResponse { + entities.Transaction transaction = 1; + entities.Metadata metadata = 2; +} +``` + +### GetScheduledTransactionResult + +GetScheduledTransactionResult gets a scheduled transaction result for a given scheduled transaction ID + +```proto +rpc GetScheduledTransactionResult(GetScheduledTransactionResultRequest) +returns (TransactionResultResponse); +``` + +#### Request + +```proto +message GetScheduledTransactionResultRequest { + uint64 id = 1; + entities.EventEncodingVersion event_encoding_version = 2; + entities.ExecutionStateQuery execution_state_query = 3; +} +``` + +#### Response + +```proto +message TransactionResponse { + entities.Transaction transaction = 1; + entities.Metadata metadata = 2; +} +``` + ### GetSystemTransaction `GetSystemTransaction` gets the system transaction for a block. +_Scheduled Transactions will not be included in the response_ + ```proto rpc GetSystemTransaction(GetSystemTransactionRequest) returns (TransactionResponse); ``` @@ -494,6 +561,8 @@ message TransactionResponse { `GetSystemTransactionResult` gets the system transaction result for a block. +_Scheduled Transactions will not be included in the response_ + ```proto rpc GetSystemTransactionResult(GetSystemTransactionResultRequest) returns (TransactionResultResponse); ``` @@ -876,7 +945,7 @@ message ExecuteScriptResponse { ## Events -The following methods can be used to query for on-chain [events](#event). +The following methods can be used to query for onchain [events](#event). ### GetEventsForHeightRange @@ -1048,7 +1117,7 @@ message ProtocolStateSnapshotResponse { ### GetProtocolStateSnapshotByBlockID -`GetProtocolStateSnapshotByBlockID` retrieves the latest sealed protocol state snapshot by block ID. +`GetProtocolStateSnapshotByBlockID` retrieves the latest sealed protocol state snapshot by block ID. Used by Flow nodes joining the network to bootstrap a space-efficient local state. ```proto @@ -1074,7 +1143,7 @@ message ProtocolStateSnapshotResponse { ### GetProtocolStateSnapshotByHeight -`GetProtocolStateSnapshotByHeight` retrieves the latest sealed protocol state snapshot by block height. +`GetProtocolStateSnapshotByHeight` retrieves the latest sealed protocol state snapshot by block height. Used by Flow nodes joining the network to bootstrap a space-efficient local state. ```proto @@ -1156,7 +1225,6 @@ message ExecutionResultByIDResponse { } ``` - ## Entities Below are in-depth descriptions of each of the data entities returned or accepted by the Access API. @@ -1179,21 +1247,21 @@ message Block { } ``` -| Field | Description | -|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| id | SHA3-256 hash of the entire block payload | -| height | Height of the block in the chain | -| parent_id | ID of the previous block in the chain | -| timestamp | Timestamp of when the proposer claims it constructed the block.
**NOTE**: It is included by the proposer, there are no guarantees on how much the time stamp can deviate from the true time the block was published.
Consider observing blocks' status changes yourself to get a more reliable value | -| collection_guarantees | List of [collection guarantees](#collection-guarantee) | -| block_seals | List of [block seals](#block-seal) | -| signatures | BLS signatures of consensus nodes | -| execution_receipt_metaList | List of [execution-receipt-meta](#execution-receipt-meta) | -| execution_result_list | List of [execution results](#execution-result) | -| block_header | A summary of a [block](#block-header) | -| protocol_state_id | The root hash of protocol state. | +| Field | Description | +| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| id | SHA3-256 hash of the entire block payload | +| height | Height of the block in the chain | +| parent_id | ID of the previous block in the chain | +| timestamp | Timestamp of when the proposer claims it constructed the block.
**NOTE**: It is included by the proposer, there are no guarantees on how much the time stamp can deviate from the true time the block was published.
Consider observing blocks' status changes yourself to get a more reliable value | +| collection_guarantees | List of [collection guarantees](#collection-guarantee) | +| block_seals | List of [block seals](#block-seal) | +| signatures | BLS signatures of consensus nodes | +| execution_receipt_metaList | List of [execution-receipt-meta](#execution-receipt-meta) | +| execution_result_list | List of [execution results](#execution-result) | +| block_header | A summary of a [block](#block-header) | +| protocol_state_id | The root hash of protocol state. | -The detailed semantics of block formation are covered in the [block formation guide](../../build/basics/blocks.md). +The detailed semantics of block formation are covered in the [block formation guide](../../build/cadence/basics/blocks.md). ### Block Header @@ -1219,7 +1287,7 @@ message BlockHeader { ``` | Field | Description | -|-----------------------|-------------------------------------------------------------------------------------------------------------------| +| --------------------- | ----------------------------------------------------------------------------------------------------------------- | | id | SHA3-256 hash of the entire block payload | | parent_id | ID of the previous block in the chain | | height | Height of the block in the chain | @@ -1263,11 +1331,11 @@ enum BlockStatus { } ``` -| Value | Description | -|------------|------------------------------------------------| -| UNKNOWN | The block status is not known | -| FINALIZED | The consensus nodes have finalized the block | -| SEALED | The verification nodes have verified the block | +| Value | Description | +| --------- | ---------------------------------------------- | +| UNKNOWN | The block status is not known | +| FINALIZED | The consensus nodes have finalized the block | +| SEALED | The verification nodes have verified the block | ### Collection @@ -1280,10 +1348,10 @@ message Collection { } ``` -| Field | Description | -|------------------|---------------------------------------------------| -| id | SHA3-256 hash of the collection contents | -| transaction_ids | Ordered list of transaction IDs in the collection | +| Field | Description | +| --------------- | ------------------------------------------------- | +| id | SHA3-256 hash of the collection contents | +| transaction_ids | Ordered list of transaction IDs in the collection | ### Collection Guarantee @@ -1300,14 +1368,14 @@ message CollectionGuarantee { } ``` -| Field | Description | -|---------------------|--------------------------------------------------------------------| -| collection_id | SHA3-256 hash of the collection contents | -| signatures | BLS signatures of the collection nodes guaranteeing the collection | -| reference_block_id | Defines expiry of the collection | -| signature | Guarantor signatures | -| signer_ids | An array that represents all the signer ids | -| signer_indices | Encoded indices of the signers | +| Field | Description | +| ------------------ | ------------------------------------------------------------------ | +| collection_id | SHA3-256 hash of the collection contents | +| signatures | BLS signatures of the collection nodes guaranteeing the collection | +| reference_block_id | Defines expiry of the collection | +| signature | Guarantor signatures | +| signer_ids | An array that represents all the signer ids | +| signer_indices | Encoded indices of the signers | ### Transaction @@ -1347,19 +1415,19 @@ message TransactionSignature { | [proposal_key](#proposal-key) | Account key used to propose the transaction | | payer | Address of the payer account | | authorizers | Addresses of the transaction authorizers | -| signatures | [Signatures](#transaction-signature) from all signer accounts | +| signatures | [Signatures](#transaction-signature) from all signer accounts | -The detailed semantics of transaction creation, signing and submission are covered in the [transaction submission guide](../../build/basics/transactions.md#signing-a-transaction). +The detailed semantics of transaction creation, signing and submission are covered in the [transaction submission guide](../../build/cadence/basics/transactions.md#signing-a-transaction). #### Proposal Key -The proposal key is used to specify a sequence number for the transaction. Sequence numbers are covered in more detail [here](../../build/basics/transactions.md#sequence-numbers). +The proposal key is used to specify a sequence number for the transaction. Sequence numbers are covered in more detail [here](../../build/cadence/basics/transactions.md#sequence-numbers). -| Field | Description | -| --------------- | ------------------------------------------------------------------------------------------- | -| address | Address of proposer account | -| key_id | ID of proposal key on the proposal account | -| sequence_number | [Sequence number](../../build/basics/transactions.md#sequence-numbers) for the proposal key | +| Field | Description | +| --------------- | --------------------------------------------------------------------------------------------------- | +| address | Address of proposer account | +| key_id | ID of proposal key on the proposal account | +| sequence_number | [Sequence number](../../build/cadence/basics/transactions.md#sequence-numbers) for the proposal key | #### Transaction Signature @@ -1415,7 +1483,7 @@ message Account { The `code` and `contracts` fields contain the raw Cadence source code, encoded as UTF-8 bytes. -More information on accounts can be found [here](../../build/basics/accounts.md). +More information on accounts can be found [here](../../build/cadence/basics/accounts.md). #### Account Key @@ -1433,17 +1501,17 @@ message AccountKey { } ``` -| Field | Description | -| --------------- |---------------------------------------------------------------------------| -| id | Index of the key within the account, used as a unique identifier | -| public_key | Public key encoded as bytes | -| sign_algo | [Signature algorithm](../../build/basics/accounts.md#signature-and-hash-algorithms) | -| hash_algo | [Hash algorithm](../../build/basics/accounts.md#signature-and-hash-algorithms) | -| weight | [Weight assigned to the key](../../build/basics/accounts.md#account-keys) | -| sequence_number | [Sequence number for the key](../../build/basics/transactions.md#sequence-numbers) | -| revoked | Flag indicating whether or not the key has been revoked | +| Field | Description | +| --------------- | ------------------------------------------------------------------------------------------- | +| id | Index of the key within the account, used as a unique identifier | +| public_key | Public key encoded as bytes | +| sign_algo | [Signature algorithm](../../build/cadence/basics/accounts.md#signature-and-hash-algorithms) | +| hash_algo | [Hash algorithm](../../build/cadence/basics/accounts.md#signature-and-hash-algorithms) | +| weight | [Weight assigned to the key](../../build/cadence/basics/accounts.md#account-keys) | +| sequence_number | [Sequence number for the key](../../build/cadence/basics/transactions.md#sequence-numbers) | +| revoked | Flag indicating whether or not the key has been revoked | -More information on account keys, key weights and sequence numbers can be found [here](../../build/basics/accounts.md). +More information on account keys, key weights and sequence numbers can be found [here](../../build/cadence/basics/accounts.md). ### Event @@ -1500,12 +1568,12 @@ message ExecutionReceiptMeta { } ``` -| Field | Description | -|----------------------|--------------------------------------| -| executor_id | Identifier of the executor node | -| result_id | Identifier of block execution result | -| spocks | SPoCK | -| executor_signature | Signature of the executor | +| Field | Description | +| ------------------ | ------------------------------------ | +| executor_id | Identifier of the executor node | +| result_id | Identifier of block execution result | +| spocks | SPoCK | +| executor_signature | Signature of the executor | #### Chunk @@ -1526,18 +1594,18 @@ message Chunk { } ``` -| Field | Description | -|-------------------------|------------------------------------------------------| -| CollectionIndex | Identifier of a collection | -| start_state | State commitment at start of the chunk | -| event_collection | Hash of events emitted by transactions in this chunk | -| block_id | Identifier of a block | -| total_computation_used | Total computation used by transactions in this chunk | -| number_of_transactions | Number of transactions in a chunk | -| index | Index of chunk inside a block (zero-based) | -| end_state | State commitment after executing chunk | -| execution_data_id | Identifier of a execution data | -| state_delta_commitment | A commitment over sorted list of register changes | +| Field | Description | +| ---------------------- | ---------------------------------------------------- | +| CollectionIndex | Identifier of a collection | +| start_state | State commitment at start of the chunk | +| event_collection | Hash of events emitted by transactions in this chunk | +| block_id | Identifier of a block | +| total_computation_used | Total computation used by transactions in this chunk | +| number_of_transactions | Number of transactions in a chunk | +| index | Index of chunk inside a block (zero-based) | +| end_state | State commitment after executing chunk | +| execution_data_id | Identifier of a execution data | +| state_delta_commitment | A commitment over sorted list of register changes | #### Service Event @@ -1660,7 +1728,6 @@ message EventFilter { | contract | A list of contracts who's events should be included. Contracts have the following name formats:
_ Protocol events: `flow`
_ Smart contract events: `A.[contract address].[contract name]`
This filter matches on the full contract including its address, not just the contract's name | | address | A list of addresses who's events should be included. Addresses must be Flow account addresses in hex format and valid for the network the node is connected to. i.e. only a mainnet address is valid for a mainnet node. Addresses may optionally include the `0x` prefix | - ## Execution data streaming API ### Execution Data API @@ -1669,10 +1736,8 @@ The `ExecutionDataAPI` provides access to block execution data over gRPC, includ [execution data protobuf file](https://github.com/onflow/flow/blob/master/protobuf/flow/executiondata/executiondata.proto) - > The API is disabled by default. To enable it, specify a listener address with the cli flag `--state-stream-addr`. - diff --git a/docs/networks/access-onchain-data/websockets-stream-api/_category_.yml b/docs/protocol/access-onchain-data/websockets-stream-api/_category_.yml similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/_category_.yml rename to docs/protocol/access-onchain-data/websockets-stream-api/_category_.yml diff --git a/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_1.png b/docs/protocol/access-onchain-data/websockets-stream-api/assets/pe_1.png similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/assets/pe_1.png rename to docs/protocol/access-onchain-data/websockets-stream-api/assets/pe_1.png diff --git a/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_2.png b/docs/protocol/access-onchain-data/websockets-stream-api/assets/pe_2.png similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/assets/pe_2.png rename to docs/protocol/access-onchain-data/websockets-stream-api/assets/pe_2.png diff --git a/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_3.png b/docs/protocol/access-onchain-data/websockets-stream-api/assets/pe_3.png similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/assets/pe_3.png rename to docs/protocol/access-onchain-data/websockets-stream-api/assets/pe_3.png diff --git a/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_4.png b/docs/protocol/access-onchain-data/websockets-stream-api/assets/pe_4.png similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/assets/pe_4.png rename to docs/protocol/access-onchain-data/websockets-stream-api/assets/pe_4.png diff --git a/docs/networks/access-onchain-data/websockets-stream-api/common-errors.md b/docs/protocol/access-onchain-data/websockets-stream-api/common-errors.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/common-errors.md rename to docs/protocol/access-onchain-data/websockets-stream-api/common-errors.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/index.md b/docs/protocol/access-onchain-data/websockets-stream-api/index.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/index.md rename to docs/protocol/access-onchain-data/websockets-stream-api/index.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/list-subscriptions-message.md b/docs/protocol/access-onchain-data/websockets-stream-api/list-subscriptions-message.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/list-subscriptions-message.md rename to docs/protocol/access-onchain-data/websockets-stream-api/list-subscriptions-message.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/postman-example.md b/docs/protocol/access-onchain-data/websockets-stream-api/postman-example.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/postman-example.md rename to docs/protocol/access-onchain-data/websockets-stream-api/postman-example.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/subscribe-message.md b/docs/protocol/access-onchain-data/websockets-stream-api/subscribe-message.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/subscribe-message.md rename to docs/protocol/access-onchain-data/websockets-stream-api/subscribe-message.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/_category_.yml b/docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/_category_.yml similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/supported-topics/_category_.yml rename to docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/_category_.yml diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/account_statuses_topic.md b/docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/account_statuses_topic.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/supported-topics/account_statuses_topic.md rename to docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/account_statuses_topic.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/block_digests_topic.md b/docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/block_digests_topic.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/supported-topics/block_digests_topic.md rename to docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/block_digests_topic.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/block_headers_topic.md b/docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/block_headers_topic.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/supported-topics/block_headers_topic.md rename to docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/block_headers_topic.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/blocks_topic.md b/docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/blocks_topic.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/supported-topics/blocks_topic.md rename to docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/blocks_topic.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/events_topic.md b/docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/events_topic.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/supported-topics/events_topic.md rename to docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/events_topic.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/index.md b/docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/index.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/supported-topics/index.md rename to docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/index.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/send_and_get_transaction_statuses_topic.md b/docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/send_and_get_transaction_statuses_topic.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/supported-topics/send_and_get_transaction_statuses_topic.md rename to docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/send_and_get_transaction_statuses_topic.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/transaction_statuses_topic.md b/docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/transaction_statuses_topic.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/supported-topics/transaction_statuses_topic.md rename to docs/protocol/access-onchain-data/websockets-stream-api/supported-topics/transaction_statuses_topic.md diff --git a/docs/networks/access-onchain-data/websockets-stream-api/unsubscribe-message.md b/docs/protocol/access-onchain-data/websockets-stream-api/unsubscribe-message.md similarity index 100% rename from docs/networks/access-onchain-data/websockets-stream-api/unsubscribe-message.md rename to docs/protocol/access-onchain-data/websockets-stream-api/unsubscribe-message.md diff --git a/docs/networks/flow-networks/accessing-mainnet.md b/docs/protocol/flow-networks/accessing-mainnet.md similarity index 88% rename from docs/networks/flow-networks/accessing-mainnet.md rename to docs/protocol/flow-networks/accessing-mainnet.md index fabc6b944a..6c39e432ff 100644 --- a/docs/networks/flow-networks/accessing-mainnet.md +++ b/docs/protocol/flow-networks/accessing-mainnet.md @@ -27,7 +27,7 @@ func main() { ## Account Creation -You can follow the [Flow Port account creation steps](../../networks/flow-port/index.md) to create a new mainnet account. +You can follow the [Flow Port account creation steps](../../protocol/flow-port/index.md) to create a new mainnet account. If you prefer watching a video, check out this tutorial: @@ -63,7 +63,7 @@ Take a note of the public key and go back to Flow Port. Open the ["Create a new On the page, enter your public key from the CLI, ensure the hash algorithm is set to `SHA3_256` and the weight is set to `1000`. Finally, check the box confirming correctness and hit 'Submit'. -> **Important**: Your account needs to have at least 0.002 FLOW for the account creation. More details can be found [in this guide](../../build/basics/fees.md#storage). +> **Important**: Your account needs to have at least 0.002 FLOW for the account creation. More details can be found [in this guide](../../build/cadence/basics/fees.md#storage). Once the transaction is sealed, you should scroll down to the events section and locate the `flow.AccountCreated` event with the newly generated address. @@ -73,4 +73,4 @@ Make sure to take a note of the address. If you want to verify the public key fo ## Important Mainnet Smart Contract Addresses -You can review [all available core contracts](../../build/core-contracts/index.md) deployed to the mainnet to identify which ones you want to import. +You can review [all available core contracts](../../build/cadence/core-contracts/index.md) deployed to the mainnet to identify which ones you want to import. diff --git a/docs/networks/flow-networks/accessing-testnet.md b/docs/protocol/flow-networks/accessing-testnet.md similarity index 93% rename from docs/networks/flow-networks/accessing-testnet.md rename to docs/protocol/flow-networks/accessing-testnet.md index c7fcddd34c..9bbb9b4375 100644 --- a/docs/networks/flow-networks/accessing-testnet.md +++ b/docs/protocol/flow-networks/accessing-testnet.md @@ -58,4 +58,4 @@ Accounts and tokens for testing can be obtained through the [testnet faucet](htt ## Important Smart Contract Addresses -You can review [all available core contracts](../../build/core-contracts/index.md) deployed to the Testnet to identify which ones you want to import. +You can review [all available core contracts](../../build/cadence/core-contracts/index.md) deployed to the Testnet to identify which ones you want to import. diff --git a/docs/protocol/flow-networks/index.md b/docs/protocol/flow-networks/index.md new file mode 100644 index 0000000000..9ca8b8241d --- /dev/null +++ b/docs/protocol/flow-networks/index.md @@ -0,0 +1,88 @@ +--- +title: Flow Networks +sidebar_position: 1 +--- + +## About Flow Networks + +Flow supports two virtual machine environments: **Flow Cadence** (native Flow smart contracts) and **Flow EVM** (EVM-equivalent smart contracts). Both environments share the same underlying Flow blockchain infrastructure and use FLOW as the native token for gas fees. + +In addition to Mainnet, developers have access to the Testnet environment, which serves as an essential testing ground for applications and smart contracts prior to their deployment on Mainnet. This ensures that any potential issues can be identified and resolved in a controlled setting, mitigating risks associated with live deployment. + +Furthermore, during network upgrades, Testnet receives updates ahead of Mainnet. This preemptive update process allows developers to comprehensively test their apps against the latest versions of the nodes, enhancements to the Cadence programming language, and core contract upgrades. This strategy guarantees that when these updates are eventually applied to Mainnet, applications and smart contracts will operate seamlessly, enhancing overall network stability and user experience. + +## Flow Cadence Networks + +Flow Cadence networks provide access to the native Flow blockchain using the Cadence programming language. Access Nodes are the node type that are most useful for developers, as they provide access to the Flow network via the following API endpoints. + +### Flow Cadence Network Endpoints + +| Network | GRPC | Web GRPC | REST | +| ------- | -------------------------------------- | -------------------- | ------------------------- | +| Mainnet | `access.mainnet.nodes.onflow.org:9000` | `mainnet.onflow.org` | `rest-mainnet.onflow.org` | +| Testnet | `access.devnet.nodes.onflow.org:9000` | `testnet.onflow.org` | `rest-testnet.onflow.org` | + +For more information on how to access these networks, refer to the following guides: + +- [Flow Testnet](./accessing-testnet.md) +- [Flow Mainnet](./accessing-mainnet.md) + +### Flow Access API + +There are two primary ways to access onchain data within the Flow network: Access Nodes and Light nodes. Access Nodes are the node type that are most useful for developers, as they provide access to the Flow network via the following API endpoints: + +- [Flow Access API](../access-onchain-data/index.md) + - [Mainnet](./accessing-mainnet.md): `access.mainnet.nodes.onflow.org:9000` + - [Testnet](./accessing-testnet.md): `access.devnet.nodes.onflow.org:9000` +- [Status Page](https://status.onflow.org/) - Network status page + +## Flow EVM Networks + +Flow EVM is an EVM-equivalent blockchain that combines the advantages of Flow, including security, low-cost gas, and native VRF with compatibility with existing blockchain applications tools and contracts. Flow EVM uses the standard Ethereum JSON-RPC API. + +### Flow EVM Network Endpoints + +#### Mainnet + +| Name | Value | +| --------------- | ------------------------------------ | +| Network Name | Flow EVM Mainnet | +| Description | The public RPC URL for Flow Mainnet | +| RPC Endpoint | https://mainnet.evm.nodes.onflow.org | +| Chain ID | 747 | +| Currency Symbol | FLOW | +| Block Explorer | https://evm.flowscan.io | + +#### Testnet + +| Name | Value | +| --------------- | ------------------------------------ | +| Network Name | Flow EVM Testnet | +| Description | The public RPC URL for Flow Testnet | +| RPC Endpoint | https://testnet.evm.nodes.onflow.org | +| Chain ID | 545 | +| Currency Symbol | FLOW | +| Block Explorer | https://evm-testnet.flowscan.io | + +### EVM Specification + +- Flow EVM is a virtual EVM-based blockchain using the latest EVM byte-code interpreter +- Utilizes `FLOW` token for transactions +- The [EVM Gateway](https://github.com/onflow/flow-evm-gateway) exposes the standard EVM API (Ethereum JSON-RPC) +- Read more about the implementation in [FLIP 223: EVM integration interface](https://github.com/onflow/flips/blob/main/protocol/20231116-evm-support.md) + +For detailed information about supported JSON-RPC methods, see the [Flow EVM Network Information](../../build/evm/networks.md) page. + +## Rate limits + +Rate limits for Flow Public Access nodes hosted by QuickNode are detailed [here](https://www.quicknode.com/docs/flow#endpoint-rate-limits). + +## Running Your Own Node + +If you're getting started, you don't need to run your own node and you can use the above public nodes. The public access nodes are rate-limited, so as your product matures you might want to run your own node. There are multiple options available: + +- Start with a [Light (Observer) Node](../node-ops/light-nodes/observer-node.md). +- For Flow EVM applications, you can run your own [EVM Gateway](../node-ops/evm-gateway/evm-gateway-setup.md) to provide a dedicated private RPC endpoint, remove rate limits, and optionally sponsor gas fees for your users. +- You can also use a third-party provider like [Quicknode](https://www.quicknode.com/docs/flow). + +Check out [Running a Node](../node-ops/light-nodes/observer-node.md) for more information. diff --git a/docs/networks/flow-networks/port-sealed-tx.png b/docs/protocol/flow-networks/port-sealed-tx.png similarity index 100% rename from docs/networks/flow-networks/port-sealed-tx.png rename to docs/protocol/flow-networks/port-sealed-tx.png diff --git a/docs/networks/flow-port/index.md b/docs/protocol/flow-port/index.md similarity index 95% rename from docs/networks/flow-port/index.md rename to docs/protocol/flow-port/index.md index 795f66ca53..9cda05789c 100644 --- a/docs/networks/flow-port/index.md +++ b/docs/protocol/flow-port/index.md @@ -75,7 +75,7 @@ If you are using a custody provider who controls your account and private keys f ### Starting a Manual Staking Transaction -1. You need to have FLOW in order to stake. Please see the [FLOW Token](../../build//core-contracts//03-flow-token.md) reference for information on how to become a FLOW holder. +1. You need to have FLOW in order to stake. Please see the [FLOW Token](../../build/cadence//core-contracts//03-flow-token.md) reference for information on how to become a FLOW holder. 2. Once you have FLOW tokens in your account, you can start staking through [Flow Port](https://port.flow.com/) or, if applicable, with your [custody provider](#staking-via-a-custody-provider). @@ -83,7 +83,7 @@ If you are using a custody provider who controls your account and private keys f ### Manual Staking/Delegating -If you are not using a custody provider, there is more responsibility that you have to accept, because you have complete control of your tokens. You need to ensure that you are well informed about the staking process and potentially node operation process because you will have to manage those on your own. Please read the [staking documentation](../../networks/staking/index.md) before continuing with this guide. +If you are not using a custody provider, there is more responsibility that you have to accept, because you have complete control of your tokens. You need to ensure that you are well informed about the staking process and potentially node operation process because you will have to manage those on your own. Please read the [staking documentation](../../protocol/staking/index.md) before continuing with this guide. Below are the various options you can choose. Please be aware, that at this time you can only have 1 stake or 1 delegate per account. This means that if you want to do multiple stakes, multiple delegates, or a mixture of stakes and delegates, you will need to create multiple accounts to do so. Please read them carefully as it will help you understand which route is best for your situation: @@ -98,9 +98,9 @@ Please see a list [here](https://github.com/onflow/flow/blob/master/nodeoperator 2. Next, select the type of node you will be running. -3. Input the amount of Flow you wish to stake with that node. You must stake at least the minimum in order for your stake request to be successfully processed. You are able to provide the minimum stake across multiple transactions. Meaning, you could execute your stake transaction with half of the minumum required. Then, before the next epoch, you can choose to 'Add Flow' to that pending stake to get it to the minimum stake required. +3. Input the amount of Flow you wish to stake with that node. You must stake at least the minimum in order for your stake request to be successfully processed. You are able to provide the minimum stake across multiple transactions. Meaning, you could execute your stake transaction with half of the minimum required. Then, before the next epoch, you can choose to 'Add Flow' to that pending stake to get it to the minimum stake required. -4. Run the [bootstrapping instructions](../../networks/node-ops/node-operation/node-bootstrap.md) and provide the remaining technical details needed to stake a node. +4. Run the [bootstrapping instructions](../../protocol/node-ops/node-operation/node-bootstrap.md) and provide the remaining technical details needed to stake a node. ### Delegating @@ -114,14 +114,14 @@ Please see a list [here](https://github.com/onflow/flow/blob/master/nodeoperator ## I Have Successfully Executed a Stake Transaction, Now What? -- Now that you have executed a stake transaction in either Flow Port or your custody provider’s portal, that transaction will sit in a pending status until it is processed, which will be at the next [Epoch](../../networks/staking/index.md#epochs) Date (which is currently weekly). -- During the next [Epoch](../../networks/staking/index.md#epochs), the transaction will be processed. If successful, the provided FLOW will be staked and the associated Node would be either **a)** included in the network protocol if it is a new node or **b)** continue to operate as is in the network protocol. +- Now that you have executed a stake transaction in either Flow Port or your custody provider’s portal, that transaction will sit in a pending status until it is processed, which will be at the next [Epoch](../../protocol/staking/index.md#epochs) Date (which is currently weekly). +- During the next [Epoch](../../protocol/staking/index.md#epochs), the transaction will be processed. If successful, the provided FLOW will be staked and the associated Node would be either **a)** included in the network protocol if it is a new node or **b)** continue to operate as is in the network protocol. - You are now a part of Flow, and will begin to earn rewards for being a valued member of the network! ## What Else Can I Do? - Add additional stake to your existing stake. Any added FLOW will again sit in a pending status and be processed at the next epoch. -- Withdraw/re-stake your earned rewards. If you decide to withdraw your rewards, this action will happen instantly. If you decide to re-stake your rewards, the request will again sit in a pending status and will be processed at the next [Epoch](../../networks/staking/index.md#epochs). +- Withdraw/re-stake your earned rewards. If you decide to withdraw your rewards, this action will happen instantly. If you decide to re-stake your rewards, the request will again sit in a pending status and will be processed at the next [Epoch](../../protocol/staking/index.md#epochs). - Withdraw Rewards and send your earnings to other accounts. If you decide that you want to withdraw your rewards and send those earnings to other accounts via the 'Send FLOW' function, you should first withdraw your rewards. Once in your account, you can send these funds to any other account via the 'Send FLOW' option. - Request to be unstaked from the network. The unstake request will sit in a pending status for two epochs. Once it is processed, the amount that has been unstaked will sit in your unstaked FLOW amount and can now be withdrawn or re-staked. - Change the node you are staked/delegated to. If your staked/delegated node has no FLOW actively staked and you have completely withdrawn all unstaked amounts and rewards associated with the node, then you can move your stake to a different node. Click on the `Change Node` button to initiate this process. Please note that this feature is only visible once you get your active stake/delegate into the appropriate status. diff --git a/docs/networks/flow-port/machine-account.png b/docs/protocol/flow-port/machine-account.png similarity index 100% rename from docs/networks/flow-port/machine-account.png rename to docs/protocol/flow-port/machine-account.png diff --git a/docs/networks/flow-port/port-delegate-1.png b/docs/protocol/flow-port/port-delegate-1.png similarity index 100% rename from docs/networks/flow-port/port-delegate-1.png rename to docs/protocol/flow-port/port-delegate-1.png diff --git a/docs/networks/flow-port/port-delegate-2.png b/docs/protocol/flow-port/port-delegate-2.png similarity index 100% rename from docs/networks/flow-port/port-delegate-2.png rename to docs/protocol/flow-port/port-delegate-2.png diff --git a/docs/networks/flow-port/port-delegate-3.png b/docs/protocol/flow-port/port-delegate-3.png similarity index 100% rename from docs/networks/flow-port/port-delegate-3.png rename to docs/protocol/flow-port/port-delegate-3.png diff --git a/docs/networks/flow-port/port-delegate-4.png b/docs/protocol/flow-port/port-delegate-4.png similarity index 100% rename from docs/networks/flow-port/port-delegate-4.png rename to docs/protocol/flow-port/port-delegate-4.png diff --git a/docs/networks/flow-port/port-stake-0-00.png b/docs/protocol/flow-port/port-stake-0-00.png similarity index 100% rename from docs/networks/flow-port/port-stake-0-00.png rename to docs/protocol/flow-port/port-stake-0-00.png diff --git a/docs/networks/flow-port/port-stake-0-01.png b/docs/protocol/flow-port/port-stake-0-01.png similarity index 100% rename from docs/networks/flow-port/port-stake-0-01.png rename to docs/protocol/flow-port/port-stake-0-01.png diff --git a/docs/networks/flow-port/port-stake-0-02.png b/docs/protocol/flow-port/port-stake-0-02.png similarity index 100% rename from docs/networks/flow-port/port-stake-0-02.png rename to docs/protocol/flow-port/port-stake-0-02.png diff --git a/docs/networks/flow-port/port-stake-0-03.png b/docs/protocol/flow-port/port-stake-0-03.png similarity index 100% rename from docs/networks/flow-port/port-stake-0-03.png rename to docs/protocol/flow-port/port-stake-0-03.png diff --git a/docs/networks/flow-port/port-stake-0-04.png b/docs/protocol/flow-port/port-stake-0-04.png similarity index 100% rename from docs/networks/flow-port/port-stake-0-04.png rename to docs/protocol/flow-port/port-stake-0-04.png diff --git a/docs/networks/flow-port/port-stake-0-05.png b/docs/protocol/flow-port/port-stake-0-05.png similarity index 100% rename from docs/networks/flow-port/port-stake-0-05.png rename to docs/protocol/flow-port/port-stake-0-05.png diff --git a/docs/networks/flow-port/port-stake-0-06.png b/docs/protocol/flow-port/port-stake-0-06.png similarity index 100% rename from docs/networks/flow-port/port-stake-0-06.png rename to docs/protocol/flow-port/port-stake-0-06.png diff --git a/docs/networks/flow-port/port-stake-1.png b/docs/protocol/flow-port/port-stake-1.png similarity index 100% rename from docs/networks/flow-port/port-stake-1.png rename to docs/protocol/flow-port/port-stake-1.png diff --git a/docs/networks/flow-port/port-stake-2.png b/docs/protocol/flow-port/port-stake-2.png similarity index 100% rename from docs/networks/flow-port/port-stake-2.png rename to docs/protocol/flow-port/port-stake-2.png diff --git a/docs/networks/flow-port/port-stake-3.png b/docs/protocol/flow-port/port-stake-3.png similarity index 100% rename from docs/networks/flow-port/port-stake-3.png rename to docs/protocol/flow-port/port-stake-3.png diff --git a/docs/networks/flow-port/port-stake-4.png b/docs/protocol/flow-port/port-stake-4.png similarity index 100% rename from docs/networks/flow-port/port-stake-4.png rename to docs/protocol/flow-port/port-stake-4.png diff --git a/docs/networks/flow-port/port-stake-5.png b/docs/protocol/flow-port/port-stake-5.png similarity index 100% rename from docs/networks/flow-port/port-stake-5.png rename to docs/protocol/flow-port/port-stake-5.png diff --git a/docs/networks/flow-port/port-stake-6.png b/docs/protocol/flow-port/port-stake-6.png similarity index 100% rename from docs/networks/flow-port/port-stake-6.png rename to docs/protocol/flow-port/port-stake-6.png diff --git a/docs/networks/flow-port/staking-collection.png b/docs/protocol/flow-port/staking-collection.png similarity index 100% rename from docs/networks/flow-port/staking-collection.png rename to docs/protocol/flow-port/staking-collection.png diff --git a/docs/networks/flow-port/staking-guide.md b/docs/protocol/flow-port/staking-guide.md similarity index 96% rename from docs/networks/flow-port/staking-guide.md rename to docs/protocol/flow-port/staking-guide.md index 9097837d44..2d132622f0 100644 --- a/docs/networks/flow-port/staking-guide.md +++ b/docs/protocol/flow-port/staking-guide.md @@ -4,7 +4,7 @@ title: Flow Port Staking Guide This guide provides step-by-step instructions for using the Flow Port to stake your FLOW tokens and start earning rewards. Currently, Flow Port only supports staking or delegating using tokens held in Blocto or Ledger wallets. -If you're new to the concepts of staking and delegating you can [read this guide](../../networks/staking/index.md) to learn more. +If you're new to the concepts of staking and delegating you can [read this guide](../../protocol/staking/index.md) to learn more. ## First Step @@ -32,7 +32,7 @@ You'll also need the following information about your node: - Staking Key - Machine Account Public Key (for collection/consensus nodes only) -If you don't have this information, go [here](../../networks/node-ops/node-operation/node-bootstrap.md#step-1---run-genesis-bootstrap) for instructions on how to acquire it. +If you don't have this information, go [here](../../protocol/node-ops/node-operation/node-bootstrap.md#step-1---run-genesis-bootstrap) for instructions on how to acquire it. ### Begin Staking @@ -46,7 +46,7 @@ but you may stake as much as you like beyond that. Here's the screen you should ![Flow Port Staking](port-stake-0-03.png) Clicking next will take you to the final screen, where you'll need to enter information about your node you previously obtained. -If you don't have this information, go [here](../../networks/node-ops/node-operation/node-bootstrap.md#step-1---run-genesis-bootstrap) for instructions on how to acquire it. +If you don't have this information, go [here](../../protocol/node-ops/node-operation/node-bootstrap.md#step-1---run-genesis-bootstrap) for instructions on how to acquire it. Here's the screen you should see: ![Flow Port Staking](port-stake-0-04.png) diff --git a/docs/networks/governance.md b/docs/protocol/governance.md similarity index 100% rename from docs/networks/governance.md rename to docs/protocol/governance.md diff --git a/docs/networks/index.md b/docs/protocol/index.md similarity index 100% rename from docs/networks/index.md rename to docs/protocol/index.md diff --git a/docs/networks/network-architecture/images/access.png b/docs/protocol/network-architecture/images/access.png similarity index 100% rename from docs/networks/network-architecture/images/access.png rename to docs/protocol/network-architecture/images/access.png diff --git a/docs/networks/network-architecture/images/banner.png b/docs/protocol/network-architecture/images/banner.png similarity index 100% rename from docs/networks/network-architecture/images/banner.png rename to docs/protocol/network-architecture/images/banner.png diff --git a/docs/networks/network-architecture/images/collection.png b/docs/protocol/network-architecture/images/collection.png similarity index 100% rename from docs/networks/network-architecture/images/collection.png rename to docs/protocol/network-architecture/images/collection.png diff --git a/docs/networks/network-architecture/images/consensus.png b/docs/protocol/network-architecture/images/consensus.png similarity index 100% rename from docs/networks/network-architecture/images/consensus.png rename to docs/protocol/network-architecture/images/consensus.png diff --git a/docs/networks/network-architecture/images/execution.png b/docs/protocol/network-architecture/images/execution.png similarity index 100% rename from docs/networks/network-architecture/images/execution.png rename to docs/protocol/network-architecture/images/execution.png diff --git a/docs/networks/network-architecture/images/flow_node_types_1.gif b/docs/protocol/network-architecture/images/flow_node_types_1.gif similarity index 100% rename from docs/networks/network-architecture/images/flow_node_types_1.gif rename to docs/protocol/network-architecture/images/flow_node_types_1.gif diff --git a/docs/networks/network-architecture/images/flow_trillema_solved.png b/docs/protocol/network-architecture/images/flow_trillema_solved.png similarity index 100% rename from docs/networks/network-architecture/images/flow_trillema_solved.png rename to docs/protocol/network-architecture/images/flow_trillema_solved.png diff --git a/docs/networks/network-architecture/images/mev_attack.png b/docs/protocol/network-architecture/images/mev_attack.png similarity index 100% rename from docs/networks/network-architecture/images/mev_attack.png rename to docs/protocol/network-architecture/images/mev_attack.png diff --git a/docs/networks/network-architecture/images/mev_protection_in_flow.png b/docs/protocol/network-architecture/images/mev_protection_in_flow.png similarity index 100% rename from docs/networks/network-architecture/images/mev_protection_in_flow.png rename to docs/protocol/network-architecture/images/mev_protection_in_flow.png diff --git a/docs/networks/network-architecture/images/pipeline.png b/docs/protocol/network-architecture/images/pipeline.png similarity index 100% rename from docs/networks/network-architecture/images/pipeline.png rename to docs/protocol/network-architecture/images/pipeline.png diff --git a/docs/networks/network-architecture/images/scaling_flow.png b/docs/protocol/network-architecture/images/scaling_flow.png similarity index 100% rename from docs/networks/network-architecture/images/scaling_flow.png rename to docs/protocol/network-architecture/images/scaling_flow.png diff --git a/docs/networks/network-architecture/images/trilemma.png b/docs/protocol/network-architecture/images/trilemma.png similarity index 100% rename from docs/networks/network-architecture/images/trilemma.png rename to docs/protocol/network-architecture/images/trilemma.png diff --git a/docs/networks/network-architecture/images/varying_redudancy.png b/docs/protocol/network-architecture/images/varying_redudancy.png similarity index 100% rename from docs/networks/network-architecture/images/varying_redudancy.png rename to docs/protocol/network-architecture/images/varying_redudancy.png diff --git a/docs/networks/network-architecture/images/verification.png b/docs/protocol/network-architecture/images/verification.png similarity index 100% rename from docs/networks/network-architecture/images/verification.png rename to docs/protocol/network-architecture/images/verification.png diff --git a/docs/networks/network-architecture/index.md b/docs/protocol/network-architecture/index.md similarity index 93% rename from docs/networks/network-architecture/index.md rename to docs/protocol/network-architecture/index.md index b2c8a16c43..e5a6b4c0f6 100644 --- a/docs/networks/network-architecture/index.md +++ b/docs/protocol/network-architecture/index.md @@ -16,7 +16,7 @@ Flow ships what roll-ups only promise: **a full modular feature-set on a single - **Decentralized sequencing** via Consensus + Collector roles - no central bottleneck and [MEV-resistance] - **Native data availability** - Flow architecture ensures all necessary state data is available within the protocol, allowing nodes to verify state without relying on an external data availability layer - **Execution / verification split** for lightweight validators, yet one global state for atomic composability -- **Protocol-level [account abstraction]:** multi-key wallets, gas sponsorship, scoped capabilities +- **Protocol-level [account abstraction]:** multi-key wallets, compute unit (gas) sponsorship, scoped capabilities - **Dual runtimes:** [EVM equivalence] alongside Cadence, so Solidity and resource-oriented contracts live side-by-side To appreciate architecture of Flow, it's important to first understand the core challenges in building performant blockchains - and then explore how the Flow **multi-role architecture** addresses them directly. @@ -42,7 +42,7 @@ Even in large, decentralized networks, MEV can be exploited by colluding actors, ### 3. Energy Inefficiency and Unsustainable Growth -Proof-of-Work chains like Bitcoin are **energy-intensive** and require constant hardware upgrades to stay viable. While Proof-of-Stake reduces the carbon footprint, it still scales poorly. As usage grows, so does the **on-chain state and throughput demand**, requiring validators to **vertically scale** their hardware-leading to greater **centralization pressure** and higher energy consumption. +Proof-of-Work chains like Bitcoin are **energy-intensive** and require constant hardware upgrades to stay viable. While Proof-of-Stake reduces the carbon footprint, it still scales poorly. As usage grows, so does the **onchain state and throughput demand**, requiring validators to **vertically scale** their hardware-leading to greater **centralization pressure** and higher energy consumption. ## Rethinking Blockchain Design @@ -86,8 +86,8 @@ Every transaction is still validated by the network - but **each node only handl In the next section, lets look at how Flow multi-role architecture solves those three big problems with blockchains. -[MEV-resistant]: ../../build/basics/mev-resistance.md +[MEV-resistant]: ../../build/cadence/basics/mev-resistance.md [user safety]: ./user-safety.md -[MEV-resistance]: ../../build/basics/mev-resistance.md -[account abstraction]: ../../build/basics/accounts.md -[EVM equivalence]: ../../evm/about.md +[MEV-resistance]: ../../build/cadence/basics/mev-resistance.md +[account abstraction]: ../../build/cadence/basics/accounts.md +[EVM equivalence]: ../../build/evm/quickstart.md diff --git a/docs/networks/network-architecture/solving-blockchain-trilemma.md b/docs/protocol/network-architecture/solving-blockchain-trilemma.md similarity index 79% rename from docs/networks/network-architecture/solving-blockchain-trilemma.md rename to docs/protocol/network-architecture/solving-blockchain-trilemma.md index 43269e5872..129cadde36 100644 --- a/docs/networks/network-architecture/solving-blockchain-trilemma.md +++ b/docs/protocol/network-architecture/solving-blockchain-trilemma.md @@ -6,7 +6,7 @@ sidebar_position: 2 # Solving the blockchain trilemma -In a monolithic architecture, all nodes perform every task. As network usage grows, the transaction processing capacity of the individual nodes becomes a limiting factor, restricting the network’s throughput and latency. The amount of data that can be stored on-chain is limited since nodes have a finite storage capacity. The only way to scale monolithic blockchains is by increasing the capacity of each node by adding more CPU, memory, and storage (i.e. vertical scaling, an approach taken by Solana). However, this solution comes at the cost of decentralization. As nodes scale vertically, they become more expensive to run, and eventually, only a few operators can afford to run such high-performance, high-capacity nodes. Worse, energy consumption for every node in the network increases over time, making the chain environmentally unsustainable. +In a monolithic architecture, all nodes perform every task. As network usage grows, the transaction processing capacity of the individual nodes becomes a limiting factor, restricting the network’s throughput and latency. The amount of data that can be stored onchain is limited since nodes have a finite storage capacity. The only way to scale monolithic blockchains is by increasing the capacity of each node by adding more CPU, memory, and storage (i.e. vertical scaling, an approach taken by Solana). However, this solution comes at the cost of decentralization. As nodes scale vertically, they become more expensive to run, and eventually, only a few operators can afford to run such high-performance, high-capacity nodes. Worse, energy consumption for every node in the network increases over time, making the chain environmentally unsustainable. Through its multi-role architecture, Flow implements a modular pipeline for processing transactions. This design allows the network to scale by tuning the level of decentralization at each specific step without sharding the state and fragmenting the network into smaller security zones. @@ -14,20 +14,20 @@ The modular pipeline is composed of Collection, Consensus, Execution and Verific ![pipeline](images/pipeline.png) - ## Separating Consensus from Compute At a high level, the pipeline essentially separates consensus from transaction computation. Non-deterministic (or “subjective”) processes such as determining the inclusion and order of transactions are decided by the broadly decentralized consensus committee. The deterministic (or “objective”) task of computing the result of those ordered transactions is done independently by a small number of specialized execution nodes. Collection and consensus are highly decentralized and achieve high levels of redundancy through a large number of lightweight, cost-effective nodes, numbering in the thousands, operated by several hundred different operators. These steps guarantee resilient transaction ordering (assuming that a malicious actor can only compromise a limited number of nodes). -In comparison, transaction execution has low decentralization and redundancy (10 or less) with more powerful and expensive nodes. To accommodate for the anticipated growth of on-chain state without sharding, only the execution nodes have to be scaled vertically. All other node types can continue to run low-cost hardware. The execution nodes may eventually be scaled up to small data centers. +In comparison, transaction execution has low decentralization and redundancy (10 or less) with more powerful and expensive nodes. To accommodate for the anticipated growth of onchain state without sharding, only the execution nodes have to be scaled vertically. All other node types can continue to run low-cost hardware. The execution nodes may eventually be scaled up to small data centers. ![scaling_flow](images/scaling_flow.png) Low decentralization for transaction execution might appear to compromise decentralization of the whole network, as it is conceivable that a malicious actor might compromise a dominant fraction of nodes participating in execution. However, correctness of the transaction results is still guaranteed by the verification step, which also requires reasonably high redundancy, again with a large number of lighter and less expensive verification nodes to withstand compromisation attempts. Every node in Flow makes the protocol stronger, and the network can grow as needed to achieve different objectives: + - More censorship resistance? Add more collection nodes - More decentralized block production? Add more consensus nodes - Need to accommodate higher transaction throughput and state storage? Scale up execution nodes @@ -42,10 +42,10 @@ In contrast, when traditional Layer 1 blockchains add more nodes to increase dec Thus, Flow’s multi-role architecture solves the blockchain trilemma: -1. **Scalability**: Scale to thousands of times higher throughput and on-chain storage capacity. +1. **Scalability**: Scale to thousands of times higher throughput and onchain storage capacity. 2. **Decentralization**: Except for the execution nodes, all nodes are light weight and low cost, lowering the barrier to entry and ensuring participation from a diverse set of node operators—big and small 3. **Security**: Maintain a shared non-sharded execution environment for all operations on the network and use a secure in-built platform to build on. -![trilemma_solved](images/flow_trillema_solved.png) \ No newline at end of file +![trilemma_solved](images/flow_trillema_solved.png) diff --git a/docs/networks/network-architecture/sustainability.md b/docs/protocol/network-architecture/sustainability.md similarity index 100% rename from docs/networks/network-architecture/sustainability.md rename to docs/protocol/network-architecture/sustainability.md diff --git a/docs/networks/network-architecture/user-safety.md b/docs/protocol/network-architecture/user-safety.md similarity index 100% rename from docs/networks/network-architecture/user-safety.md rename to docs/protocol/network-architecture/user-safety.md diff --git a/docs/networks/node-ops/_category_.yml b/docs/protocol/node-ops/_category_.yml similarity index 100% rename from docs/networks/node-ops/_category_.yml rename to docs/protocol/node-ops/_category_.yml diff --git a/docs/networks/node-ops/access-nodes/_category_.yml b/docs/protocol/node-ops/access-nodes/_category_.yml similarity index 100% rename from docs/networks/node-ops/access-nodes/_category_.yml rename to docs/protocol/node-ops/access-nodes/_category_.yml diff --git a/docs/networks/node-ops/access-nodes/access-node-configuration-options.md b/docs/protocol/node-ops/access-nodes/access-node-configuration-options.md similarity index 63% rename from docs/networks/node-ops/access-nodes/access-node-configuration-options.md rename to docs/protocol/node-ops/access-nodes/access-node-configuration-options.md index a38add3293..b32401402c 100644 --- a/docs/networks/node-ops/access-nodes/access-node-configuration-options.md +++ b/docs/protocol/node-ops/access-nodes/access-node-configuration-options.md @@ -5,13 +5,13 @@ sidebar_position: 2 --- Flow chain data comprises of two parts, + 1. Protocol state data - This refers to the blocks, collection, transaction that are being continuously added to the chain. 2. Execution state data - This refers to what makes up the execution state and includes transaction events and account balances. The access node by default syncs the protocol state data and has been now updated to also sync the execution state data. This guide provides an overview of how to use the execution data sync feature of the Access node. -