mirror of
https://github.com/d0zingcat/ore.git
synced 2026-05-13 15:09:57 +00:00
cli
This commit is contained in:
5
Cargo.lock
generated
5
Cargo.lock
generated
@@ -2510,15 +2510,20 @@ dependencies = [
|
|||||||
name = "ore-cli"
|
name = "ore-cli"
|
||||||
version = "3.7.0"
|
version = "3.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bincode",
|
"bincode",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"ore-api 3.7.0",
|
"ore-api 3.7.0",
|
||||||
|
"ore-boost-api",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"solana-account-decoder",
|
||||||
"solana-client",
|
"solana-client",
|
||||||
"solana-program",
|
"solana-program",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"spl-associated-token-account",
|
"spl-associated-token-account",
|
||||||
|
"spl-token 4.0.2",
|
||||||
|
"steel",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ readme = "./README.md"
|
|||||||
keywords = ["solana", "crypto", "mining"]
|
keywords = ["solana", "crypto", "mining"]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
|
anyhow = "1.0"
|
||||||
array-const-fn-init = "0.1.1"
|
array-const-fn-init = "0.1.1"
|
||||||
bincode = "1.3.3"
|
bincode = "1.3.3"
|
||||||
bytemuck = "1.14.3"
|
bytemuck = "1.14.3"
|
||||||
@@ -25,6 +26,7 @@ mpl-token-metadata = "5.1"
|
|||||||
num_enum = "0.7.2"
|
num_enum = "0.7.2"
|
||||||
ore-api = { path = "api" }
|
ore-api = { path = "api" }
|
||||||
ore-boost-api = "4.0.0-alpha"
|
ore-boost-api = "4.0.0-alpha"
|
||||||
|
solana-account-decoder = "^2.1"
|
||||||
solana-program = "^2.1"
|
solana-program = "^2.1"
|
||||||
solana-client = "^2.1"
|
solana-client = "^2.1"
|
||||||
solana-sdk = "^2.1"
|
solana-sdk = "^2.1"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use crate::{
|
|||||||
pub fn bet(signer: Pubkey, mint: Pubkey, amount: u64, round: u64, seed: [u8; 32]) -> Instruction {
|
pub fn bet(signer: Pubkey, mint: Pubkey, amount: u64, round: u64, seed: [u8; 32]) -> Instruction {
|
||||||
let sender = spl_associated_token_account::get_associated_token_address(&signer, &mint);
|
let sender = spl_associated_token_account::get_associated_token_address(&signer, &mint);
|
||||||
let block = block_pda().0;
|
let block = block_pda().0;
|
||||||
let block_bets = spl_associated_token_account::get_associated_token_address(&signer, &mint);
|
let block_bets = spl_associated_token_account::get_associated_token_address(&block, &mint);
|
||||||
let wager = wager_pda(round, seed).0;
|
let wager = wager_pda(round, seed).0;
|
||||||
Instruction {
|
Instruction {
|
||||||
program_id: crate::ID,
|
program_id: crate::ID,
|
||||||
@@ -21,7 +21,7 @@ pub fn bet(signer: Pubkey, mint: Pubkey, amount: u64, round: u64, seed: [u8; 32]
|
|||||||
AccountMeta::new(block_bets, false),
|
AccountMeta::new(block_bets, false),
|
||||||
AccountMeta::new(sender, false),
|
AccountMeta::new(sender, false),
|
||||||
AccountMeta::new(wager, false),
|
AccountMeta::new(wager, false),
|
||||||
AccountMeta::new_readonly(spl_associated_token_account::ID, false),
|
AccountMeta::new_readonly(system_program::ID, false),
|
||||||
AccountMeta::new_readonly(spl_token::ID, false),
|
AccountMeta::new_readonly(spl_token::ID, false),
|
||||||
AccountMeta::new_readonly(sysvar::slot_hashes::ID, false),
|
AccountMeta::new_readonly(sysvar::slot_hashes::ID, false),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -14,13 +14,18 @@ no-entrypoint = []
|
|||||||
default = []
|
default = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow.workspace = true
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
bincode = "1.3.3"
|
bincode = "1.3.3"
|
||||||
bytemuck = { workspace = true }
|
bytemuck.workspace = true
|
||||||
ore-api = { path = "../api" }
|
ore-api = { path = "../api" }
|
||||||
|
ore-boost-api.workspace = true
|
||||||
serde_json = "1.0.140"
|
serde_json = "1.0.140"
|
||||||
solana-client = { workspace = true }
|
solana-account-decoder.workspace = true
|
||||||
solana-sdk = { workspace = true }
|
solana-client.workspace = true
|
||||||
solana-program = { workspace = true }
|
solana-sdk.workspace = true
|
||||||
|
solana-program.workspace = true
|
||||||
|
spl-token.workspace = true
|
||||||
spl-associated-token-account.workspace = true
|
spl-associated-token-account.workspace = true
|
||||||
tokio = { workspace = true }
|
steel.workspace = true
|
||||||
|
tokio.workspace = true
|
||||||
|
|||||||
357
cli/src/main.rs
357
cli/src/main.rs
@@ -1,9 +1,20 @@
|
|||||||
use solana_client::nonblocking::rpc_client::RpcClient;
|
use ore_api::{prelude::*, sdk::*};
|
||||||
|
use solana_account_decoder::UiAccountEncoding;
|
||||||
|
use solana_client::{
|
||||||
|
client_error::{reqwest::StatusCode, ClientErrorKind},
|
||||||
|
nonblocking::rpc_client::RpcClient,
|
||||||
|
rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig},
|
||||||
|
rpc_filter::{Memcmp, RpcFilterType},
|
||||||
|
};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
compute_budget::ComputeBudgetInstruction,
|
compute_budget::ComputeBudgetInstruction,
|
||||||
|
keccak::hashv,
|
||||||
|
native_token::{lamports_to_sol, sol_to_lamports},
|
||||||
|
pubkey::Pubkey,
|
||||||
signature::{read_keypair_file, Signer},
|
signature::{read_keypair_file, Signer},
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
};
|
};
|
||||||
|
use steel::{AccountDeserialize, Clock, Discriminator, Instruction};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
@@ -13,27 +24,349 @@ async fn main() {
|
|||||||
|
|
||||||
// Build transaction
|
// Build transaction
|
||||||
let rpc = RpcClient::new(std::env::var("RPC").expect("Missing RPC env var"));
|
let rpc = RpcClient::new(std::env::var("RPC").expect("Missing RPC env var"));
|
||||||
let cu_budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(1_400_000);
|
match std::env::var("COMMAND")
|
||||||
let ix = match std::env::var("COMMAND")
|
|
||||||
.expect("Missing COMMAND env var")
|
.expect("Missing COMMAND env var")
|
||||||
.as_str()
|
.as_str()
|
||||||
{
|
{
|
||||||
"initialize" => ore_api::sdk::initialize(payer.pubkey()),
|
"initialize" => {
|
||||||
// "payout" => ore_api::sdk::payout(payer.pubkey()),
|
let ix = initialize(payer.pubkey());
|
||||||
// "reset" => ore_api::sdk::reset(payer.pubkey()),
|
submit_transaction(&rpc, &payer, &[ix]).await.unwrap();
|
||||||
|
}
|
||||||
|
"payout" => {
|
||||||
|
let ix = payout(payer.pubkey(), Pubkey::new_unique(), Pubkey::new_unique());
|
||||||
|
submit_transaction(&rpc, &payer, &[ix]).await.unwrap();
|
||||||
|
}
|
||||||
|
"reset" => {
|
||||||
|
let ix = reset(payer.pubkey(), ore_boost_api::state::config_pda().0);
|
||||||
|
submit_transaction(&rpc, &payer, &[ix]).await.unwrap();
|
||||||
|
}
|
||||||
|
"block" => {
|
||||||
|
let block = get_block(&rpc).await.unwrap();
|
||||||
|
println!("Block: {:?}", block);
|
||||||
|
}
|
||||||
|
"crank" => {
|
||||||
|
crank(&rpc, &payer).await.unwrap();
|
||||||
|
}
|
||||||
|
"bet" => {
|
||||||
|
bet(&rpc, &payer, sol_to_lamports(1.0)).await.unwrap();
|
||||||
|
}
|
||||||
|
"close" => {
|
||||||
|
close_all_wagers(&rpc, &payer).await.unwrap();
|
||||||
|
}
|
||||||
|
"wagers" => {
|
||||||
|
let wagers = get_block_wagers(&rpc).await.unwrap();
|
||||||
|
println!("Wagers: {:?}", wagers);
|
||||||
|
}
|
||||||
_ => panic!("Invalid command"),
|
_ => panic!("Invalid command"),
|
||||||
};
|
};
|
||||||
let blockhash = rpc.get_latest_blockhash().await.unwrap();
|
}
|
||||||
|
|
||||||
|
async fn crank(
|
||||||
|
rpc: &RpcClient,
|
||||||
|
payer: &solana_sdk::signer::keypair::Keypair,
|
||||||
|
) -> Result<(), solana_client::client_error::ClientError> {
|
||||||
|
loop {
|
||||||
|
let block = get_block(rpc).await?;
|
||||||
|
let clock = get_clock(rpc).await?;
|
||||||
|
|
||||||
|
if clock.slot >= block.ends_at {
|
||||||
|
// Time to payout and reset
|
||||||
|
let payout_ix = build_payout_ix(rpc, payer).await?;
|
||||||
|
let reset_ix = reset(payer.pubkey(), ore_boost_api::state::config_pda().0);
|
||||||
|
submit_transaction(rpc, &payer, &[payout_ix, reset_ix]).await?;
|
||||||
|
println!("Submitted payout and reset transaction");
|
||||||
|
} else {
|
||||||
|
// Calculate and print time remaining
|
||||||
|
let slots_remaining = block.ends_at.saturating_sub(clock.slot);
|
||||||
|
let seconds_remaining = (slots_remaining as f64) * 0.4;
|
||||||
|
println!(
|
||||||
|
"Time until payout: {:.1} seconds ({} slots) – {} wagers – {} SOL",
|
||||||
|
seconds_remaining,
|
||||||
|
slots_remaining,
|
||||||
|
block.bet_count,
|
||||||
|
lamports_to_sol(block.total_bets)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait 3 seconds before next check
|
||||||
|
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn bet(
|
||||||
|
rpc: &RpcClient,
|
||||||
|
payer: &solana_sdk::signer::keypair::Keypair,
|
||||||
|
amount: u64,
|
||||||
|
) -> Result<(), solana_client::client_error::ClientError> {
|
||||||
|
// Get current block to get round number
|
||||||
|
let block = get_block(rpc).await?;
|
||||||
|
|
||||||
|
// Create WSOL ATA if it doesn't exist
|
||||||
|
let wsol_ata = spl_associated_token_account::get_associated_token_address(
|
||||||
|
&payer.pubkey(),
|
||||||
|
&spl_token::native_mint::ID,
|
||||||
|
);
|
||||||
|
let create_ata_ix = spl_associated_token_account::instruction::create_associated_token_account(
|
||||||
|
&payer.pubkey(),
|
||||||
|
&payer.pubkey(),
|
||||||
|
&spl_token::native_mint::ID,
|
||||||
|
&spl_token::ID,
|
||||||
|
);
|
||||||
|
let mut ixs = match rpc.get_account(&wsol_ata).await {
|
||||||
|
Ok(_) => vec![],
|
||||||
|
Err(_) => vec![create_ata_ix],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wrap SOL
|
||||||
|
let wrap_ix = solana_sdk::system_instruction::transfer(
|
||||||
|
&payer.pubkey(),
|
||||||
|
&spl_associated_token_account::get_associated_token_address(
|
||||||
|
&payer.pubkey(),
|
||||||
|
&spl_token::native_mint::ID,
|
||||||
|
),
|
||||||
|
amount,
|
||||||
|
);
|
||||||
|
let sync_native_ix = spl_token::instruction::sync_native(
|
||||||
|
&spl_token::ID,
|
||||||
|
&spl_associated_token_account::get_associated_token_address(
|
||||||
|
&payer.pubkey(),
|
||||||
|
&spl_token::native_mint::ID,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Build bet instruction
|
||||||
|
let seed = generate_seed(&payer, &block);
|
||||||
|
println!("Seed: {:?}", seed);
|
||||||
|
let ix = ore_api::sdk::bet(
|
||||||
|
payer.pubkey(),
|
||||||
|
spl_token::native_mint::ID,
|
||||||
|
amount,
|
||||||
|
block.current_round,
|
||||||
|
seed,
|
||||||
|
);
|
||||||
|
ixs.push(wrap_ix);
|
||||||
|
ixs.push(sync_native_ix);
|
||||||
|
ixs.push(ix);
|
||||||
|
|
||||||
|
// Submit transaction
|
||||||
|
submit_transaction(rpc, payer, &ixs).await?;
|
||||||
|
println!("Placed bet of {} lamports", amount);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn build_payout_ix(
|
||||||
|
rpc: &RpcClient,
|
||||||
|
payer: &solana_sdk::signer::keypair::Keypair,
|
||||||
|
) -> Result<Instruction, solana_client::client_error::ClientError> {
|
||||||
|
let block = get_block(rpc).await?;
|
||||||
|
let wagers = get_block_wagers(rpc).await?;
|
||||||
|
|
||||||
|
// Return early if no wagers
|
||||||
|
if block.total_bets == 0 {
|
||||||
|
return Ok(payout(
|
||||||
|
payer.pubkey(),
|
||||||
|
Pubkey::new_unique(),
|
||||||
|
Pubkey::new_unique(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get blockhash
|
||||||
|
let solana_block = rpc.get_block(block.ends_at).await?;
|
||||||
|
let blockhash = solana_block.blockhash;
|
||||||
|
let noise = hashv(&[&block.noise, blockhash.as_ref()]).to_bytes();
|
||||||
|
|
||||||
|
// Calculate the random number.
|
||||||
|
let x = u64::from_le_bytes(noise[0..8].try_into().unwrap());
|
||||||
|
let y = u64::from_le_bytes(noise[8..16].try_into().unwrap());
|
||||||
|
let z = u64::from_le_bytes(noise[16..24].try_into().unwrap());
|
||||||
|
let w = u64::from_le_bytes(noise[24..32].try_into().unwrap());
|
||||||
|
let roll = (x ^ y ^ z ^ w) % block.total_bets;
|
||||||
|
|
||||||
|
// Find the winning wager
|
||||||
|
let mut winner = None;
|
||||||
|
for (pubkey, wager) in wagers {
|
||||||
|
if roll >= wager.cumulative_bets && roll < wager.cumulative_bets + wager.amount {
|
||||||
|
println!("Roll: {}, Winner: {:?}", roll, pubkey);
|
||||||
|
winner = Some((pubkey, wager));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build payout instruction
|
||||||
|
let ix = if let Some((pubkey, wager)) = winner {
|
||||||
|
payout(
|
||||||
|
payer.pubkey(),
|
||||||
|
pubkey,
|
||||||
|
spl_associated_token_account::get_associated_token_address(
|
||||||
|
&wager.authority,
|
||||||
|
&spl_token::native_mint::ID,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
payout(payer.pubkey(), Pubkey::new_unique(), Pubkey::new_unique())
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(ix)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn close_all_wagers(
|
||||||
|
rpc: &RpcClient,
|
||||||
|
payer: &solana_sdk::signer::keypair::Keypair,
|
||||||
|
) -> Result<(), solana_client::client_error::ClientError> {
|
||||||
|
let block = get_block(rpc).await?;
|
||||||
|
let wagers = get_my_wagers(rpc, payer).await?;
|
||||||
|
let mut ixs = vec![];
|
||||||
|
for (pubkey, wager) in wagers {
|
||||||
|
if wager.round != block.current_round {
|
||||||
|
let ix = ore_api::sdk::close(payer.pubkey(), pubkey);
|
||||||
|
ixs.push(ix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
submit_transaction(rpc, payer, &ixs).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_block(rpc: &RpcClient) -> Result<Block, solana_client::client_error::ClientError> {
|
||||||
|
let block_pda = ore_api::state::block_pda();
|
||||||
|
let account = rpc.get_account(&block_pda.0).await?;
|
||||||
|
let block = Block::try_from_bytes(&account.data).unwrap();
|
||||||
|
Ok(*block)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_clock(rpc: &RpcClient) -> Result<Clock, solana_client::client_error::ClientError> {
|
||||||
|
let data = rpc
|
||||||
|
.get_account_data(&solana_sdk::sysvar::clock::ID)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let clock = bincode::deserialize::<Clock>(&data).unwrap();
|
||||||
|
Ok(clock)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_block_wagers(
|
||||||
|
rpc: &RpcClient,
|
||||||
|
) -> Result<Vec<(Pubkey, Wager)>, solana_client::client_error::ClientError> {
|
||||||
|
let block = get_block(rpc).await?;
|
||||||
|
let filter = RpcFilterType::Memcmp(Memcmp::new_base58_encoded(
|
||||||
|
56,
|
||||||
|
&block.current_round.to_le_bytes(),
|
||||||
|
));
|
||||||
|
let wagers = get_program_accounts::<Wager>(rpc, ore_api::ID, vec![filter])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
Ok(wagers)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_my_wagers(
|
||||||
|
rpc: &RpcClient,
|
||||||
|
payer: &solana_sdk::signer::keypair::Keypair,
|
||||||
|
) -> Result<Vec<(Pubkey, Wager)>, solana_client::client_error::ClientError> {
|
||||||
|
let filter = RpcFilterType::Memcmp(Memcmp::new_base58_encoded(
|
||||||
|
16,
|
||||||
|
&payer.pubkey().to_bytes().as_ref(),
|
||||||
|
));
|
||||||
|
let wagers = get_program_accounts::<Wager>(rpc, ore_api::ID, vec![filter])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
Ok(wagers)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_seed(payer: &solana_sdk::signer::keypair::Keypair, block: &Block) -> [u8; 32] {
|
||||||
|
solana_sdk::hash::hash(
|
||||||
|
&[
|
||||||
|
payer.pubkey().to_bytes().as_ref(),
|
||||||
|
block.current_round.to_le_bytes().as_ref(),
|
||||||
|
std::time::SystemTime::now()
|
||||||
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_nanos()
|
||||||
|
.to_le_bytes()
|
||||||
|
.as_ref(),
|
||||||
|
]
|
||||||
|
.concat(),
|
||||||
|
)
|
||||||
|
.to_bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn submit_transaction(
|
||||||
|
rpc: &RpcClient,
|
||||||
|
payer: &solana_sdk::signer::keypair::Keypair,
|
||||||
|
instructions: &[solana_sdk::instruction::Instruction],
|
||||||
|
) -> Result<solana_sdk::signature::Signature, solana_client::client_error::ClientError> {
|
||||||
|
let blockhash = rpc.get_latest_blockhash().await?;
|
||||||
|
let mut all_instructions = vec![ComputeBudgetInstruction::set_compute_unit_limit(1_400_000)];
|
||||||
|
all_instructions.extend_from_slice(instructions);
|
||||||
let transaction = Transaction::new_signed_with_payer(
|
let transaction = Transaction::new_signed_with_payer(
|
||||||
&[cu_budget_ix, ix],
|
&all_instructions,
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
&[&payer],
|
&[payer],
|
||||||
blockhash,
|
blockhash,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send transaction
|
|
||||||
match rpc.send_and_confirm_transaction(&transaction).await {
|
match rpc.send_and_confirm_transaction(&transaction).await {
|
||||||
Ok(signature) => println!("Transaction succeeded! Signature: {}", signature),
|
Ok(signature) => {
|
||||||
Err(err) => println!("Transaction failed: {}", err),
|
println!("Transaction submitted: {:?}", signature);
|
||||||
|
Ok(signature)
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("Error submitting transaction: {:?}", e);
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_program_accounts<T>(
|
||||||
|
client: &RpcClient,
|
||||||
|
program_id: Pubkey,
|
||||||
|
filters: Vec<RpcFilterType>,
|
||||||
|
) -> Result<Vec<(Pubkey, T)>, anyhow::Error>
|
||||||
|
where
|
||||||
|
T: AccountDeserialize + Discriminator + Clone,
|
||||||
|
{
|
||||||
|
let mut all_filters = vec![RpcFilterType::Memcmp(Memcmp::new_base58_encoded(
|
||||||
|
0,
|
||||||
|
&T::discriminator().to_le_bytes(),
|
||||||
|
))];
|
||||||
|
all_filters.extend(filters);
|
||||||
|
let result = client
|
||||||
|
.get_program_accounts_with_config(
|
||||||
|
&program_id,
|
||||||
|
RpcProgramAccountsConfig {
|
||||||
|
filters: Some(all_filters),
|
||||||
|
account_config: RpcAccountInfoConfig {
|
||||||
|
encoding: Some(UiAccountEncoding::Base64),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(accounts) => {
|
||||||
|
let accounts = accounts
|
||||||
|
.into_iter()
|
||||||
|
.map(|(pubkey, account)| {
|
||||||
|
let account = T::try_from_bytes(&account.data).unwrap().clone();
|
||||||
|
(pubkey, account)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
Ok(accounts)
|
||||||
|
}
|
||||||
|
Err(err) => match err.kind {
|
||||||
|
ClientErrorKind::Reqwest(err) => {
|
||||||
|
if let Some(status_code) = err.status() {
|
||||||
|
if status_code == StatusCode::GONE {
|
||||||
|
panic!(
|
||||||
|
"\n{} Your RPC provider does not support the getProgramAccounts endpoint, needed to execute this command. Please use a different RPC provider.\n",
|
||||||
|
"ERROR"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Err(anyhow::anyhow!("Failed to get program accounts: {}", err));
|
||||||
|
}
|
||||||
|
_ => return Err(anyhow::anyhow!("Failed to get program accounts: {}", err)),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
solana-test-validator \
|
|
||||||
-r \
|
|
||||||
--bpf-program oreV2ZymfyeXgNgBdqMkumTqqAprVqgBWQfoYkrtKWQ target/deploy/ore.so \ # ORE program
|
|
||||||
--url https://api.mainnet-beta.solana.com \ # Set copy of mainnet
|
|
||||||
--clone-upgradeable-program BoostzzkNfCA9D1qNuN5xZxB5ErbK4zQuBeTHGDpXT1 \ # Boost program
|
|
||||||
--clone-upgradeable-program Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB \ # Meteora pools program
|
|
||||||
--clone-upgradeable-program 24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi \ # Meteora vault program
|
|
||||||
--clone 2G3WKgP9Eemzgbzk5B4w2JSAizjWfEmEwa4JMfzLyXzM \ # ORE config
|
|
||||||
--clone Dh5ZkjGD8EVujR7C8mxMyYaE2LRVarJ9W6bMofTgNJFP \ # Treasury
|
|
||||||
--clone HqPcY2CUB4FL5EAGWN1yZkS6DHYUoMsnjoSpdGqV8wPC \ # Treasury tokens
|
|
||||||
--clone oreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhwyK9jSybcp \ # ORE mint
|
|
||||||
--clone DvYP7L1dH6vK4CbEKtQehP9cSZC5qXFP53NQi5THt5U5 \ # Boost proof
|
|
||||||
--clone FQpx4mmybtZSwv8G5QwfyXWYjRt9nkqiw3sAsKGiUpCG \ # Boost config
|
|
||||||
--clone GgaDTFbqdgjoZz3FP7zrtofGwnRS4E6MCzmmD5Ni1Mxj \ # ORE-SOL pool
|
|
||||||
--clone 3s6ki6dQSM8FuqWiPsnGkgVsAEo8BTAfUR1Vvt1TPiJN \ # A vault
|
|
||||||
--clone FERjPVNEa7Udq8CEv68h6tPL46Tq7ieE49HrE2wea3XT \ # B vault
|
|
||||||
--clone BtJuiRG44vew5nYBVeUhuBawPTZLyYYxdzTYzerkfnto \ # A token vault
|
|
||||||
--clone HZeLxbZ9uHtSpwZC3LBr4Nubd14iHwz7bRSghRZf5VCG \ # B token vault
|
|
||||||
--clone 6Av9sdKvnjwoDHVnhEiz6JEq8e6SGzmhCsCncT2WJ7nN \ # A vault LP mint
|
|
||||||
--clone FZN7QZ8ZUUAxMPfxYEYkH3cXUASzH8EqA6B4tyCL8f1j \ # B vault LP mint
|
|
||||||
--clone 2k7V1NtM1krwh1sdt5wWqBRcvNQ5jzxj3J2rV78zdTsL \ # A vault LP
|
|
||||||
--clone CFATQFgkKXJyU3MdCNvQqN79qorNSMJFF8jrF66a7r6i \ # B vault LP
|
|
||||||
--clone 3WYz5TC8X4FLvwWQ2QvSfXuZHXjqvsdymKwmMFkgCgVs \ # Protocol token fee A
|
|
||||||
--clone 6kzYo2LMo2q2bkLAD8ienoG5NC1MkNXNTfm8sdyHuX3h # Protocol token fee B
|
|
||||||
|
|
||||||
20
localnet.sh
20
localnet.sh
@@ -1,3 +1,23 @@
|
|||||||
|
# BoostzzkNfCA9D1qNuN5xZxB5ErbK4zQuBeTHGDpXT1 - Boost program
|
||||||
|
# Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB - Meteora pools program
|
||||||
|
# 24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi - Meteora vault program
|
||||||
|
# 2G3WKgP9Eemzgbzk5B4w2JSAizjWfEmEwa4JMfzLyXzM - ORE config
|
||||||
|
# Dh5ZkjGD8EVujR7C8mxMyYaE2LRVarJ9W6bMofTgNJFP - Treasury
|
||||||
|
# HqPcY2CUB4FL5EAGWN1yZkS6DHYUoMsnjoSpdGqV8wPC - Treasury tokens
|
||||||
|
# oreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhwyK9jSybcp - ORE mint
|
||||||
|
# DvYP7L1dH6vK4CbEKtQehP9cSZC5qXFP53NQi5THt5U5 - Boost proof
|
||||||
|
# FQpx4mmybtZSwv8G5QwfyXWYjRt9nkqiw3sAsKGiUpCG - Boost config
|
||||||
|
# GgaDTFbqdgjoZz3FP7zrtofGwnRS4E6MCzmmD5Ni1Mxj - ORE-SOL pool
|
||||||
|
# 3s6ki6dQSM8FuqWiPsnGkgVsAEo8BTAfUR1Vvt1TPiJN - A vault
|
||||||
|
# FERjPVNEa7Udq8CEv68h6tPL46Tq7ieE49HrE2wea3XT - B vault
|
||||||
|
# BtJuiRG44vew5nYBVeUhuBawPTZLyYYxdzTYzerkfnto - A token vault
|
||||||
|
# HZeLxbZ9uHtSpwZC3LBr4Nubd14iHwz7bRSghRZf5VCG - B token vault
|
||||||
|
# 6Av9sdKvnjwoDHVnhEiz6JEq8e6SGzmhCsCncT2WJ7nN - A vault LP mint
|
||||||
|
# FZN7QZ8ZUUAxMPfxYEYkH3cXUASzH8EqA6B4tyCL8f1j - B vault LP mint
|
||||||
|
# 2k7V1NtM1krwh1sdt5wWqBRcvNQ5jzxj3J2rV78zdTsL - A vault LP
|
||||||
|
# CFATQFgkKXJyU3MdCNvQqN79qorNSMJFF8jrF66a7r6i - B vault LP
|
||||||
|
# 3WYz5TC8X4FLvwWQ2QvSfXuZHXjqvsdymKwmMFkgCgVs - Protocol token fee A
|
||||||
|
# 6kzYo2LMo2q2bkLAD8ienoG5NC1MkNXNTfm8sdyHuX3h - Protocol token fee B
|
||||||
solana-test-validator \
|
solana-test-validator \
|
||||||
-r \
|
-r \
|
||||||
--bpf-program oreV2ZymfyeXgNgBdqMkumTqqAprVqgBWQfoYkrtKWQ target/deploy/ore.so \
|
--bpf-program oreV2ZymfyeXgNgBdqMkumTqqAprVqgBWQfoYkrtKWQ target/deploy/ore.so \
|
||||||
|
|||||||
@@ -21,8 +21,12 @@ pub fn process_bet(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult {
|
|||||||
.as_account_mut::<Block>(&ore_api::ID)?
|
.as_account_mut::<Block>(&ore_api::ID)?
|
||||||
.assert_mut(|b| b.ends_at > clock.slot)?
|
.assert_mut(|b| b.ends_at > clock.slot)?
|
||||||
.assert_mut(|b| b.payed_out == 0)?;
|
.assert_mut(|b| b.payed_out == 0)?;
|
||||||
block_bets_info.as_associated_token_account(block_info.key, &block.mint)?;
|
block_bets_info
|
||||||
sender_info.as_associated_token_account(signer_info.key, &block.mint)?;
|
.is_writable()?
|
||||||
|
.as_associated_token_account(block_info.key, &block.mint)?;
|
||||||
|
sender_info
|
||||||
|
.is_writable()?
|
||||||
|
.as_associated_token_account(signer_info.key, &block.mint)?;
|
||||||
wager_info.is_writable()?.is_empty()?.has_seeds(
|
wager_info.is_writable()?.is_empty()?.has_seeds(
|
||||||
&[WAGER, &block.current_round.to_le_bytes(), &seed],
|
&[WAGER, &block.current_round.to_le_bytes(), &seed],
|
||||||
&ore_api::ID,
|
&ore_api::ID,
|
||||||
@@ -37,11 +41,7 @@ pub fn process_bet(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult {
|
|||||||
&system_program,
|
&system_program,
|
||||||
&signer_info,
|
&signer_info,
|
||||||
&ore_api::ID,
|
&ore_api::ID,
|
||||||
&[
|
&[WAGER, &block.current_round.to_le_bytes(), &seed],
|
||||||
WAGER,
|
|
||||||
&block.current_round.to_le_bytes(),
|
|
||||||
&block.bet_count.to_le_bytes(),
|
|
||||||
],
|
|
||||||
)?;
|
)?;
|
||||||
let wager = wager_info.as_account_mut::<Wager>(&ore_api::ID)?;
|
let wager = wager_info.as_account_mut::<Wager>(&ore_api::ID)?;
|
||||||
wager.amount = amount;
|
wager.amount = amount;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use steel::*;
|
|||||||
pub fn process_bury(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult {
|
pub fn process_bury(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult {
|
||||||
// Load accounts.
|
// Load accounts.
|
||||||
let clock = Clock::get()?;
|
let clock = Clock::get()?;
|
||||||
let (required_accounts, meteora_accounts) = accounts.split_at(5);
|
let (required_accounts, meteora_accounts) = accounts.split_at(6);
|
||||||
let [signer_info, block_info, block_bets_info, block_ore_info, bet_mint_info, ore_mint_info] =
|
let [signer_info, block_info, block_bets_info, block_ore_info, bet_mint_info, ore_mint_info] =
|
||||||
required_accounts
|
required_accounts
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use steel::*;
|
|||||||
pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult {
|
pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult {
|
||||||
// Load accounts.
|
// Load accounts.
|
||||||
let clock = Clock::get()?;
|
let clock = Clock::get()?;
|
||||||
let (required_accounts, boost_accounts) = accounts.split_at(5);
|
let (required_accounts, boost_accounts) = accounts.split_at(6);
|
||||||
let [signer_info, block_info, mint_info, treasury_info, treasury_tokens_info, token_program] =
|
let [signer_info, block_info, mint_info, treasury_info, treasury_tokens_info, token_program] =
|
||||||
required_accounts
|
required_accounts
|
||||||
else {
|
else {
|
||||||
@@ -15,7 +15,7 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul
|
|||||||
signer_info.is_signer()?;
|
signer_info.is_signer()?;
|
||||||
let block = block_info
|
let block = block_info
|
||||||
.as_account_mut::<Block>(&ore_api::ID)?
|
.as_account_mut::<Block>(&ore_api::ID)?
|
||||||
.assert_mut(|b| b.ends_at < clock.slot)?
|
.assert_mut(|b| b.ends_at <= clock.slot)?
|
||||||
.assert_mut(|b| b.payed_out != 0)?;
|
.assert_mut(|b| b.payed_out != 0)?;
|
||||||
let mint = mint_info
|
let mint = mint_info
|
||||||
.has_address(&MINT_ADDRESS)?
|
.has_address(&MINT_ADDRESS)?
|
||||||
|
|||||||
Reference in New Issue
Block a user