| Crates.io | carbon-player-profile-decoder |
| lib.rs | carbon-player-profile-decoder |
| version | 0.12.1 |
| created_at | 2025-10-22 16:56:20.946063+00 |
| updated_at | 2026-01-21 23:32:23.667192+00 |
| description | Rust decoder for Star Atlas Player Profile program on Solana |
| homepage | https://github.com/staratlasmeta/star-atlas-decoders |
| repository | https://github.com/staratlasmeta/star-atlas-decoders |
| max_upload_size | |
| id | 1895950 |
| size | 189,453 |
Rust decoder for the Star Atlas Player Profile program on Solana, generated using Carbon CLI.
pprofELXjL5Kck7Jn5hCpwAL82DpTkSYBENzahVtbc9Add this crate to your Cargo.toml:
[dependencies]
carbon-player-profile-decoder = "0.12.0"
use carbon_player_profile_decoder::{PlayerProfileDecoder, PlayerProfileAccount};
use carbon_core::account::AccountDecoder;
let decoder = PlayerProfileDecoder;
let decoded_account = decoder.decode_account(&account);
if let Some(decoded) = decoded_account {
match decoded.data {
PlayerProfileAccount::Profile(profile) => {
println!("Profile has {} keys", profile.profile_keys.len());
for key in &profile.profile_keys {
println!(" Key: {}, Scope: {}", key.key, key.scope);
}
}
PlayerProfileAccount::PlayerName(player_name) => {
let name_str = String::from_utf8_lossy(&player_name.name);
println!("Player Name: {}", name_str);
}
PlayerProfileAccount::Role(role) => {
println!("Role has {} members", role.members.len());
for member in &role.members {
println!(" Member: {}", member.key);
}
}
PlayerProfileAccount::ProfileRoleMembership(membership) => {
println!("Profile has {} role memberships", membership.memberships.len());
}
}
}
The decoder supports parsing all Player Profile instructions with full account resolution:
use carbon_player_profile_decoder::{PlayerProfileDecoder, PlayerProfileInstruction};
use carbon_core::instruction::InstructionDecoder;
let decoder = PlayerProfileDecoder;
let decoded_ix = decoder.decode_instruction(&instruction);
if let Some(decoded) = decoded_ix {
match decoded.data {
PlayerProfileInstruction::AddKeys(add_keys) => {
println!("Adding {} keys to profile", add_keys.keys_to_add.len());
// Access the instruction data (permissions)
for (i, key_input) in add_keys.keys_to_add.iter().enumerate() {
println!(" Key {}: scope={}, expire={}",
i, key_input.scope, key_input.expire_time);
}
// Access the actual account pubkeys being added
for (i, pubkey) in decoded.accounts.keys_to_add_accounts.iter().enumerate() {
println!(" Account {}: {}", i, pubkey);
}
}
PlayerProfileInstruction::CreateProfile(create_profile) => {
println!("Creating profile with {} keys", create_profile.key_permissions.len());
println!("Key threshold: {}", create_profile.key_threshold);
// Access the initial key account pubkeys
for pubkey in &decoded.accounts.init_keys_accounts {
println!(" Init key: {}", pubkey);
}
}
_ => {
// Handle other instructions
}
}
}
Note: The AddKeys and CreateProfile instructions include both:
keys_to_add, key_permissions) - Contains permission scopes and metadatakeys_to_add_accounts, init_keys_accounts) - Contains the actual pubkeys of the keys being addedThe decoder includes ergonomic permission handling with bitflags:
use carbon_player_profile_decoder::{ProfileKey, ProfilePermissions};
// Check if a key has specific permissions
let key: ProfileKey = /* ... */;
if key.is_auth() {
println!("This is an auth key");
}
if key.has_permission(ProfilePermissions::ADD_KEYS) {
println!("This key can add other keys");
}
// Check if a key has expired
let current_time = /* current unix timestamp */;
if key.is_expired(current_time) {
println!("This key has expired");
}
// Get permission flags
let flags = key.permissions_flags();
if flags.contains(ProfilePermissions::CREATE_ROLE | ProfilePermissions::REMOVE_ROLE) {
println!("This key can manage roles");
}
This decoder supports all Player Profile account types:
Profile - Player profile with keys and metadataPlayerName - Player name registrationRole - Role definition with permissionsProfileRoleMembership - Membership relationship between profiles and rolesAll account types include dynamically-sized fields deserialized from RemainingData:
profile_keys: Vec<ProfileKey> - List of all keys associated with this profile
name: Vec<u8> - UTF-8 encoded player name bytes
String::from_utf8_lossy(&player_name.name)members: Vec<RoleMembership> - List of all members in this role
memberships: Vec<RoleMembership> - List of all roles this profile belongs to
The ProfilePermissions bitflags type includes:
AUTH - Auth key with full profile controlADD_KEYS - Can add non-auth keysREMOVE_KEYS - Can remove non-auth keysCHANGE_NAME - Can change player nameCREATE_ROLE - Can create new rolesREMOVE_ROLE - Can remove rolesSET_AUTHORIZER - Can set role authorizerJOIN_ROLE - Can add profile to a roleLEAVE_ROLE - Can remove profile from a roleTOGGLE_ACCEPTING_NEW_MEMBERS - Can toggle accepting new membersADD_MEMBER - Can add members to rolesREMOVE_MEMBER - Can remove members from rolesDRAIN_SOL_VAULT - Can withdraw from SOL vault (scope-agnostic)Full documentation is available at docs.rs.
See the main repository for build instructions and contribution guidelines.
Licensed under the Apache-2.0 license.