Character
A character is a distinct identity that enables interaction with the blockchain. In other words, it is the account that represents a user on the blockchain.
One user has one single crypto wallet. Each wallet (also referred to as an address) can contain multiple characters. Every character is associated with a single wallet.
You can learn more about characters in the Concept - Character section.
Prepare the Contract and Indexer
Our futher steps will be using the Contract
and Indexer
. Please refer to the API Reference section to learn how to create them.
Check if You Have a Character
You can check if you have a character by checking from the indexer:
const result = await indexer.character.getMany(address)
console.log(result.list) // character list
Because a wallet can have multiple characters, the result is a list of characters. If you don't have a character yet, the list will be empty.
Create a Character
If you don't have a character yet, or you want to create a new one, you can use the contract.character.create
(opens in a new tab) method:
const result = await contract.character.create({
owner,
handle: 'best-character-ever',
metadataOrUri: 'https://example.com/character-metadata.json',
})
console.log(result.data) // character id
The handle must be unique when creating a character. This is a unique identifier that will be displayed as @best-character-ever
in the user interface. If a character with an existing handle is attempted to be created on the Crossbell blockchain, the transaction will be unsuccessful.
Check if a Handle is Available
To ensure that the handle is available before creating a character, you can query from the indexer:
const result = await indexer.character.getByHandle('best-character-ever')
console.log(result.data) // a character or null
If the result is null
, the handle is available.
Character Metadata
The character metadata is a JSON object that contains the character's information.
In the example above, "https://example.com/character-metadata.json"
is the URL of the character metadata. The character metadata can also be a JSON object:
{
"name": "John Doe",
"bio": "I am the best character ever"
}
You can add more metadata fields like avatars
:
{
"name": "John Doe",
"bio": "I am the best character ever",
"avatars": ["https://example.com/avatar.png"]
}
It can be hosted on any web server. It can be ipfs://
URL. For example, here is another more complex note metadata: ipfs://bafkreibu6cxouafklrbf5vvwnqdv2jtszru45gqdyswesyqlcdiffyy5la
(opens in a new tab).
You can create a character with metadata content object directly:
const result = await contract.character.create({
owner, // wallet address
handle: 'best-character-ever', // handle
metadataOrUri: {
name: 'John Doe',
bio: 'I am the best character ever',
}, // character metadata
})
console.log(result.data) // character id
In this case, the SDK will automatically upload the metadata to IPFS and create a character with the ipfs://
URL.
Please refer to the Character Metadata section to learn more about the character metadata.
Character Link Module
Before attaching a link module to a character, please refer to the Concepts - Mint/Link Module section to learn more about what a link module is.
Note that you won't be able to change the link module after the character is created.
Update a Character
You can update a character using a variety of methods. For example:
- Update handle (opens in a new tab)
- Update metadata (opens in a new tab)
- Switch primary character (opens in a new tab)
Delete a Character
Topics
Update Character Metadata
Example: Add an Avatar
Let's say we have a character 42
with the following metadata:
{
"name": "John Doe",
"bio": "I am the best character ever"
}
If this character wants to add a new avatar, we can use the contract.character.changeMetadata
(opens in a new tab) method:
contract.character.changeMetadata({
characterId: 42,
modifier: (metadata) => {
metadata = {
...metadata,
avatars: ['https://example.com/avatar.png'],
}
return metadata
}
})
The metadata
parameter is the current metadata of the character. You can modify it and return the new metadata. The SDK will automatically upload the new metadata to IPFS and update the character.
Example: Update the Attributes
As described in the Character Metadata section, the character metadata can have an attributes
field. This field is an array of attributes. Each attribute has a trait_type
and a value
field.
Let's say our character 42
has the following metadata:
{
"name": "John Doe",
"bio": "I am the best character ever",
"avatars": ["https://example.com/avatar.png"],
"attributes": [
{
"trait_type": "Strength",
"value": 100
},
{
"trait_type": "Agility",
"value": 100
}
]
}
We want to add a new attribute Intelligence
with a value of 100
:
contract.character.changeMetadata({
characterId: 42,
modifier: (metadata) => {
metadata = {
...metadata,
attributes: [
...metadata.attributes, // copy the existing attributes
{
trait_type: 'Intelligence',
value: 100,
},
],
}
return metadata
}
})
If we want to update the value of an existing attribute, we can use the Array.prototype.map
(opens in a new tab) method:
contract.character.changeMetadata({
characterId: 42,
modifier: (metadata) => {
metadata = {
...metadata,
attributes: metadata.attributes.map(attribute => {
if (attribute.trait_type === 'Intelligence') {
return {
...attribute,
value: 200,
}
}
return attribute
}),
}
return metadata
}
})
Pitfall: Overwriting vs Merging
We are using the contract.character.changeMetadata
(opens in a new tab) method to update the character metadata. This method helps us to update the metadata with merging instead of overwriting.
There is another method called contract.character.setCharacterMetadata
(opens in a new tab). This method will overwrite the metadata with the new metadata, which in most cases is NOT what we want because it will remove all the existing metadata of the character.