use crate::SbError;
use serde::Deserialize;
use envy::Error as EnvyError;
fn default_cluster() -> String {
"devnet".to_string()
}
const DEFAULT_PUBKEY: &str = "11111111111111111111111111111111";
#[derive(Clone, Debug, Default, Deserialize)]
pub struct SolanaFunctionEnvironment {
pub function_key: String,
pub payer: String,
pub verifier: String,
pub reward_receiver: String,
#[serde(default)]
pub function_data: String,
#[serde(default)]
pub verifier_enclave_signer: String,
#[serde(default)]
pub queue_authority: String,
#[serde(default)]
pub function_routine_key: String,
#[serde(default)]
pub function_routine_data: String,
#[serde(default)]
pub function_request_key: String,
#[serde(default)]
pub function_request_data: String,
#[serde(default = "default_cluster")]
pub cluster: String,
pub minimum_context_slot: Option<u64>,
}
impl SolanaFunctionEnvironment {
pub fn parse() -> Result<Self, SbError> {
match envy::from_env::<SolanaFunctionEnvironment>() {
Ok(env) => Ok(env),
Err(error) => {
match &error {
EnvyError::MissingValue(msg) =>
Err(SbError::EnvVariableMissing(msg.to_string())),
EnvyError::Custom(msg) =>
Err(
SbError::CustomMessage(
format!("failed to decode environment variables: {}", msg)
)
),
}
}
}
}
pub fn to_env(&self) -> Vec<String> {
let mut env = vec![];
env.push(format!("CLUSTER={}", self.cluster));
env.push(format!("FUNCTION_KEY={}", self.function_key));
env.push(format!("PAYER={}", self.payer));
env.push(format!("VERIFIER={}", self.verifier));
env.push(format!("REWARD_RECEIVER={}", self.reward_receiver));
if
!self.verifier_enclave_signer.is_empty() &&
&self.verifier_enclave_signer != &DEFAULT_PUBKEY.to_string()
{
env.push(format!("VERIFIER_ENCLAVE_SIGNER={}", self.verifier_enclave_signer));
}
if !self.queue_authority.is_empty() && &self.queue_authority != &DEFAULT_PUBKEY.to_string() {
env.push(format!("QUEUE_AUTHORITY={}", self.queue_authority));
}
if !self.function_data.is_empty() && !self.function_data.chars().all(|c| c == '0') {
env.push(format!("FUNCTION_DATA={}", self.function_data));
}
if
!self.function_routine_key.is_empty() &&
&self.function_routine_key != &DEFAULT_PUBKEY.to_string()
{
env.push(format!("FUNCTION_ROUTINE_KEY={}", self.function_routine_key));
}
if
!self.function_routine_data.is_empty() &&
!self.function_routine_data.chars().all(|c| c == '0')
{
env.push(format!("FUNCTION_ROUTINE_DATA={}", self.function_routine_data));
}
if
!self.function_request_key.is_empty() &&
&self.function_request_key != &DEFAULT_PUBKEY.to_string()
{
env.push(format!("FUNCTION_REQUEST_KEY={}", self.function_request_key));
}
if
!self.function_request_data.is_empty() &&
!self.function_request_data.chars().all(|c| c == '0')
{
env.push(format!("FUNCTION_REQUEST_DATA={}", self.function_request_data));
}
if let Some(minimum_context_slot) = self.minimum_context_slot {
env.push(format!("MINIMUM_CONTEXT_SLOT={}", minimum_context_slot));
}
env
}
pub fn set_env(&self) -> Result<(), SbError> {
if !self.function_key.is_empty() {
std::env::set_var("FUNCTION_KEY", self.function_key.clone());
}
if !self.payer.is_empty() {
std::env::set_var("PAYER", self.payer.clone());
}
if !self.verifier.is_empty() {
std::env::set_var("VERIFIER", self.verifier.clone());
}
if !self.reward_receiver.is_empty() {
std::env::set_var("REWARD_RECEIVER", self.reward_receiver.clone());
}
if !self.function_data.is_empty() {
std::env::set_var("FUNCTION_DATA", self.function_data.clone());
}
if !self.verifier_enclave_signer.is_empty() {
std::env::set_var("VERIFIER_ENCLAVE_SIGNER", self.verifier_enclave_signer.clone());
}
if !self.queue_authority.is_empty() {
std::env::set_var("QUEUE_AUTHORITY", self.queue_authority.clone());
}
if !self.function_routine_key.is_empty() {
std::env::set_var("FUNCTION_ROUTINE_KEY", self.function_routine_key.clone());
}
if !self.function_routine_data.is_empty() {
std::env::set_var("FUNCTION_ROUTINE_DATA", self.function_routine_data.clone());
}
if !self.function_request_key.is_empty() {
std::env::set_var("FUNCTION_REQUEST_KEY", self.function_request_key.clone());
}
if !self.function_request_data.is_empty() {
std::env::set_var("FUNCTION_REQUEST_DATA", self.function_request_data.clone());
}
if !self.cluster.is_empty() {
std::env::set_var("CLUSTER", self.cluster.clone());
} else {
std::env::set_var("CLUSTER", "devnet");
}
if let Some(minimum_context_slot) = self.minimum_context_slot {
std::env::set_var("MINIMUM_CONTEXT_SLOT", minimum_context_slot.to_string());
}
Ok(())
}
}