Skip to content

LifeOrDream/hashiden-rust-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

minebtc-sdk

Rust SDK for MineBTC, the Solana country-warfare game. It decodes live round and cycle state, derives PDAs, and builds betting, claim, stake, and marketplace transactions — straight from RPC, with no MineBTC backend, GraphQL, or socket. The low-level client is generated from the on-chain IDLs with Codama (renderRustVisitor); ergonomic wrappers sit on top.

Install

[dependencies]
minebtc-sdk = "0.1"

The crate is named minebtc-sdk; the library is imported as minebtc_sdk.

Quick start

use minebtc_sdk::{BetSelection, MinebtcClient, SendTxOptions};

let client = MinebtcClient::new("https://your-rpc-endpoint");

// Read the current round's pools.
let pools = client.reads().get_country_pools(None)?;
println!("active countries: {:?}", pools.active_faction_ids);

// Build and send a bet (signer is any solana-signer Signers, e.g. a Keypair).
let ixs = client.writes().place_bet(
    &[BetSelection { faction_id: 0, direction: 2 }], // USA, Up
    100_000,        // lamports per position
    &signer.pubkey(),
    None, None, None,
)?;
let sig = client.send(&signer.pubkey(), &ixs, &[&signer], &SendTxOptions::default())?;

Configuration

// Mainnet config (program ids, mints, collection, fee recipients,
// marketplace PDA) is pinned. Bring your own RPC URL.
let client = MinebtcClient::new("https://your-rpc-endpoint");

// Public Solana Labs endpoint — rate-limited, fine for a smoke test.
let client = MinebtcClient::public_mainnet();

// Devnet (or any non-mainnet): program ids are identical, so supply the
// chain-specific addresses via an explicit NetworkConfig.
let client = MinebtcClient::with_config("https://api.devnet.solana.com", devnet_config);
  • RPC. Bring your own URL. The public Solana Labs endpoint is available via public_mainnet() — fine for a smoke test, rate-limited for anything real.
  • Network. Only mainnet values are pinned. Program ids are identical across networks; for devnet pass a NetworkConfig with the chain-specific addresses.
  • Keypair. The SDK signs nothing on its own — write builders return unsigned Vec<Instruction>. You supply the signers (see the examples for loading one from a Solana CLI keypair).
  • Commitment is confirmed everywhere, matching the on-chain cranker.
  • Features. The fetch feature (on by default) pulls in solana-rpc-client for the read layer and client.send. Disable default features for a pure no-RPC build that only derives PDAs and builds instructions.

API reference

Reads — client.reads().*

Each returns a decoded DecodedAccount<T> (or a derived view).

Method Returns
get_global_state() GlobalGameSate — round id, duration, jackpot pot
get_global_config() GlobalConfig — fee config, tuning
get_mining() DegenBtcMining — dBTC per round, LP op count, prices
get_round(round_id) GameSession — boards, totals, result; None = current
get_country_pools(round_id) per-country×direction {points, wgtd_points, sol, active} view
get_faction_state(id) one FactionState (name-keyed PDA)
get_factions() all 12 FactionState, indexed by faction id
get_cycle_config() FactionWarConfig — war id, cutoff round, multipliers
get_cycle_state(war_id) FactionWarState — scores, round wins, MVP; None = current
get_cycle_settlement(war_id) FactionWarSettlement — final ranks
get_rankings(war_id) current standings sorted by score (the public leaderboard)
get_player(wallet) PlayerData
get_pending_claims(wallet) pending round + cycle claim counts
get_user_game_bet(wallet, round_id) UserGameBet
get_user_cycle_bets(wallet, war_id) UserFactionWarBets
get_autominer(wallet) AutominerVault
get_stake_position(w, idx, type) StakedPosition (dBTC / LP)
get_hashbeast(asset) HashBeastMetadata

Writes — client.writes().*

Each returns an unsigned Vec<Instruction> (compute-budget, ATA/WSOL pre-ix, and the program ix in order). Sign and send yourself, or pass to client.send. Vectors let you batch — e.g. several claim_round_rewards in one transaction.

Method Instruction
place_bet(bets, amount_per_bet, …) join_bets (+ WSOL unwrap)
claim_round(round_id, wallet, caller) claim_round_rewards
claim_rounds_batch(round_ids, wallet, caller) batched claim_round_rewards (1.4M CU)
claim_autominer(round_id, owner, caller) claim_autominer_rewards
claim_cycle(war_id, wallet, cranker) claim_war_rewards
stake_dbtc / unstake_dbtc stake_degenbtc / unstake_degenbtc (Token-2022)
stake_lp / unstake_lp stake_lp_tokens / unstake_lp_tokens (classic SPL)
claim_staking_rewards / withdraw_dbtc_rewards claim_staking_rewards / withdraw_dbtc_rewards
lock_for_gameplay / request_unlock / withdraw_gameplay HashBeast gameplay lock / unlock
init_player / claim_referral initialize_player / claim_referral_rewards
market_buy / market_list / market_cancel / market_update_price marketplace CPI wrappers

The builders fold in correctness work the IDL can't express, each verified against the production frontend: exact IDL account order; the required UserFactionWarBetCloseState remaining account on claims, with user_bet_rent_payer read from the on-chain close-state; CU bumps on heavy claims; mpl-core (not SPL) on HashBeast and marketplace ix; Token-2022 dBTC vs classic-SPL LP ATAs with idempotent creation; native-SOL bets that unwrap WSOL first; the optional referrer and gameplay-HashBeast accounts.

Unlike the TypeScript SDK's async builders, the Codama Rust client takes every account explicitly, so the wrappers derive every PDA for you and read the few on-chain values (current ids, home faction, close-state rent payers, listing price) needed to assemble a correct account list.

PDAs, SPL, tx

PDA helpers (derive_global_game_state, derive_faction_state, derive_game_session, derive_stake_position, …), SPL helpers (derive_ata, create_dbtc_ata_idempotent, …), and the send path (send_transaction, build_signed_transaction, clamp_priority_fee) are exported from the crate root. The raw Codama client lives under minebtc_sdk::generated for anything the wrappers don't cover.

Anchor / on-chain use

The generated client is plain Borsh + the split Solana crates, so it works in both off-chain tooling and on-chain programs. The account names and orders match the IDL exactly; the per-instruction *Cpi structs (e.g. JoinBetsCpi) are generated for CPI from another program.

Examples

In examples/. RPC and keypair come from env (RPC_URL, KEYPAIR_PATH); nothing is hardcoded.

  • read_state — connect and print global state, factions, and the current round's pools.
  • place_bet — build and send one bet from the env keypair.
  • auto_claimer — self-scan a wallet's unclaimed rounds and batch claim_round_rewards (permissionless cranker).
RPC_URL=https://your-rpc cargo run --example read_state

Contributing

The generated client under src/generated/ is committed and reproducible from the vendored IDLs — never hand-edit it; change the IDL or codegen and regenerate. When the contract changes, copy the new IDL into idl/, run the codegen, and update any wrapper whose account list or args changed.

./scripts/codegen.sh && git diff --exit-code src/generated  # no codegen drift
cargo build
cargo clippy --all-targets -- -D warnings
cargo test

CI runs the same checks.

Links

License

MIT — see LICENSE.

About

Rust SDK for Hashiden — typed Solana client for agents that play the country war. Codama client + ergonomic wrappers.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages