diff --git a/docs/blockchain-development-tutorials/cadence/account-management/account-linking-with-dapper.md b/docs/blockchain-development-tutorials/cadence/account-management/account-linking-with-dapper.md index 51b509f704..0e445e2d59 100644 --- a/docs/blockchain-development-tutorials/cadence/account-management/account-linking-with-dapper.md +++ b/docs/blockchain-development-tutorials/cadence/account-management/account-linking-with-dapper.md @@ -28,16 +28,16 @@ keywords: ![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 those users needing 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 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. ## Prerequisites @@ -51,7 +51,7 @@ 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 @@ -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,7 +70,7 @@ 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 @@ -78,13 +78,13 @@ You'll need a few more dependencies to efficiently work with Cadence inside of y ### 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 for interacting with the Flow ecosystem. If you don't have it installed, you can add it with Brew (or using [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 @@ -118,7 +118,7 @@ export default nextConfig; ## 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 @@ -132,7 +132,7 @@ yarn add dotenv ### 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`: @@ -229,7 +229,7 @@ Don't forget to replace `` with your own [Wallet Connect] app id! ### Implement the Provider and Flow Config -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. ::: @@ -302,7 +302,7 @@ export default function RootLayout({ ### 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'; @@ -351,11 +351,9 @@ Run the app: yarn dev ``` -You'll see your `Log In` button in the middle of the window. - ![Welcome](./imgs/welcome.png) -Click the button and log in with your Flow wallet. +Click `Log In` in the middle of the window and log in with your Flow wallet. ![Flow Wallet](./imgs/flow-wallet.png) @@ -375,7 +373,7 @@ The Dapper Wallet requires that you complete KYC before you can use Account Link ### Discovering 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]: @@ -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" @@ -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're using 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); @@ -620,7 +618,7 @@ Run the app again. If you have linked your account and have NFTs in that account ### Displaying the Moments -Now that they're here, all to do is display them nicely! Return to `DisplayLinkedNFTs.tsx`. Add a helper function to confirm each returned NFT matches the Moments format. You can update this to handle other NFTs you'd like to show as well. +Now that they're here, all that's left to do is display them nicely! Return to `DisplayLinkedNFTs.tsx`. Add a helper function to confirm each returned NFT matches the Moments format. You can update this to handle other NFTs you'd like to show as well. :::warning @@ -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. diff --git a/docs/blockchain-development-tutorials/cadence/account-management/child-accounts.md b/docs/blockchain-development-tutorials/cadence/account-management/child-accounts.md index 88bde2d2fa..9adec4fa0d 100644 --- a/docs/blockchain-development-tutorials/cadence/account-management/child-accounts.md +++ b/docs/blockchain-development-tutorials/cadence/account-management/child-accounts.md @@ -20,8 +20,8 @@ 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 +In this tutorial, we'll dive into a progressive onboarding flow, including the Cadence scripts & 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 delegating control of the app account as Account Linking. @@ -30,34 +30,32 @@ account as Account Linking. - 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 +- 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 + wallet-mediated "parent" account and any "child" accounts. +- Facilitate transactions acting on assets in child accounts. ## 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 +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 +Very simply, account linking is a [feature in Cadence](https://github.com/onflow/flips/pull/53) that lets 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 - -transaction: +Below is an example demonstrating how to issue an `&Account` Capability from a signing account transaction: ```cadence link_account.cdc #allowAccountLinking @@ -73,9 +71,9 @@ 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. +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 +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`. @@ -83,43 +81,42 @@ transaction that may create a Capability on their `Account`. 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. +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 & 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. -**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 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`, providing its owning user access to any and all of their linked accounts. +`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 +walletless onboarding and later linking 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. +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. +which gives the delegatee presiding authority superseding 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 +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. @@ -130,8 +127,8 @@ Since account delegation is mediated by developer-defined rules, you should make 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 +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, retrieving a Capability that can be cast to `Capability<&NonFungibleToken.Collection>` for example. Here's how you would configure an `AllowlistFilter` and add allowed types to it: @@ -174,7 +171,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 +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. @@ -225,18 +222,16 @@ transaction { ![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 +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 +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: -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. +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. Let's take a look at both. @@ -255,7 +250,7 @@ those NFTs so the user can easily transfer them between their linked accounts. #### Publish -Here, the account delegating access to itself links its `&Account` Capability, and publishes it to be claimed by the +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 @@ -295,7 +290,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 +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 @@ -361,7 +356,7 @@ 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 +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. ::: @@ -540,18 +535,14 @@ power of the complex transactions you can compose on Flow with Cadence! Recall the [prerequisites](#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 -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 while immediately delegating 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 @@ -685,11 +676,11 @@ transaction( ## Funding & Custody Patterns -Aside from implementing onboarding flows & account linking, you'll want to also consider the account funding & custodial +Aside from implementing onboarding flows and 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. -In general, the funding pattern for account creation will determine to some extent the backend infrastructure needed to +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 diff --git a/docs/blockchain-development-tutorials/cadence/account-management/index.md b/docs/blockchain-development-tutorials/cadence/account-management/index.md index ddc6124422..2791497077 100644 --- a/docs/blockchain-development-tutorials/cadence/account-management/index.md +++ b/docs/blockchain-development-tutorials/cadence/account-management/index.md @@ -22,42 +22,40 @@ keywords: # Account Linking -Account linking is a unique Flow concept that enables sharing ownership over [accounts](../../../build/cadence/basics/accounts.md). In -order to understand how we can achieve that we must first understand how accounts on Flow are accessed. +Account linking is a unique Flow concept that allows sharing ownership over [accounts](../../../build/cadence/basics/accounts.md). To understand how we can achieve that, we must first understand how to access accounts on Flow. -Accounts on flow can be accessed in Cadence through two types, `PublicAccount` and `Account`. As the name implies the +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](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 +`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) ## 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 +Accessing `Account` allows for modification to account storage, so it's essential to mandate that the account being accessed signs all transactions, which safeguards this access. +[Account +entitlements](https://cadence-lang.org/docs/language/accounts/#performing-write-operations) 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](../../../build/cadence/basics/transactions.md). -Since access to the `Account` object enables state change, the idea of account ownership actually translates to the +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 [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. +Before you continue with this section, you'll need a clear understanding of [Cadence +capabilities](https://cadence-lang.org/docs/language/capabilities). Advanced features such as +Account Capabilities are powerful, but they can put your app or users at risk if used incorrectly. -Cadence allows the creation of Capabilities to delegate access to account storage, meaning any account obtaining a valid +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 - 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. +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 @@ -67,13 +65,13 @@ 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 +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) -A link between two existing accounts on Flow can be created in two steps: +You can create a link between two existing 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. @@ -128,9 +126,9 @@ transaction { ## 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 +Account linking was specifically designed to allow 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 +user's reluctance to install a wallet, which opens 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 @@ -139,7 +137,7 @@ account instead of the user and stores that user's specific state in the app-cre can take ownership of the app account providing they possess a full [Flow account](../../../build/cadence/basics/accounts.md), typically by installing a wallet app. -Account linking enables users to possess multiple linked child accounts from different apps. Complexities associated +Account linking allows 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 @@ -154,48 +152,47 @@ 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 enables users to establish real ownership of the items +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 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. +Most importantly, users can do this without the need to transfer the digital items between accounts, which makes it +seamless to continue using the original app and enjoy 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. +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. -Creating an `&Account` Capability and publishing it to an account we don't own means we are giving that account full +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 -Creating an `&Account` Capability and sharing it with third-party account effectually the same as giving that person your +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](./parent-accounts.md) that helps custodial applications regulate access while enabling parent accounts to +contract](./parent-accounts.md) that helps custodial applications regulate access and allows 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: +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 + 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. + Linking to create a seamless user experience and allow 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. diff --git a/docs/blockchain-development-tutorials/cadence/account-management/parent-accounts.md b/docs/blockchain-development-tutorials/cadence/account-management/parent-accounts.md index 705b2e75e0..b3f460af9d 100644 --- a/docs/blockchain-development-tutorials/cadence/account-management/parent-accounts.md +++ b/docs/blockchain-development-tutorials/cadence/account-management/parent-accounts.md @@ -20,18 +20,18 @@ keywords: - account security --- -In this doc, we'll continue from the perspective of a wallet or marketplace app seeking to facilitate a unified account +In this tutorial, 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. ## 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 @@ -69,7 +69,7 @@ Parent accounts own a `Manager` resource which stores Capabilities to `ChildAcco 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. +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`. @@ -80,20 +80,20 @@ To clarify, insofar as the standard is concerned, an account is a parent account 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. +with corresponding values that give the `Manager` access to those accounts via corresponding `ChildAccount` Capability. ![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). +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. #### Restricted vs. Owned Accounts -It's worth noting here that `ChildAccount` Capabilities enable access to the underlying account according to rules + `ChildAccount` Capabilities allow 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 @@ -117,7 +117,7 @@ Capability to itself before publishing the new `ChildAccount` Capability for the :::info -Note that by enumerating allowable Types in your `CapabilityFilter.Filter` implementation, you're by default excluding +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. ::: @@ -134,12 +134,12 @@ Do note that this construction does not prevent an account from having multiple 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 +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 +Ultimately, it's' up to the implementing wallet or marketplace how far down the graph of account associations they'd want to traverse and display to the user. ## Implementation @@ -199,8 +199,8 @@ Since some accounts hold thousands of NFTs, we recommend breaking up iteration, over accounts and the storage of each account. Batching queries on individual accounts may even be required based on the number of NFTs held. -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. Looping over each associated account address client-side, 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. @@ -268,15 +268,15 @@ 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 +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 -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. Looping over each associated account address client-side, get each address's owned FungibleToken Vault metadata. However, we'll condense both of these steps down into one script for simplicity: @@ -360,9 +360,9 @@ to aggregate more information about the underlying Vaults. ### 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 +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`, enabling withdrawal from the child account having signed as the parent account. +`NonFungibleToken.Provider`, which allows withdrawal from the child account that signs as the parent account. ```cadence withdraw_nft_from_child.cdc import "NonFungibleToken" @@ -440,8 +440,7 @@ 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 +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 @@ -460,5 +459,5 @@ 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. \ No newline at end of file