Wrapping Characters
Pre-requisites
Before following this guide to wrap characters, please make sure that you've followed our getting started guide and set up your development environment. If you need any help at any point.
You will also need to have an existing project on Honeycomb. If you don't have one, you can create a project by following the steps here.
Intro
Wrapping characters is a process that basically locks an NFT into a vault and creates a Honeycomb character. This process is useful for creating characters from NFTs that are not part of the Honeycomb Protocol.
Follow these steps to create a character using wrapping.
1. Create a character model
In order to wrap a character, you first need to create a character model. This model will contain the information about the character's traits.
- JavaScript
- GraphQL
- Unity/C#
await client.createCreateCharacterModelTransaction({
authority: adminPublicKey.toString(), // Project authority public key as a string
project: projectAddress.toString(),
payer: adminPublicKey.toString(), // Optional, if you want to pay from a different wallet
config: {
kind: "Wrapped",
criterias: [
{
kind: "MerkleTree", // Can be Collection, Creator, or MerkleTree
params: merkleTreeAddress.toString(), // Provide the relevant address here
}
]
},
cooldown: { // Optional, add a cool down period (in seconds) before the characters can be unwrapped
ejection: 1, // Ejection/unwrap cool down (in seconds)
}
});
query CreateCreateCharacterModelTransaction($config: CharacterConfigInput!, $project: String!, $authority: String!, $attributes: JSON, $payer: String, $cooldown: CharacterCooldownInput) {
createCreateCharacterModelTransaction(config: $config, project: $project, authority: $authority, payer: $payer, cooldown: $cooldown) {
characterModel
tx {
blockhash
lastValidBlockHeight
transaction
}
}
}
Provide the data like this:
{
"config": {
"kind": "Wrapped", // For Wrapped characters
"criterias": [ // Multiple criterias can be defined
{
"kind": "Collection/Creator/MerkleTree", // Pass one of the three at a time
"params": "pubkey" // Relevant public key as a string
}
]
},
"project": "pubkey", // Project public key as a string
"authority": "pubkey", // Authority public key as a string
"payer": "pubkey" // Optional, payer public key as a string
}
var config = new CharacterConfigInput
{
Kind = "Wrapped",
Criterias = new List<NftWrapCriteriaInput>
{
new NftWrapCriteriaInput
{
Kind = "MerkleTree", // Can be Collection, Creator, or MerkleTree
Params = "merkleTreeAddress.ToString()" // Provide the relevant address here
}
}
};
var createCharacterModelTransaction = new CreateCreateCharacterModelTransactionParams
{
Authority = adminPublicKey.ToString(), // Project authority public key as a string
Project = projectAddress.ToString(),
Payer = adminPublicKey.ToString(), // Optional, if you want to pay from a different wallet
Config = config,
Cooldown = new CharacterCooldownInput
{
Ejection = 1 // Ejection/unwrap cool down (in seconds)
}, // Optional, add a cool down period (in seconds) before the characters can be unwrapped
};
// Execute the transaction
await Client.CreateCreateCharacterModelTransaction(createCharacterModelTransaction);
2. Creating a character tree
After creating a character model, you need to create a character tree. This tree is used to store characters and their necessary information, like who owns the character and if a character is on a mission.
- JavaScript
- GraphQL
- Unity/C#
await client.createCreateCharactersTreeTransaction({
authority: adminPublicKey.toString(),
project: projectAddress.toString(),
characterModel: characterModelAddress.toString(),
payer: adminPublicKey.toString(), // Optional, only use if you want to pay from a different wallet
treeConfig: {
// Provide either the basic or advanced configuration, we recommend using the basic configuration if you don't know the exact values of maxDepth, maxBufferSize, and canopyDepth (the basic configuration will automatically configure these values for you)
basic: {
numAssets: 100000, // The desired number of characters this tree will be able to store
},
// Uncomment the following config if you want to configure your own profile tree (also comment out the above config)
// advanced: {
// canopyDepth: 20,
// maxBufferSize: 64,
// maxDepth: 14,
// }
},
});
query CreateCharacterTreeTransaction($treeConfig: TreeSetupConfig!, $project: Bytes!, $characterModel: Bytes!, $authority: Bytes!, $payer: Bytes) {
createCreateCharactersTreeTransaction(treeConfig: $treeConfig, project: $project, characterModel: $characterModel, authority: $authority, payer: $payer) {
blockhash
lastValidBlockHeight
transaction
}
}
Pass the variables like this:
{
"treeConfig": {
// Provide either the basic or advanced configuration, we recommend using the basic configuration if you don't know the exact values of maxDepth, maxBufferSize, and canopyDepth (the basic configuration will automatically configure these values for you)
"basic": {
"numAssets": 100000 // The desired number of characters this tree will be able to store
},
// Use the following config if you want to configure your own profile tree (also remove the above basic config)
// "advanced": {
// "canopyDepth": 20, // Canopy depth
// "maxBufferSize": 64, // Maximum buffer size
// "maxDepth": 14 // Maximum depth
// }
},
"project": "pubkey", // Project public key as a string
"characterModel": "pubkey", // Character model public as a string
"authority": "pubkey", // Authority public key as a string
"payer": "pubkey" // Payer public key as a string
}
var treeConfig = new TreeSetupConfig
{
// Provide either the basic or advanced configuration
Basic = new BasicTreeConfig
{
NumAssets = 100000 // The desired number of characters this tree will be able to store
},
// Uncomment the following config if you want to configure your own profile tree
// Advanced = new AdvancedTreeConfig
// {
// CanopyDepth = 20,
// MaxBufferSize = 64,
// MaxDepth = 14
// }
};
var createCharactersTreeTransaction = new CreateCreateCharactersTreeTransactionParams
{
Authority = adminPublicKey.ToString(),
Project = projectAddress.ToString(),
CharacterModel = characterModelAddress.ToString(),
Payer = adminPublicKey.ToString(), // Optional, only use if you want to pay from a different wallet
TreeConfig = treeConfig
};
// Execute the transaction
await Client.CreateCreateCharactersTreeTransaction(createCharactersTreeTransaction);
To calculate the canopy depth, buffer size, and depth, use compressed.app. If you have any confusions about these values, please reach out to us on Discord or email.
3. Wrap assets to character
After creating a character model and a character tree, you can wrap assets to create a new character.
This process will lock the NFT(s) and create a Honeycomb character.
To wrap, send a query like this:
- JavaScript
- GraphQL
- Unity/C#
await client.createWrapAssetsToCharacterTransactions({
project: projectAddress.toString(),
mintList: [] // Provide NFT addresses here,
wallet: userPublicKey.toString(), // User's wallet public key as a string
characterModel: characterModelAddress.toString(),
});
query CreateWrapAssetsToCharacterTransactions($mintList: [Bytes!]!, $project: Bytes!, $characterModel: Bytes!, $wallet: Bytes!) {
createWrapAssetsToCharacterTransactions(mintList: $mintList, project: $project, characterModel: $characterModel, wallet: $wallet) {
blockhash
lastValidBlockHeight
transactions
}
}
Send accompanying data like so:
{
"mintList": ["pubkey1", "pubkey2"], // NFT public keys as a string array
"project": "pubkey", // Project public key as a string
"characterModel": "pubkey", // Character model public key as a string
"wallet": "pubkey" // Send the public key as a string
}
var wrapAssetsToCharacterTransaction = new CreateWrapAssetsToCharacterTransactionsParams
{
Project = projectAddress.ToString(),
MintList = new List<string>{
// Provide NFT addresses here
},
Wallet = userPublicKey.ToString(), // User's wallet public key as a string
CharacterModel = characterModelAddress.ToString()
};
// Execute the transaction
await Client.CreateWrapAssetsToCharacterTransactions(wrapAssetsToCharacterTransaction);
Other operations
Honeycomb also supports other utility operations, covered below.
Find characters
All of the variables in the find characters function are optional. You can use any combination of them as needed.
- JavaScript
- GraphQL
- Unity/C#
await client.findCharacters({
addresses: [], // String array of character addresses
includeProof: true, // Boolean to include proof or not
filters: {}, // Available filters are usedBy, owner, and source
mints: [], // Array of NFT mint public keys as a string
trees: [], // Array of character model merkle tree public keys as a string
wallets: [], // Array of wallet public keys as a string (wallets that own the characters)
attributeHashes: [] // Array of attribute hashes as a string
});
query Character($addresses: [Bytes!], $trees: [Bytes!], $wallets: [Pubkey!], $mints: [Pubkey!], $attributeHashes: [Pubkey!], $includeProof: Boolean, $filters: CharactersFilter) {
character(addresses: $addresses, trees: $trees, wallets: $wallets, mints: $mints, attributeHashes: $attributeHashes, includeProof: $includeProof, filters: $filters) {
address
tree_id
leaf_idx
owner
source {
params {
... on Wrapped {
mint
criteria {
kind
params
}
isCompressed
}
... on Assembled {
hash
mint
uri
attributes
updateAuthority
}
}
kind
}
usedBy {
kind
params {
... on UsedByStaking {
pool
staker
stakedAt
claimedAt
}
... on UsedByMission {
missionId
participationId
rewards {
rewardIdx
delta
collected
}
endTime
}
... on UsedByGuild {
id
role {
kind
}
order
}
... on UsedByEjected {
wasAssembled
mint
}
... on UsedByCustom {
user
data
}
}
}
proof {
root
proof
node_index
leaf
leaf_index
tree_id
}
asset
}
}
Provide the accompanying data like this:
{
"addresses": [], // Array of character addresses
"trees": [], // Array of character model merkle tree public keys as a string
"wallets": [], // Array of wallet public keys as a string (user wallets that hold the characters)
"mints": [], // Array of NFT mint public keys as a string
"attributeHashes": [], // Array of attribute hashes as a string
"includeProof": boolean, // Determines if the proof should be included in the result or not
"filters": { // Filters for the characters,
"usedBy": {
"params": {
"wasAssembled": boolean,
"user": "pubkey",
"staker": "pubkey",
"stakedAt": int,
"role": {
"kind": "string"
},
"rewards": [
{
"rewardIdx": int,
"delta": int,
"collected": boolean
}
],
"pool": "pubkey", // Staking pool public key
"order": int, // Guild order
"mint": "pubkey",
"id": "pubkey",
"endTime": int,
"claimedAt": int
},
"kind": "string"
},
"source": {
"params": {
"mint": "pubkey",
"is_compressed": boolean,
"criteria": { // NFT Wrap criteria
"params": "pubkey",
"kind": "string"
}
},
"kind": "string"
},
"owner": "pubkey" // Character owner public key
}
}
var findCharactersParams = new FindCharactersParams
{
Addresses = new List<string>
{
// String array of character addresses
},
IncludeProof = true, // Boolean to include proof or not
Filters = new CharactersFilter
{
// Available filters are usedBy, owner, and source
},
Mints = new List<string>
{
// Array of NFT mint public keys as a string
},
Trees = new List<string>
{
// Array of character model merkle tree public keys as a string
},
Wallets = new List<string>
{
// Array of wallet public keys as a string (wallets that own the characters)
},
AttributeHashes = new List<string>
{
// Array of attribute hashes as a string
}
};
// Execute the find characters method
var characters = await Client.FindCharacters(findCharactersParams);
Unwrapping characters (optional)
Unwrapping an asset means that the character will be removed from your project and the assets (NFTs/cNFTs) will be returned to the user's wallet.
- JavaScript
- GraphQL
- Unity/C#
await client.createUnwrapAssetsFromCharacterTransactions({
characterAddresses: [], // Array of character addresses as a string
characterModel: characterModelAddress.toString(),
project: projectAddress.toString(),
wallet: userPublicKey.toString(),
});
query CreateUnwrapAssetsFromCharacterTransactions($characterAddresses: [String!]!, $project: String!, $characterModel: String!, $wallet: String!) {
createUnwrapAssetsFromCharacterTransactions(characterAddresses: $characterAddresses, project: $project, characterModel: $characterModel, wallet: $wallet) {
transactions
lastValidBlockHeight
blockhash
}
}
Provide the accompanying data like this:
{
"characterAddresses": [], // Array of character addresses as a string
"project": "pubkey", // Project public key as a string
"characterModel": "pubkey", // Character model public key as a string
"wallet": "pubkey" // User's wallet public key as a string
}
var unwrapAssetsFromCharacterTransaction = new CreateUnwrapAssetsFromCharacterTransactionsParams
{
CharacterAddresses = new List<string>
{
// Array of character addresses as a string
},
CharacterModel = characterModelAddress.ToString(),
Project = projectAddress.ToString(),
Wallet = userPublicKey.ToString(),
LibreplexDeployment = libreplexDeploymentAddress.ToString() // Optional, Libreplex deployment public key as a string
};
// Execute the transaction
await Client.CreateUnwrapAssetsFromCharacterTransactions(unwrapAssetsFromCharacterTransaction);