use std::path::PathBuf;
use crate::error::SandboxErrorCode;
use crate::result::Result;
use crate::types::SecretKey;
use near_account_id::AccountId;
use reqwest::Url;
use tracing::info;
use near_sandbox as sandbox;
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum ValidatorKey {
HomeDir(PathBuf),
Known(AccountId, SecretKey),
}
pub struct SandboxServer {
pub(crate) validator_key: ValidatorKey,
rpc_addr: Url,
sandbox_instance: Option<near_sandbox::Sandbox>,
}
impl SandboxServer {
pub(crate) fn new(rpc_addr: String, validator_key: ValidatorKey) -> Result<Self> {
let rpc_addr = Url::parse(&rpc_addr).map_err(|e| {
SandboxErrorCode::InitFailure.full(format!("Invalid rpc_url={rpc_addr}"), e)
})?;
Ok(Self {
validator_key,
rpc_addr,
sandbox_instance: None,
})
}
#[allow(dead_code)]
pub(crate) async fn run_new() -> Result<Self> {
Self::run_new_with_version(sandbox::DEFAULT_NEAR_SANDBOX_VERSION).await
}
pub(crate) async fn run_new_with_version(version: &str) -> Result<Self> {
suppress_sandbox_logs_if_required();
let sandbox_config = near_sandbox::SandboxConfig {
additional_accounts: vec![sandbox::GenesisAccount::default_with_name(
"registrar".parse().unwrap(),
)],
..Default::default()
};
let sandbox_instance =
sandbox::Sandbox::start_sandbox_with_config_and_version(sandbox_config, version)
.await
.map_err(|e| SandboxErrorCode::RunFailure.custom(e))?;
info!(target: "workspaces", "Started up sandbox at {}", sandbox_instance.rpc_addr);
let rpc_addr: Url = sandbox_instance
.rpc_addr
.parse()
.expect("static scheme and host name with variable u16 port numbers form valid urls");
let dir = sandbox_instance.home_dir.path().to_path_buf();
Ok(Self {
validator_key: ValidatorKey::HomeDir(dir),
rpc_addr,
sandbox_instance: Some(sandbox_instance),
})
}
pub fn rpc_port(&self) -> Option<u16> {
self.rpc_addr.port()
}
pub fn rpc_addr(&self) -> String {
self.rpc_addr.to_string()
}
}
impl Drop for SandboxServer {
fn drop(&mut self) {
if self.sandbox_instance.is_some() {
info!(
target: "workspaces",
"Cleaning up sandbox"
);
}
}
}
fn suppress_sandbox_logs_if_required() {
if let Ok(val) = std::env::var("NEAR_ENABLE_SANDBOX_LOG") {
if val != "0" {
return;
}
}
std::env::set_var("NEAR_SANDBOX_LOG", "near=error,stats=error,network=error");
}