Home

Use Token Bound Accounts

Learn how use token bound accounts (ERC6551) in your game.

In this guide you'll find how to implement a token bound account based on a game character. This guide implements the backend code necessary to use token bound accounts in your game. It uses the Openfort Node SDK. Architecture of the solution proposed in this guide:

using-token-bound-accounts

note

For a genereral overview of token bound accounts, see the Token Bound Accounts blog post. You can find the complete code of this guide in the openfort samples GitHub.

Prerequisites#

When interacting with smart wallets through Openfort, import the contract and create a policy to sponsor gas. Get your secret key from the Openfort dashboard.

1. Import the NFT contract#

Token bound accounts are based on the ownership of a non-fungible token. In this guide, we'll use a contract, deployed at in Polygon Amoy at 0x380...AC0.

Add a new contract by clicking the Add contract button in the Asset contracts section, then enter:

  • The name of the contract (it can be any name you want; the name is only for identification purposes)
  • The network (chainId) where the smart contract is located: 80002.
  • The address of the contract.
  • Because the contract is verified in the block explorer, there's no need to provide an ABI manually.
DashboardAddContract

2. Set up gas sponsoring#

Add a new policy by clicking the Add policy button in the Policies page, then enter:

  • The name of the policy (it can be any name you want; the name is only for identification purposes)
  • The network (chainId) where the smart contract is located: 80002.
  • As a fee sponsorship strategy, leave pay gas for user.
  • Under policy rules, create two rules:
    • 1st rule:
      • Leave contract_functions under Rule model.
      • Under Contract, select the contract you imported in the previous step.
      • Under Function name, select All functions.
    • 2nd rule:
      • Choose account_functions under Rule model.
GasPolicy

Create the character NFT#

As you know, to create a token bound account, you need to first know what NFT will be used to define the ownership of the account. Becasue in this guide we start from scratch, we'll also mint that NFT, but you could potentially use any NFT that you already own. If you want to use your own NFT, skip to the next section.

We'll use a regular Openfort account to mint it. We start by creating an Openfort player and a regular Openfort account.

server.ts

_10
const upgradeable_account = await openfort.accounts.create({
_10
chainId: chainId,
_10
});
_10
const player_upgradeable = upgradeable_account.player.id;

Then, we define the mint function interaction and create a transactionIntent using the gas sponsoring policy we created in the previous step.

server.ts

_14
const interactionsMintOwnerNFT: Interaction[] = [
_14
{
_14
contract: SimpleNFT.id,
_14
functionName: 'mint',
_14
functionArgs: [player_upgradeable.id],
_14
},
_14
]
_14
const transactionIntentSimpleNFT = await openfort.transactionIntents.create({
_14
player: player_upgradeable.id,
_14
interactions: interactionsMintOwnerNFT,
_14
policy: policy.id,
_14
chainId: chainId,
_14
optimistic: false,
_14
})

And we're all set! The character NFT is minted and owned by the player_upgradeable's account.

Create a token bound account#

Now that we have the NFT that will defined the ownership of the account, we can create a token bound account. Note that when creating the token bound account, we need to specify:

  • The externalOwnerAddress field: the address that currently owns the character NFT.
  • The tokenContract field: the address of the NFT contract.
  • The tokenId field: the token id of the character NFT.
  • The accountType field: specified that the account to be created is a token bound account.

We start off by creating a new player and then assign a new counterfactual token bound account to it:

server.ts

_11
const player_6551 = await openfort.players.create({
_11
name: '6551 account',
_11
})
_11
const account = await openfort.accounts.create({
_11
player: player_6551.id,
_11
chainId: chainId,
_11
accountType: DataAccountTypes.Erc6551,
_11
tokenContract: SimpleNFT.id,
_11
tokenId: simpleOwnerNFTTokenId,
_11
externalOwnerAddress: upgradeable_account.address,
_11
})

Transferring the character NFT#

You can send the character NFT to another account by calling the safeTransferFrom function of the NFT contract. This function takes the address of the current owner, the address of the new owner, and the token id as arguments.

In this case, we'll transfer the character NFT to the previously account ownerAddress. This is because Openfort accounts come, by default, with a managed signer. Sending the NFT to the account ownerAddress allows a regular EOA to control the account.

server.ts

_24
const interactionsExecCall: Interaction[] = [
_24
{
_24
contract: SimpleNFT.id,
_24
functionName: 'approve',
_24
functionArgs: [ownerAddress, simpleOwnerNFTTokenId],
_24
},
_24
{
_24
contract: SimpleNFT.id,
_24
functionName: 'safeTransferFrom',
_24
functionArgs: [
_24
player_upgradeable.id,
_24
account.ownerAddress,
_24
simpleOwnerNFTTokenId,
_24
],
_24
},
_24
]
_24
const transactionIntentTransferOwnerNFT =
_24
await openfort.transactionIntents.create({
_24
player: player_upgradeable.id,
_24
interactions: interactionsExecCall,
_24
policy: policy.id,
_24
chainId: chainId,
_24
optimistic: false,
_24
})

Minting an asset into the character NFT#

You can easily mint assets into the token bound account and even use it to mint assets. Here we interact with the same simple NFT contract to mint an NFT into the token bound account.

server.ts

_16
const interactionsMintNFT: Interaction[] = [
_16
{
_16
contract: SimpleNFT.id,
_16
functionName: 'mint',
_16
functionArgs: [player_6551.id],
_16
},
_16
]
_16
const transactionIntentSimpleNFT6551 = await openfort.transactionIntents.create(
_16
{
_16
player: player_6551.id,
_16
interactions: interactionsMintNFT,
_16
policy: policy.id,
_16
chainId: chainId,
_16
optimistic: false,
_16
}
_16
)