use crate::{api::Api, rpc::Request};
use ac_compose_macros::compose_extrinsic;
use ac_primitives::{
config::Config, extrinsic_params::ExtrinsicParams, extrinsics::CallIndex, Determinism,
SignExtrinsic, UncheckedExtrinsic, Weight,
};
use codec::{Compact, Encode};
use sp_core::Bytes;
pub const CONTRACTS_MODULE: &str = "Contracts";
pub const UPLOAD_CODE: &str = "upload_code";
pub const REMOVE_CODE: &str = "remove_code";
pub const SET_CODE: &str = "set_code";
pub const CALL: &str = "call";
pub const INSTANTIATE_WITH_CODE: &str = "instantiate_with_code";
pub const INSTANTIATE: &str = "instantiate";
pub const MIGRATE: &str = "migrate";
pub type UploadCodeCall<P> = (CallIndex, CodeFor<P>, Option<CurrencyFor<P>>, DeterminismFor<P>);
pub type RemoveCodeCall<P> = (CallIndex, CodeHashFor<P>);
pub type SetCodeCall<P> = (CallIndex, AddressFor<P>, CodeHashFor<P>);
pub type ContractCall<P> =
(CallIndex, AddressFor<P>, CurrencyFor<P>, WeightFor<P>, Option<CurrencyFor<P>>, DataFor<P>);
pub type InstantiateWithCodeCall<P> = (
CallIndex,
CurrencyFor<P>,
WeightFor<P>,
Option<CurrencyFor<P>>,
CodeFor<P>,
DataFor<P>,
SaltFor<P>,
);
pub type InstantiateCall<P> = (
CallIndex,
CurrencyFor<P>,
WeightFor<P>,
Option<CurrencyFor<P>>,
CodeHashFor<P>,
DataFor<P>,
SaltFor<P>,
);
pub type MigrateCall<P> = (CallIndex, WeightFor<P>);
pub type WeightFor<P> = <P as ContractsExtrinsics>::Weight;
pub type DeterminismFor<P> = <P as ContractsExtrinsics>::Determinism;
pub type DataFor<P> = <P as ContractsExtrinsics>::Data;
pub type CodeFor<P> = <P as ContractsExtrinsics>::Code;
pub type SaltFor<P> = <P as ContractsExtrinsics>::Salt;
pub type CodeHashFor<P> = <P as ContractsExtrinsics>::CodeHash;
pub type AddressFor<P> = <P as ContractsExtrinsics>::Address;
pub type CurrencyFor<P> = Compact<<P as ContractsExtrinsics>::Currency>;
#[maybe_async::maybe_async(?Send)]
pub trait ContractsExtrinsics {
type Weight;
type Currency;
type Determinism;
type CodeHash;
type Code;
type Data;
type Salt;
type Address;
type Extrinsic<Call>;
async fn contract_upload_code(
&self,
code: Self::Code,
storage_deposit_limit: Option<Self::Currency>,
determinism: Self::Determinism,
) -> Option<Self::Extrinsic<UploadCodeCall<Self>>>;
async fn contract_remove_code(
&self,
code_hash: Self::CodeHash,
) -> Option<Self::Extrinsic<RemoveCodeCall<Self>>>;
async fn contract_set_code(
&self,
dest: Self::Address,
code_hash: Self::CodeHash,
) -> Option<Self::Extrinsic<SetCodeCall<Self>>>;
async fn contract_call(
&self,
dest: Self::Address,
value: Self::Currency,
gas_limit: Self::Weight,
storage_deposit_limit: Option<Self::Currency>,
data: Self::Data,
) -> Option<Self::Extrinsic<ContractCall<Self>>>;
async fn contract_instantiate_with_code(
&self,
value: Self::Currency,
gas_limit: Self::Weight,
storage_deposit_limit: Option<Self::Currency>,
code: Self::Code,
data: Self::Data,
salt: Self::Salt,
) -> Option<Self::Extrinsic<InstantiateWithCodeCall<Self>>>;
async fn contract_instantiate(
&self,
value: Self::Currency,
gas_limit: Self::Weight,
storage_deposit_limit: Option<Self::Currency>,
code_hash: Self::CodeHash,
data: Self::Data,
salt: Self::Salt,
) -> Option<Self::Extrinsic<InstantiateCall<Self>>>;
async fn contract_migrate(
&self,
weight_limit: Self::Weight,
) -> Option<Self::Extrinsic<MigrateCall<Self>>>;
}
#[cfg(feature = "std")]
#[maybe_async::maybe_async(?Send)]
impl<T, Client> ContractsExtrinsics for Api<T, Client>
where
T: Config,
Client: Request,
Compact<T::ContractCurrency>: Encode + Clone,
{
type Weight = Weight;
type Currency = T::ContractCurrency;
type Determinism = Determinism;
type CodeHash = T::Hash;
type Code = Bytes;
type Data = Bytes;
type Salt = Bytes;
type Address = <T::ExtrinsicSigner as SignExtrinsic<T::AccountId>>::ExtrinsicAddress;
type Extrinsic<Call> = UncheckedExtrinsic<
Self::Address,
Call,
<T::ExtrinsicSigner as SignExtrinsic<T::AccountId>>::Signature,
<T::ExtrinsicParams as ExtrinsicParams<T::Index, T::Hash>>::TxExtension,
>;
async fn contract_upload_code(
&self,
code: Self::Code,
storage_deposit_limit: Option<Self::Currency>,
determinism: Self::Determinism,
) -> Option<Self::Extrinsic<UploadCodeCall<Self>>> {
compose_extrinsic!(
self,
CONTRACTS_MODULE,
UPLOAD_CODE,
code,
storage_deposit_limit.map(Compact),
determinism
)
}
async fn contract_remove_code(
&self,
code_hash: Self::CodeHash,
) -> Option<Self::Extrinsic<RemoveCodeCall<Self>>> {
compose_extrinsic!(self, CONTRACTS_MODULE, REMOVE_CODE, code_hash)
}
async fn contract_set_code(
&self,
dest: Self::Address,
code_hash: Self::CodeHash,
) -> Option<Self::Extrinsic<SetCodeCall<Self>>> {
compose_extrinsic!(self, CONTRACTS_MODULE, SET_CODE, dest, code_hash)
}
async fn contract_call(
&self,
dest: Self::Address,
value: Self::Currency,
gas_limit: Self::Weight,
storage_deposit_limit: Option<Self::Currency>,
data: Self::Data,
) -> Option<Self::Extrinsic<ContractCall<Self>>> {
compose_extrinsic!(
self,
CONTRACTS_MODULE,
CALL,
dest,
Compact(value),
gas_limit,
storage_deposit_limit.map(Compact),
data
)
}
async fn contract_instantiate_with_code(
&self,
value: Self::Currency,
gas_limit: Self::Weight,
storage_deposit_limit: Option<Self::Currency>,
code: Self::Code,
data: Self::Data,
salt: Self::Salt,
) -> Option<Self::Extrinsic<InstantiateWithCodeCall<Self>>> {
compose_extrinsic!(
self,
CONTRACTS_MODULE,
INSTANTIATE_WITH_CODE,
Compact(value),
gas_limit,
storage_deposit_limit.map(Compact),
code,
data,
salt
)
}
async fn contract_instantiate(
&self,
value: Self::Currency,
gas_limit: Self::Weight,
storage_deposit_limit: Option<Self::Currency>,
code_hash: Self::CodeHash,
data: Self::Data,
salt: Self::Salt,
) -> Option<Self::Extrinsic<InstantiateCall<Self>>> {
compose_extrinsic!(
self,
CONTRACTS_MODULE,
INSTANTIATE,
Compact(value),
gas_limit,
storage_deposit_limit.map(Compact),
code_hash,
data,
salt
)
}
async fn contract_migrate(
&self,
weight_limit: Self::Weight,
) -> Option<Self::Extrinsic<MigrateCall<Self>>> {
compose_extrinsic!(self, CONTRACTS_MODULE, MIGRATE, weight_limit)
}
}