carbon-player-profile-decoder 0.12.0

Rust decoder for Star Atlas Player Profile program on Solana
Documentation

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.