Users and Profiles
Difference between users and profiles in Honeycomb Protocol
In the Honeycomb Protocol, users and profiles are distinct:
-
User: A person with a universal account, allowing access to any Honeycomb app. Users can link their Steam, Twitter, Discord, and Civic IDs for enhanced functionality, with Civic ID used for KYC verification.
-
Profile: Specific to each project within the ecosystem. For instance, a user needs separate profiles for a social media app and a game. The social media profile tracks posts, comments, and friends, while the game profile tracks achievements, scores, and in-game purchases. In order to create profiles, you need to create a profiles tree.
In summary, the same user can have different profiles for different apps within the Honeycomb Protocol.
Users
Before you can create a profile for your project, you need to create a user. Let's cover how you can create a user.
Creating a user
- JavaScript
- GraphQL
const {
createNewUserTransaction: txResponse // This is the transaction response, you'll need to sign and send this transaction
} = await client.createNewUserTransaction({
wallet: userPublicKey.toString(), // User's wallet public key
info: { // Optional, user's information
name: "Test User",
username: "testuser",
pfp: "https://lh3.googleusercontent.com/-Jsm7S8BHy4nOzrw2f5AryUgp9Fym2buUOkkxgNplGCddTkiKBXPLRytTMXBXwGcHuRr06EvJStmkHj-9JeTfmHsnT0prHg5Mhg",
bio: "This is a test user",
},
payer: adminPublicKey.toString(), // Optional, the transaction payer's public key
});
query CreateNewUserTransaction($wallet: String!, $info: UserInfoInput) {
createNewUserTransaction(wallet: $wallet, info: $info) {
blockhash
lastValidBlockHeight
transaction
}
}
Provide the accompanying data like this:
{
"wallet": "pubkey", // User's wallet address in string format
"info": {
"bio": "string", // User's bio
"name": "string", // User's name
"pfp": "string", // Link to user's profile picture
"username": "string" // User's username
}
}
Create user and profile
You can create a user and a profile in a single transaction. However, please do keep in mind that profiles are stored in a merkle tree, so if your project doesn't have a profiles tree, this operation won't work as intended. Please create a profiles tree before using this operation.
- JavaScript
- GraphQL
const {
createNewUserWithProfileTransaction: txResponse // This is the transaction response, you'll need to sign and send this transaction
} = await client.createNewUserWithProfileTransaction({
project: projectAddress.toString(),
wallet: userPublicKey.toString(),
payer: adminPublicKey.toString(),
profileIdentity: "main",
userInfo: { // Optional
username: "hcDev",
name: "Honeycomb Developer",
bio: "This user is created for testing purposes",
pfp: "https://lh3.googleusercontent.com/-Jsm7S8BHy4nOzrw2f5AryUgp9Fym2buUOkkxgNplGCddTkiKBXPLRytTMXBXwGcHuRr06EvJStmkHj-9JeTfmHsnT0prHg5Mhg",
},
profileInfo: { // Optional
bio: "Honeycomb Developer's profile bio",
name: "Honeycomb Developer",
pfp: "https://lh3.googleusercontent.com/-Jsm7S8BHy4nOzrw2f5AryUgp9Fym2buUOkkxgNplGCddTkiKBXPLRytTMXBXwGcHuRr06EvJStmkHj-9JeTfmHsnT0prHg5Mhg"
}
});
query CreateNewUserWithProfileTransaction($userInfo: UserInfoInput, $project: String!, $profileIdentity: String, $profileInfo: ProfileInfoInput, $wallet: String!, $payer: String) {
createNewUserWithProfileTransaction(userInfo: $userInfo, project: $project, profileIdentity: $profileIdentity, profileInfo: $profileInfo, wallet: $wallet, payer: $payer) {
blockhash
lastValidBlockHeight
transaction
}
}
Provide data like this:
{
"project": "pubkey", // Project's pubkey address in string format
"wallet": "pubkey", // User's wallet address in string format
"payer": "pubkey", // Transaction payer's wallet address in string format
"profileIdentity": "main", // Identity type of the profile, usually "main" is used, but you can use any string
"profileInfo": {
"bio": "string", // User's bio
"name": "string", // User's name
"pfp": "string", // Link to user's profile picture
},
"userInfo": {
"bio": "string", // User's bio
"name": "string", // User's name
"pfp": "string", // Link to user's profile picture
"username": "string" // User's username
},
}
Update user
The update user operation allows you to not only update a user's previously provided information, but also to get their Civic Pass information.
- JavaScript
- GraphQL
const { createUpdateUserTransaction: txResponse } =
await client.createUpdateUserTransaction(
{
payer: userPublicKey.toString(), // The public key of the user who is updating their information
populateCivic: true, // Optional, set to true if you want to populate the Civic Pass information
wallets: { // Optional, add or remove wallets from the user's Honeycomb Protocol account
add: [newPublicKey], // Optional, add any wallets to the user's Honeycomb Protocol account
remove: [oldPublicKey] // Optional, remove any wallets from the user's Honeycomb Protocol account
},
info: { // Optional, user's information
bio: "Updated user bio", // Optional, updated user bio
name: "Honeycomb Developer", // Optional, updated name
pfp: "https://lh3.googleusercontent.com/-Jsm7S8BHy4nOzrw2f5AryUgp9Fym2buUOkkxgNplGCddTkiKBXPLRytTMXBXwGcHuRr06EvJStmkHj-9JeTfmHsnT0prHg5Mhg", // Optional, updated profile picture
username: "hcDev", // Optional, updated username
}
},
{
fetchOptions: {
headers: {
authorization: `Bearer ${accessToken}`, // Required, you'll need to authenticate the user with our Edge Client and provide the resulting access token here, otherwise this operation will fail
},
},
}
);
query CreateUpdateUserTransaction($info: UserInfoInput, $payer: String, $populateCivic: Boolean, $wallets: WalletsInput) {
createUpdateUserTransaction(info: $info, payer: $payer, populateCivic: $populateCivic, wallets: $wallets) {
blockhash
lastValidBlockHeight
transaction
}
}
Provide the accompanying data like this:
{
"info": {
"bio": "string", // User's bio
"name": "string", // User's name
"pfp": "string", // Link to user's profile picture
"username": "string" // User's username
},
"payer": "pubkey", // User's public key in string format
"populateCivic": true, // Optional, set to true if you want to populate the Civic Pass information
"wallets": {
"add": ["pubkey"], // Optional, add any wallets to the user's Honeycomb Protocol account
"remove": ["pubkey"] // Optional, remove any wallets from the user's Honeycomb Protocol account
}
}
Please see this page to learn how to get an access token.
In order to access the user's updated data after this operation, you'll have to fetch the user again.
Lastly, please note that if the user hasn't done Civic Pass verification on any of their wallets, the civic
array in the fetch user response will be empty.
Find user(s)
The find user operation allows you to search for Honeycomb Protocol users by various filters, all of which are optional.
- JavaScript
- GraphQL
const usersArray = await client.findUsers({ // All filters below are optional
wallets: [], // String array of users' wallet addresses
addresses: [], // String array of Honeycomb Protocol user account addresses
ids: [], // Integer array of Honeycomb Protocol user account IDs
includeProof: true, // Optional, set to true if you want to include the proof of the user's account
usernames: [] // String array of usernames
}).then(({user}) => user); // This will be an array of users
query FindUsers($addresses: [String!], $ids: [Int!], $usernames: [String!], $wallets: [String!], $includeProof: Boolean) {
user(addresses: $addresses, ids: $ids, usernames: $usernames, wallets: $wallets, includeProof: $includeProof) {
address
id
info {
bio
name
pfp
username
}
leaf_idx
proof {
canopy_depth
leaf
leaf_index
maxDepth
node_index
proof
root
tree_id
}
socialInfo {
civic {
expiry
gatekeeperNetwork
walletIndex
}
discord
steam
twitter
}
tree_id
wallets {
shadow
wallets
}
}
}
Provide the accompanying data like this:
{
"addresses": ["pubkey"], // String array of Honeycomb Protocol user account addresses
"ids": [int], // Integer array of Honeycomb Protocol user account IDs
"usernames": ["string"], // String array of usernames
"wallets": ["pubkey"], // String array of users' wallet addresses
"includeProof": boolean // Optional, set to true if you want to include the proof of the user's account
}
Profiles
Profiles are specific to each project within the Honeycomb Protocol ecosystem. Let's cover how you can create a profile for your project.
Before you can start creating profiles for your project, you'll need to create a profiles tree. Let's cover that first.
Create a profiles tree
- JavaScript
- GraphQL
const {
createCreateProfilesTreeTransaction: txResponse // This is the transaction response, you'll need to sign and send this transaction
} = await client.createCreateProfilesTreeTransaction({
payer: adminPublicKey.toString(),
project: projectAddress.toString(),
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 profiles 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: {
// maxDepth: 20,
// maxBufferSize: 64,
// canopyDepth: 14,
// }
}
});
query CreateCreateProfilesTreeTransaction($treeConfig: TreeSetupConfig!, $project: String!, $authority: String!, $payer: String) {
createCreateProfilesTreeTransaction(treeConfig: $treeConfig, project: $project, authority: $authority, payer: $payer) {
cost
maxTreeCapacity
proofBytes
space
treeAddress
tx {
blockhash
lastValidBlockHeight
transaction
}
}
}
Provide the data like this:
{
"project": "pubkey", // Project public key as a string
"authority": "pubkey", // Authority public key as a string
"payer": "pubkey", // Payer public key as a string
"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": int // The desired number of profiles 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": int, // The depth of the canopy
// "maxBufferSize": int, // The maximum buffer size
// "maxDepth": int // The maximum depth of the tree
// }
}
}
Creating a profile
When creating a profile for an existing user, you'll have to authenticate that user and include an access token in the request. Please see this page to learn how to get an access token.
- JavaScript
- GraphQL
const {
createNewProfileTransaction: txResponse // This is the transaction response, you'll need to sign and send this transaction
} = await client.createNewProfileTransaction({
project: projectAddress.toString(), // The project's public key
payer: userPublicKey.toString(), // The transaction payer's public key, the profile will also be created for this payer
identity: "main", // Identity type in string, the value depends on the project's needs
info: { // Optional, profile information, all values in the object are optional
bio: "My name is John Doe",
name: "John Doe",
pfp: "link-to-pfp"
}
},
{
fetchOptions: {
headers: {
authorization: `Bearer ${accessToken}`, // Required, you'll need to authenticate the user with our Edge Client and provide the resulting access token here, otherwise this operation will fail
},
}
});
query CreateNewProfileQuery($project: String!, $identity: String, $info: ProfileInfoInput) {
createNewProfileTransaction(project: $project, identity: $identity, info: $info) {
blockhash
lastValidBlockHeight
transaction
}
}
Provide the accompanying data like this:
{
"project": "pubkey", // Project's pubkey address in string format
"identity": "string", // Identity type of the profile, usually "main" is used, but you can use any string
"info": {
"bio": "string", // User's bio
"name": "string", // User's name
"pfp": "string", // Link to user's profile picture
}
}
Update profile
Same as creating a profile, you'll need to authenticate the user and include an access token in the request. Please see this page to learn how to get an access token.
- JavaScript
- GraphQL
const {
createUpdateProfileTransaction: txResponse // This is the transaction response, you'll need to sign and send this transaction
} = await client.createUpdateProfileTransaction({
payer: userPublicKey.toString(),
profile: profileAddress.toString(),
info: {
bio: "This is profile of user",
name: "User",
pfp: "link-to-pfp"
},
customData: {
add: [ // Here you can add any custom data to a user's profile, the format is given below (please always use key: ["string"])
location: ["San Francisco, CA"],
website: ["https://johndoe.dev"],
github: ["https://github.com/johndoe"],
stars: ["55"]
],
remove: [ // Provide any keys for custom data you want to remove from the profile, the key-value pairs will be removed, the format is given below
"collaborations" // This will remove the key "collaborations" from the profile along with the corresponding value
]
}
},
{
fetchOptions: {
headers: {
authorization: `Bearer ${accessToken}`, // Required, you'll need to authenticate the user with our Edge Client and provide the resulting access token here, otherwise this operation will fail
},
}
});
query CreateUpdateProfileTransaction($profile: String!, $payer: String!, $info: ProfileInfoInput, $customData: CustomDataInput) {
createUpdateProfileTransaction(profile: $profile, payer: $payer, info: $info, customData: $customData) {
transaction
blockhash
lastValidBlockHeight
}
}
Provide data like this:
{
"profile": "pubkey", // Profile's pubkey address in string format
"payer": "pubkey", // Transaction payer's wallet address in string format
"info": {
"bio": "string", // Profile's bio
"name": "string", // Profile name
"pfp": "string", // Link to the profile picture
},
"customData": {
"add": { // Here you can add any custom data to a user's profile, the format is given below (please always use "key": ["string"])
"location": ["San Francisco, CA"],
"website": ["https://johndoe.dev"],
"github": ["https://github.com/johndoe"],
"stars": ["55"]
},
"remove": [ // Provide any keys for custom data you want to remove from the profile, the key-value pairs will be removed, the format is given below
"collaborations" // This will remove the key "collaborations" from the profile along with the corresponding value
]
}
}
After updating the profile, you'll need to fetch the profile again to access the updated data.
Find profile(s)
- JavaScript
- GraphQL
const profilesArray = await client.findProfiles({ // All filters below are optional
userIds: [], // Integer array of Honeycomb Protocol user account IDs
projects: [], // String array of project addresses
addresses: [], // String array of Honeycomb Protocol profile account addresses
identities: [], // String array of profile identities
includeProof: true, // Optional, set to true if you want to include the proof of the profile's account
}).then(({profile}) => profile); // This will be an array of profiles,
query FindProfiles($addresses: [String!], $identities: [String!], $includeProof: Boolean, $projects: [String!], $userIds: [Int!]) {
profile(addresses: $addresses, identities: $identities, includeProof: $includeProof, projects: $projects, userIds: $userIds) {
address
customData
identity
info {
bio
name
pfp
}
leaf_idx
platformData {
achievements
custom
xp
}
project
proof {
canopy_depth
leaf
leaf_index
maxDepth
proof
node_index
root
tree_id
}
tree_id
userId
}
}
Provide the accompanying data like this:
{
"addresses": ["pubkey"], // String array of Honeycomb Protocol profile account addresses
"identities": ["string"], // String array of profile identities
"includeProof": boolean, // Optional, set to true if you want to include the proof of the profile's account
"projects": ["pubkey"], // String array of project addresses
"userIds": [int] // Integer array of Honeycomb Protocol user account IDs
}