use ink_env::{
Environment,
call::utils::{
DecodeMessageResult,
EncodeArgsWith,
},
};
use ink_primitives::H160;
use ink_revive_types::evm::CallTrace;
use jsonrpsee::core::async_trait;
use sp_weights::Weight;
use subxt::dynamic::Value;
use super::{
H256,
InstantiateDryRunResult,
Keypair,
};
use crate::{
CallBuilder,
CallBuilderFinal,
CallDryRunResult,
UploadResult,
backend_calls::{
InstantiateBuilder,
RemoveCodeBuilder,
UploadBuilder,
},
builders::CreateBuilderPartial,
contract_results::BareInstantiationResult,
};
#[async_trait]
pub trait E2EBackend<E: Environment>: ChainBackend + BuilderClient<E> {}
#[async_trait]
pub trait ChainBackend {
type AccountId;
type Balance: Send + From<u32> + std::fmt::Debug;
type Error;
type EventLog;
async fn create_and_fund_account(
&mut self,
origin: &Keypair,
amount: Self::Balance,
) -> Keypair;
async fn free_balance(
&mut self,
account: Self::AccountId,
) -> Result<Self::Balance, Self::Error>;
async fn runtime_call<'a>(
&mut self,
origin: &Keypair,
pallet_name: &'a str,
call_name: &'a str,
call_data: Vec<Value>,
) -> Result<Self::EventLog, Self::Error>;
async fn transfer_allow_death(
&mut self,
origin: &Keypair,
dest: Self::AccountId,
value: Self::Balance,
) -> Result<(), Self::Error>;
}
#[async_trait]
pub trait ContractsBackend<E: Environment> {
type Error;
type EventLog;
fn instantiate<
'a,
Contract: Clone,
Args: Send + Clone + EncodeArgsWith<Abi> + Sync,
R,
Abi: Send + Sync + Clone,
>(
&'a mut self,
contract_name: &'a str,
caller: &'a Keypair,
constructor: &'a mut CreateBuilderPartial<E, Contract, Args, R, Abi>,
) -> InstantiateBuilder<'a, E, Contract, Args, R, Self, Abi>
where
Self: Sized + BuilderClient<E>,
{
InstantiateBuilder::new(self, caller, contract_name, constructor)
}
fn upload<'a>(
&'a mut self,
contract_name: &'a str,
caller: &'a Keypair,
) -> UploadBuilder<'a, E, Self>
where
Self: Sized + BuilderClient<E>,
{
UploadBuilder::new(self, contract_name, caller)
}
fn remove_code<'a>(
&'a mut self,
caller: &'a Keypair,
code_hash: H256,
) -> RemoveCodeBuilder<'a, E, Self>
where
Self: Sized + BuilderClient<E>,
{
RemoveCodeBuilder::new(self, caller, code_hash)
}
fn call<
'a,
Args: Sync + EncodeArgsWith<Abi> + Clone,
RetType: Send + DecodeMessageResult<Abi>,
Abi: Sync + Clone,
>(
&'a mut self,
caller: &'a Keypair,
message: &'a CallBuilderFinal<E, Args, RetType, Abi>,
) -> CallBuilder<'a, E, Args, RetType, Self, Abi>
where
Self: Sized + BuilderClient<E>,
{
CallBuilder::new(self, caller, message)
}
}
#[async_trait]
pub trait BuilderClient<E: Environment>: ContractsBackend<E> {
async fn bare_call<
Args: Sync + EncodeArgsWith<Abi> + Clone,
RetType: Send + DecodeMessageResult<Abi>,
Abi: Sync + Clone,
>(
&mut self,
caller: &Keypair,
message: &CallBuilderFinal<E, Args, RetType, Abi>,
value: E::Balance,
gas_limit: Weight,
storage_deposit_limit: E::Balance,
) -> Result<(Self::EventLog, Option<CallTrace>), Self::Error>
where
CallBuilderFinal<E, Args, RetType, Abi>: Clone;
async fn bare_call_dry_run<
Args: Sync + EncodeArgsWith<Abi> + Clone,
RetType: Send + DecodeMessageResult<Abi>,
Abi: Sync + Clone,
>(
&mut self,
caller: &Keypair,
message: &CallBuilderFinal<E, Args, RetType, Abi>,
value: E::Balance,
storage_deposit_limit: Option<E::Balance>,
) -> Result<CallDryRunResult<E, RetType, Abi>, Self::Error>
where
CallBuilderFinal<E, Args, RetType, Abi>: Clone;
async fn raw_call_dry_run<
RetType: Send + DecodeMessageResult<Abi>,
Abi: Sync + Clone,
>(
&mut self,
dest: H160,
input_data: Vec<u8>,
value: E::Balance,
storage_deposit_limit: Option<E::Balance>,
signer: &Keypair,
) -> Result<CallDryRunResult<E, RetType, Abi>, Self::Error>;
async fn raw_call(
&mut self,
dest: H160,
input_data: Vec<u8>,
value: E::Balance,
gas_limit: Weight,
storage_deposit_limit: E::Balance,
signer: &Keypair,
) -> Result<(Self::EventLog, Option<CallTrace>), Self::Error>;
async fn bare_upload(
&mut self,
contract_name: &str,
caller: &Keypair,
storage_deposit_limit: Option<E::Balance>,
) -> Result<UploadResult<E, Self::EventLog>, Self::Error>;
async fn bare_remove_code(
&mut self,
caller: &Keypair,
code_hash: crate::H256,
) -> Result<Self::EventLog, Self::Error>;
async fn bare_instantiate<
Contract: Clone,
Args: Send + Sync + EncodeArgsWith<Abi> + Clone,
R,
Abi: Send + Sync + Clone,
>(
&mut self,
code: Vec<u8>,
caller: &Keypair,
constructor: &mut CreateBuilderPartial<E, Contract, Args, R, Abi>,
value: E::Balance,
gas_limit: Weight,
storage_deposit_limit: E::Balance,
) -> Result<BareInstantiationResult<E, Self::EventLog>, Self::Error>;
async fn raw_instantiate(
&mut self,
code: Vec<u8>,
caller: &Keypair,
constructor: Vec<u8>,
value: E::Balance,
gas_limit: Weight,
storage_deposit_limit: E::Balance,
) -> Result<BareInstantiationResult<E, Self::EventLog>, Self::Error>;
async fn raw_instantiate_dry_run<Abi: Sync + Clone>(
&mut self,
code: Vec<u8>,
caller: &Keypair,
constructor: Vec<u8>,
value: E::Balance,
storage_deposit_limit: Option<E::Balance>,
) -> Result<InstantiateDryRunResult<E, Abi>, Self::Error>;
async fn exec_instantiate(
&mut self,
signer: &Keypair,
contract_name: &str,
data: Vec<u8>,
value: E::Balance,
gas_limit: Weight,
storage_deposit_limit: E::Balance,
) -> Result<BareInstantiationResult<E, Self::EventLog>, Self::Error>;
async fn bare_instantiate_dry_run<
Contract: Clone,
Args: Send + Sync + EncodeArgsWith<Abi> + Clone,
R,
Abi: Send + Sync + Clone,
>(
&mut self,
contract_name: &str,
caller: &Keypair,
constructor: &mut CreateBuilderPartial<E, Contract, Args, R, Abi>,
value: E::Balance,
storage_deposit_limit: Option<E::Balance>,
) -> Result<InstantiateDryRunResult<E, Abi>, Self::Error>;
async fn map_account(
&mut self,
caller: &Keypair,
) -> Result<Option<Self::EventLog>, Self::Error>;
async fn to_account_id(&mut self, addr: &H160) -> Result<E::AccountId, Self::Error>;
fn load_code(&self, contract_name: &str) -> Vec<u8>;
}