SDK
crossbell.js
Guides
Character

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:

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.