use casper_types::{
system::{
handle_payment, mint,
standard_payment::{AccountProvider, HandlePaymentProvider, MintProvider, StandardPayment},
},
ApiError, Key, RuntimeArgs, StoredValue, URef, U512,
};
use crate::{
core::{execution, runtime::Runtime},
storage::global_state::StateReader,
};
pub(crate) const METHOD_GET_PAYMENT_PURSE: &str = "get_payment_purse";
impl From<execution::Error> for Option<ApiError> {
fn from(exec_error: execution::Error) -> Self {
match exec_error {
execution::Error::GasLimit => Some(mint::Error::GasLimit.into()),
_ => None,
}
}
}
impl<'a, R> AccountProvider for Runtime<'a, R>
where
R: StateReader<Key, StoredValue>,
R::Error: Into<execution::Error>,
{
fn get_main_purse(&mut self) -> Result<URef, ApiError> {
self.context.get_main_purse().map_err(|exec_error| {
<Option<ApiError>>::from(exec_error).unwrap_or(ApiError::InvalidPurse)
})
}
}
impl<'a, R> MintProvider for Runtime<'a, R>
where
R: StateReader<Key, StoredValue>,
R::Error: Into<execution::Error>,
{
fn transfer_purse_to_purse(
&mut self,
source: URef,
target: URef,
amount: U512,
) -> Result<(), ApiError> {
let mint_contract_hash = self
.get_mint_contract()
.map_err(|_| ApiError::MissingSystemContractHash)?;
match self.mint_transfer(mint_contract_hash, None, source, target, amount, None) {
Ok(Ok(_)) => Ok(()),
Ok(Err(mint_error)) => Err(mint_error.into()),
Err(exec_error) => {
let maybe_api_error: Option<ApiError> = exec_error.into();
Err(maybe_api_error.unwrap_or(ApiError::Transfer))
}
}
}
}
impl<'a, R> HandlePaymentProvider for Runtime<'a, R>
where
R: StateReader<Key, StoredValue>,
R::Error: Into<execution::Error>,
{
fn get_payment_purse(&mut self) -> Result<URef, ApiError> {
let handle_payment_contract_hash = self
.get_handle_payment_contract()
.map_err(|_| ApiError::MissingSystemContractHash)?;
let cl_value = self
.call_contract(
handle_payment_contract_hash,
METHOD_GET_PAYMENT_PURSE,
RuntimeArgs::new(),
)
.map_err(|exec_error| {
let maybe_api_error: Option<ApiError> = exec_error.into();
maybe_api_error
.unwrap_or_else(|| handle_payment::Error::PaymentPurseNotFound.into())
})?;
let payment_purse_ref: URef = cl_value.into_t()?;
Ok(payment_purse_ref)
}
}
impl<'a, R> StandardPayment for Runtime<'a, R>
where
R: StateReader<Key, StoredValue>,
R::Error: Into<execution::Error>,
{
}