Use token bound accounts (ERC6551)
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:
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.
Dashboard
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.

API Methods
curl
curl https://api.openfort.io/v1/contracts \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d name="SimpleNFT" \
-d address="0xbed6a05ce8719bc00db1cc81a814192c82be1bb1" \
-d chainId="80002"
Node.js
const openfort = new Openfort(process.env.YOUR_SECRET_KEY);
const SimpleNFT = await openfort.contracts.create({
name: "SimpleNFT",
address: "0xbed6a05ce8719bc00db1cc81a814192c82be1bb1",
chainId: chainId,
});
2. Set up gas sponsoring
Dashboard
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
.
- Leave
- 2nd rule:
- Choose
account_functions
under Rule model.
- Choose
- 1st rule:

API Methods
curl
curl https://api.openfort.io/v1/policies \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d name="Trial sponsor" \
-d chainId="80002" \
-d "strategy[sponsorSchema]=pay_for_user"
Use the policy id to create policy rules and use the previously imported contract.
curl https://api.openfort.io/v1/policies/:id/policy_rules \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d type="contract_functions" \
-d functionName="All functions" \
-d contract="con_..."
curl https://api.openfort.io/v1/policies/:id/policy_rules \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d type="account_functions"
Node.js
const policy = await openfort.policies.create({
name: "test",
chainId: 80002,
strategy: {
sponsorSchema: SponsorSchema.PayForUser,
},
});
await openfort.policyRules.create({
contract: SimpleNFT.id,
type: PolicySchema.ContractFunctions,
policy: policy.id,
functionName: "All functions",
});
await openfort.policyRules.create({
type: PolicySchema.AccountFunctions,
policy: policy.id,
});
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. Because 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.
const upgradeable_account = await openfort.accounts.create({
chainId: chainId,
});
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.
const interactionsMintOwnerNFT: Interaction[] = [
{
contract: SimpleNFT.id,
functionName: 'mint',
functionArgs: [player_upgradeable.id],
},
]
const transactionIntentSimpleNFT = await openfort.transactionIntents.create({
player: player_upgradeable.id,
interactions: interactionsMintOwnerNFT,
policy: policy.id,
chainId: chainId,
optimistic: false,
})
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:
const player_6551 = await openfort.players.create({
name: '6551 account',
})
const account = await openfort.accounts.create({
player: player_6551.id,
chainId: chainId,
accountType: DataAccountTypes.Erc6551,
tokenContract: SimpleNFT.id,
tokenId: simpleOwnerNFTTokenId,
externalOwnerAddress: upgradeable_account.address,
})
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.
const interactionsExecCall: Interaction[] = [
{
contract: SimpleNFT.id,
functionName: 'approve',
functionArgs: [ownerAddress, simpleOwnerNFTTokenId],
},
{
contract: SimpleNFT.id,
functionName: 'safeTransferFrom',
functionArgs: [
player_upgradeable.id,
account.ownerAddress,
simpleOwnerNFTTokenId,
],
},
]
const transactionIntentTransferOwnerNFT =
await openfort.transactionIntents.create({
player: player_upgradeable.id,
interactions: interactionsExecCall,
policy: policy.id,
chainId: chainId,
optimistic: false,
})
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.
const interactionsMintNFT: Interaction[] = [
{
contract: SimpleNFT.id,
functionName: 'mint',
functionArgs: [player_6551.id],
},
]
const transactionIntentSimpleNFT6551 = await openfort.transactionIntents.create(
{
player: player_6551.id,
interactions: interactionsMintNFT,
policy: policy.id,
chainId: chainId,
optimistic: false,
}
)