carbon-player-profile-decoder

Crates.iocarbon-player-profile-decoder
lib.rscarbon-player-profile-decoder
version0.12.1
created_at2025-10-22 16:56:20.946063+00
updated_at2026-01-21 23:32:23.667192+00
descriptionRust decoder for Star Atlas Player Profile program on Solana
homepagehttps://github.com/staratlasmeta/star-atlas-decoders
repositoryhttps://github.com/staratlasmeta/star-atlas-decoders
max_upload_size
id1895950
size189,453
Samuel Vanderwaal (samuelvanderwaal)

documentation

README

Carbon Player Profile Decoder

Rust decoder for the Star Atlas Player Profile program on Solana, generated using Carbon CLI.

Program Information

  • Program ID: pprofELXjL5Kck7Jn5hCpwAL82DpTkSYBENzahVtbc9
  • Network: Solana Mainnet
  • Description: Star Atlas Player Profile program for managing player identities, permissions, and role-based access control within the Star Atlas ecosystem.

Features

  • Decodes all Player Profile account types
  • Full instruction parsing support
  • Integration with Carbon indexing framework
  • Permission bitflags support for ergonomic permission checking
  • Helper methods for key expiration and authorization checks

Usage

Add this crate to your Cargo.toml:

[dependencies]
carbon-player-profile-decoder = "0.12.0"

Decoding Accounts

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());
        }
    }
}

Decoding Instructions

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:

  • Instruction data (keys_to_add, key_permissions) - Contains permission scopes and metadata
  • Account lists (keys_to_add_accounts, init_keys_accounts) - Contains the actual pubkeys of the keys being added

Working with Permissions

The 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");
}

Account Types

This decoder supports all Player Profile account types:

  • Profile - Player profile with keys and metadata
  • PlayerName - Player name registration
  • Role - Role definition with permissions
  • ProfileRoleMembership - Membership relationship between profiles and roles

Account Fields (RemainingData)

All account types include dynamically-sized fields deserialized from RemainingData:

Profile

  • profile_keys: Vec<ProfileKey> - List of all keys associated with this profile
    • Each key includes: public key, scope, expiration time, and permissions
    • Maximum of 65,535 keys (u16 length prefix)

PlayerName

  • name: Vec<u8> - UTF-8 encoded player name bytes
    • Variable length, stored as raw bytes without length prefix
    • Example: String::from_utf8_lossy(&player_name.name)

Role

  • members: Vec<RoleMembership> - List of all members in this role
    • Each membership includes: member key and status (Active/Inactive)
    • Maximum of 256 members (u32 length prefix, enforced by MAX_MEMBERSHIPS)

ProfileRoleMembership

  • memberships: Vec<RoleMembership> - List of all roles this profile belongs to
    • Each membership includes: role key and status (Active/Inactive)
    • Maximum of 256 memberships (u32 length prefix, enforced by MAX_MEMBERSHIPS)

Permission Flags

The ProfilePermissions bitflags type includes:

  • AUTH - Auth key with full profile control
  • ADD_KEYS - Can add non-auth keys
  • REMOVE_KEYS - Can remove non-auth keys
  • CHANGE_NAME - Can change player name
  • CREATE_ROLE - Can create new roles
  • REMOVE_ROLE - Can remove roles
  • SET_AUTHORIZER - Can set role authorizer
  • JOIN_ROLE - Can add profile to a role
  • LEAVE_ROLE - Can remove profile from a role
  • TOGGLE_ACCEPTING_NEW_MEMBERS - Can toggle accepting new members
  • ADD_MEMBER - Can add members to roles
  • REMOVE_MEMBER - Can remove members from roles
  • DRAIN_SOL_VAULT - Can withdraw from SOL vault (scope-agnostic)

Documentation

Full documentation is available at docs.rs.

Repository

See the main repository for build instructions and contribution guidelines.

License

Licensed under the Apache-2.0 license.

Commit count: 104

cargo fmt