ton_lib 0.0.38

A collection of types and utilities for interacting with the TON network
use crate::block_tlb::TVMStack;
use crate::emulators::emul_utils::require_field;
use crate::error::TLError;
use base64::prelude::BASE64_STANDARD;
use base64::Engine;
use serde::{Deserialize, Serialize};
use ton_lib_core::traits::tlb::TLB;

#[derive(Debug, Clone)]
pub struct TVMGetMethodSuccess {
    pub vm_exit_code: i32,
    pub vm_log: Option<String>,
    pub stack_boc_base64: String,
    pub gas_used: i32,
    pub raw_response: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct TVMGetMethodResponse {
    pub success: bool,
    pub vm_exit_code: Option<i32>,
    pub vm_log: Option<String>,
    pub stack: Option<String>,
    pub gas_used: Option<String>,
    pub missing_library: Option<String>,
    pub error: Option<String>,
    #[serde(skip)]
    pub raw_response: String,
}

impl TVMGetMethodResponse {
    pub fn from_json(json: String) -> Result<Self, TLError> {
        let mut value: Self = serde_json::from_str(&json)?;
        value.raw_response = json;
        Ok(value)
    }

    pub fn into_success(self) -> Result<TVMGetMethodSuccess, TLError> {
        if !self.success {
            return Err(TLError::EmulatorEmulationError {
                vm_exit_code: self.vm_exit_code,
                response_raw: self.raw_response,
            });
        }
        let vm_exit_code = require_field(self.vm_exit_code, "vm_exit_code", &self.raw_response)?;
        if vm_exit_code != 0 && vm_exit_code != 1 {
            return Err(TLError::EmulatorEmulationError {
                vm_exit_code: self.vm_exit_code,
                response_raw: self.raw_response,
            });
        }

        let vm_log = self.vm_log;
        let stack_boc_base64 = require_field(self.stack, "stack", &self.raw_response)?;
        let gas_used = require_field(self.gas_used, "gas_used", &self.raw_response)?.parse::<i32>()?;

        Ok(TVMGetMethodSuccess {
            vm_log,
            vm_exit_code,
            stack_boc_base64,
            gas_used,
            raw_response: self.raw_response,
        })
    }
}

impl TVMGetMethodSuccess {
    pub fn stack_parsed(&self) -> Result<TVMStack, TLError> { Ok(TVMStack::from_boc_base64(&self.stack_boc_base64)?) }

    pub fn stack_boc(&self) -> Result<Vec<u8>, TLError> {
        Ok(BASE64_STANDARD.decode(self.stack_boc_base64.as_bytes())?)
    }

    pub fn exit_success(&self) -> bool { self.vm_exit_code == 0 || self.vm_exit_code == 1 }
}

#[derive(Debug)]
pub struct TVMSendMsgSuccess {
    pub new_code_boc_base64: Option<String>,
    pub new_data_boc_base64: Option<String>,
    pub accepted: bool,
    pub vm_exit_code: i32,
    pub vm_log: String,
    pub missing_library: Option<String>,
    pub gas_used: i32,
    pub actions_boc_base64: Option<String>,
    pub raw_response: String,
}

impl TVMSendMsgSuccess {
    pub fn exit_success(&self) -> bool { self.vm_exit_code == 0 || self.vm_exit_code == 1 }
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct TVMSendMsgResponse {
    pub success: bool,
    pub new_code_boc_base64: Option<String>,
    pub new_data_boc_base64: Option<String>,
    pub accepted: Option<bool>,
    pub vm_exit_code: Option<i32>,
    pub vm_log: Option<String>,
    pub missing_library: Option<String>,
    pub gas_used: Option<String>,
    pub actions: Option<String>,
    pub error: Option<String>,
    #[serde(skip)]
    pub raw_response: String,
}

impl TVMSendMsgResponse {
    pub fn from_json(json: String) -> Result<Self, TLError> {
        let mut value: Self = serde_json::from_str(&json)?;
        value.raw_response = json;
        Ok(value)
    }

    pub fn into_success(self) -> Result<TVMSendMsgSuccess, TLError> {
        if !self.success {
            return Err(TLError::EmulatorEmulationError {
                vm_exit_code: self.vm_exit_code,
                response_raw: self.raw_response,
            });
        }

        let accepted = require_field(self.accepted, "accepted", &self.raw_response)?;
        let vm_log = require_field(self.vm_log, "vm_log", &self.raw_response)?;
        let vm_exit_code = require_field(self.vm_exit_code, "vm_exit_code", &self.raw_response)?;
        let missing_library = self.missing_library;
        let gas_used = require_field(self.gas_used, "gas_used", &self.raw_response)?.parse::<i32>()?;
        let actions_boc_base64 = self.actions;
        Ok(TVMSendMsgSuccess {
            new_code_boc_base64: self.new_code_boc_base64,
            new_data_boc_base64: self.new_data_boc_base64,
            accepted,
            vm_exit_code,
            vm_log,
            missing_library,
            gas_used,
            actions_boc_base64,
            raw_response: self.raw_response,
        })
    }
}