carbon-points-store-decoder 0.12.0

Rust decoder for Star Atlas Points Store program on Solana
Documentation

Carbon Points Store Decoder

Rust decoder for the Star Atlas Points Store program on Solana, generated using Carbon CLI.

Program Information

  • Program ID: PsToRxhEPScGt1Bxpm7zNDRzaMk31t8Aox7fyewoVse
  • Network: Solana Mainnet
  • Description: Star Atlas Points Store program for managing token purchases with points and epoch-based token redemptions. Enables players to spend points to buy tokens directly or participate in time-locked redemption pools with dynamic pricing based on participation.

Features

  • Decodes all Points Store account types
  • Full instruction parsing support
  • Integration with Carbon indexing framework
  • Support for direct token purchases and epoch-based redemptions
  • Faction-based redemption configurations

Usage

Add this crate to your Cargo.toml:

[dependencies]
carbon-points-store-decoder = "0.12.0"

Decoding Accounts

use carbon_points_store_decoder::{PointsStoreDecoder, PointsStoreAccount};
use carbon_core::account::AccountDecoder;

let decoder = PointsStoreDecoder;
let decoded_account = decoder.decode_account(&account);

if let Some(decoded) = decoded_account {
    match decoded.data {
        PointsStoreAccount::PointsStore(store) => {
            println!("Points Store: {:?}", store);
            println!("Point Category: {}", store.point_category);
            println!("Profile: {}", store.profile);
            println!("Bank: {}", store.bank);
            println!("Price (points per token): {}", store.price);
            println!("Signer Bump: {}", store.signer_bump);
        }
        PointsStoreAccount::RedemptionConfig(config) => {
            println!("Redemption Config: {:?}", config);
            println!("Point Category: {}", config.point_category);
            println!("Profile: {}", config.profile);
            println!("Faction: {}", config.faction);
            println!("Bank: {}", config.bank);
            println!("Allow Only Current Epoch: {}", config.allow_only_current_epoch != 0);

            // Access the redemption_epochs array (deserialized from remaining data)
            println!("Number of redemption epochs: {}", config.redemption_epochs.len());
            for epoch in &config.redemption_epochs {
                println!("  Day {}: {} total points, {} total tokens",
                         epoch.day_index, epoch.total_points, epoch.total_tokens);
                println!("    Redeemed: {} points, {} tokens",
                         epoch.redeemed_points, epoch.redeemed_tokens);
                if epoch.total_points > 0 {
                    let tokens_remaining = epoch.total_tokens - epoch.redeemed_tokens;
                    println!("    Tokens remaining: {}", tokens_remaining);
                }
            }
        }
        PointsStoreAccount::UserRedemption(redemption) => {
            println!("User Redemption: {:?}", redemption);
            println!("Profile: {}", redemption.profile);
            println!("Point Category: {}", redemption.point_category);
            println!("User Points Account: {}", redemption.user_points_account);
            println!("Config: {}", redemption.config);
            println!("Points: {}", redemption.points);
            println!("Day Index: {}", redemption.day_index);
        }
    }
}

Working with Faction Values

The RedemptionConfig.faction field is stored as a u8. Map values to factions:

// Faction values (from profile-faction program)
const FACTION_UNALIGNED: u8 = 0;
const FACTION_MUD: u8 = 1;
const FACTION_ONI: u8 = 2;
const FACTION_USTUR: u8 = 3;

let faction_name = match config.faction {
    0 => "Unaligned",
    1 => "MUD",
    2 => "ONI",
    3 => "Ustur",
    _ => "Unknown",
};

println!("Redemption config is for faction: {}", faction_name);

Working with Boolean Flags

The Points Store program uses u8 fields for boolean flags. Check them like this:

// Check if redemptions are limited to current epoch only
if config.allow_only_current_epoch != 0 {
    println!("Only the current epoch can be redeemed");
} else {
    println!("Past epochs can also be redeemed");
}

Account Types

This decoder supports all Points Store account types:

  • PointsStore - A store where tokens can be purchased directly with points at a fixed price

    • Stores the point category, managing profile, token bank, and price per token
    • Includes a signer bump for PDA-based token transfers
    • Simple direct exchange: spend X points, receive Y tokens
  • RedemptionConfig - Configuration for epoch-based token redemptions

    • Enables time-locked redemption pools where users contribute points
    • Tokens are distributed proportionally based on each user's contribution
    • Faction-specific configurations allow different redemption rules per faction
    • Includes fully deserialized redemption_epochs array from remaining data (each epoch tracks total/redeemed points and tokens for a specific day)
    • Can restrict redemptions to only the current epoch
  • UserRedemption - Tracks a user's points contribution for a specific redemption epoch

    • Links to the user's profile and points account
    • Stores the points submitted for redemption
    • Tied to a specific day index (24-hour epoch)
    • Used to calculate proportional token distribution when claiming

Store vs Redemption

The Points Store program provides two mechanisms for exchanging points for tokens:

Direct Store Purchase

  • Fixed pricing: Set price per token
  • Immediate exchange: Spend points, receive tokens instantly
  • Simple model: Like buying items from a store

Epoch-Based Redemption

  • Pool-based: Users contribute points to a daily pool
  • Proportional distribution: Tokens distributed based on contribution percentage
  • Time-locked: Must wait for epoch to complete
  • Dynamic pricing: Effective rate depends on total participation
  • Faction-specific: Different configs for different factions

Example: If 1000 tokens are available for an epoch, and you contributed 100 points out of a total 1000 points submitted, you can claim 100 tokens (10% of the pool).

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.