diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index 0fa1119c6..808182355 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -13,7 +13,7 @@ scale-info = { version = "2.6", default-features = false, features = ["derive"] sp-io = { version = "23.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] } sp-runtime = { version = "24.0", default-features = false } -pop-primitives = { path = "../primitives", default-features = false } +pop-primitives = { path = "../primitives", features = ["devnet"], default-features = false } [lib] name = "pop_api" diff --git a/pop-api/examples/trust_backed_assets/.gitignore b/pop-api/examples/fungibles/.gitignore similarity index 100% rename from pop-api/examples/trust_backed_assets/.gitignore rename to pop-api/examples/fungibles/.gitignore diff --git a/pop-api/examples/trust_backed_assets/Cargo.toml b/pop-api/examples/fungibles/Cargo.toml similarity index 93% rename from pop-api/examples/trust_backed_assets/Cargo.toml rename to pop-api/examples/fungibles/Cargo.toml index 3c3716fcc..1fe32d6d4 100755 --- a/pop-api/examples/trust_backed_assets/Cargo.toml +++ b/pop-api/examples/fungibles/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "pop_api_trust_backed_assets_example" +name = "fungibles" version = "0.1.0" authors = ["[your_name] <[your_email]>"] edition = "2021" diff --git a/pop-api/examples/trust_backed_assets/lib.rs b/pop-api/examples/fungibles/lib.rs similarity index 68% rename from pop-api/examples/trust_backed_assets/lib.rs rename to pop-api/examples/fungibles/lib.rs index 0e3492ef2..f9c55d2c0 100755 --- a/pop-api/examples/trust_backed_assets/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -1,33 +1,30 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -// Utilizing Trust Backed Assets with the Pop API. -// -// This example demonstrates interaction with trust backed assets via the assets pallet. Trust backed assets are originated -// and managed within Pop Network, harnessing the platform's inherent trust, security, and governance models. -use pop_api::assets::trust_backed as assets; +// Using fungible assets with the Pop API. +use pop_api::assets::fungibles; #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum ContractError { - AssetsError(assets::Error), + AssetsError(Error), UnknownAsset, } -impl From for ContractError { - fn from(value: assets::Error) -> Self { +impl From for ContractError { + fn from(value: Error) -> Self { ContractError::AssetsError(value) } } #[ink::contract(env = pop_api::Environment)] -mod pop_api_assets_example { +mod fungibles { use super::*; #[ink(storage)] #[derive(Default)] - pub struct PopApiAssetsExample; + pub struct Fungibles; - impl PopApiAssetsExample { + impl Fungibles { #[ink(constructor, payable)] pub fn new() -> Self { ink::env::debug_println!("PopApiAssetsExample::new"); @@ -35,7 +32,17 @@ mod pop_api_assets_example { } #[ink(message)] - pub fn mint_asset_through_runtime( + pub fn token_supply(id: AssetId) -> Result { + token_supply(id)? + } + + #[ink(message)] + pub fn token_name(id: AssetId) -> Result>, ContractError> { + token_name(id) + } + + #[ink(message)] + pub fn mint_asset( &mut self, id: u32, beneficiary: AccountId, diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 68ce69067..bc67259dd 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -3,7 +3,7 @@ pub mod primitives; pub mod v0; -use crate::PopApiError::{Balances, Nfts, TrustBackedAssets, UnknownStatusCode}; +use crate::PopApiError::{Balances, Nfts, Assets, UnknownStatusCode}; use ink::{prelude::vec::Vec, ChainExtensionInstance}; use primitives::{cross_chain::*, storage_keys::*}; pub use sp_runtime::{BoundedVec, MultiAddress, MultiSignature}; @@ -26,7 +26,7 @@ pub enum PopApiError { SystemCallFiltered, Balances(balances::Error), Nfts(nfts::Error), - TrustBackedAssets(assets::trust_backed::Error), + Assets(assets::fungibles::Error), Xcm(cross_chain::Error), } @@ -38,7 +38,7 @@ impl ink::env::chain_extension::FromStatusCode for PopApiError { 5 => Err(PopApiError::SystemCallFiltered), 10_000..=10_999 => Err(Balances((status_code - 10_000).try_into()?)), 50_000..=50_999 => Err(Nfts((status_code - 50_000).try_into()?)), - 52_000..=52_999 => Err(TrustBackedAssets((status_code - 52_000).try_into()?)), + 52_000..=52_999 => Err(Assets((status_code - 52_000).try_into()?)), _ => Err(UnknownStatusCode(status_code)), } } diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs new file mode 100644 index 000000000..2887b24ad --- /dev/null +++ b/pop-api/src/v0/assets/fungibles.rs @@ -0,0 +1,534 @@ +use crate::{Balance, PopApiError::UnknownStatusCode, RuntimeCall, *}; +use ink::prelude::vec::Vec; +use primitives::{AssetId, MultiAddress}; +use scale::{Compact, Encode}; + +type Result = core::result::Result; + +/// Local Fungibles: +/// 1. PSP-22 Interface +/// 2. PSP-22 Metadata Interface +/// 3. Asset Management + +/// 1. PSP-22 Interface: +/// - total_supply +/// - balance_of +/// - allowance +/// - transfer +/// - transfer_from +/// - approve +/// - increase_allowance +/// - decrease_allowance + +/// Returns the total token supply for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The total supply of the token, or an error if the operation fails. +pub fn total_supply(id: AssetId) -> Result { + Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id)))?) +} + +/// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if +/// the account is non-existent. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `owner` - The account whose balance is being queried. +/// +/// # Returns +/// The balance of the specified account, or an error if the operation fails. +// fn balance_of(id: AssetId, owner: AccountId) -> Result { +// Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner)))?) +// } + +/// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given +/// asset ID. Returns `0` if no allowance has been set. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `owner` - The account that owns the tokens. +/// * `spender` - The account that is allowed to spend the tokens. +/// +/// # Returns +/// The remaining allowance, or an error if the operation fails. +// fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { +// Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender)))?) +// } + +/// Transfers `value` amount of tokens from the caller's account to account `to`, with additional +/// `data` in unspecified format. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `to` - The recipient account. +/// * `value` - The number of tokens to transfer. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the transfer fails. +#[allow(unused_variables)] +pub fn transfer( + id: AssetId, + to: impl Into>, + value: Balance, +) -> Result<()> { + todo!() + // TODO: transfer or transfer_keep_alive + // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Transfer { + // id: id.into(), + // target: target.into(), + // amount: Compact(amount), + // }))?) + // Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { + // id: id.into(), + // target: target.into(), + // amount: Compact(amount), + // }))?) +} + +/// Transfers `value` tokens on the behalf of `from` to the account `to` with additional `data` +/// in unspecified format. This can be used to allow a contract to transfer tokens on ones behalf +/// and/or to charge fees in sub-currencies, for example. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `from` - The account from which the tokens are transferred. +/// * `to` - The recipient account. +/// * `value` - The number of tokens to transfer. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the transfer fails. +#[allow(unused_variables)] +pub fn transfer_from( + id: AssetId, + from: impl Into>, + to: impl Into>, + value: Balance, +) -> Result<()> { + todo!() + // TODO: depending on `from` and `to`, decide whether to mint, burn or transfer_approved. + // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Mint { + // id: id.into(), + // beneficiary: beneficiary.into(), + // amount: Compact(amount), + // }))?) + // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Burn { + // id: id.into(), + // who: who.into(), + // amount: Compact(amount), + // }))?) + // Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferApproved { + // id: id.into(), + // owner: from.into(), + // destination: to.into(), + // amount: Compact(value), + // }))?) +} + +/// Approves an account to spend a specified number of tokens on behalf of the caller. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `spender` - The account that is allowed to spend the tokens. +/// * `value` - The number of tokens to approve. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the approval fails. +#[allow(unused_variables)] +fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + todo!() + // TODO: read allowance and increase or decrease. + // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { + // id: id.into(), + // delegate: spender.into(), + // amount: Compact(value), + // }))?) +} + +/// Increases the allowance of a spender. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `spender` - The account that is allowed to spend the tokens. +/// * `value` - The number of tokens to increase the allowance by. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { + id: id.into(), + delegate: spender.into(), + amount: Compact(value), + }))?) +} + +/// Decreases the allowance of a spender. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `spender` - The account that is allowed to spend the tokens. +/// * `value` - The number of tokens to decrease the allowance by. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +#[allow(unused_variables)] +fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + todo!() + // TODO: cancel_approval + approve_transfer + // Ok(dispatch(RuntimeCall::Assets(AssetsCall::CancelApproval { + // id: id.into(), + // delegate: delegate.into(), + // }))?) + // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { + // id: id.into(), + // delegate: spender.into(), + // amount: Compact(value), + // }))?) +} + +/// 2. PSP-22 Metadata Interface: +/// - token_name +/// - token_symbol +/// - token_decimals + +/// Returns the token name for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The name of the token as a byte vector, or an error if the operation fails. +#[allow(unused_variables)] +pub fn token_name(id: AssetId) -> Result>> { + todo!() + // Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenName(id)))?) +} + +/// Returns the token symbol for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The symbol of the token as a byte vector, or an error if the operation fails. +#[allow(unused_variables)] +fn token_symbol(id: AssetId) -> Result>> { + todo!() +} + +/// Returns the token decimals for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The number of decimals of the token as a byte vector, or an error if the operation fails. +#[allow(unused_variables)] +fn token_decimals(id: AssetId) -> Result>> { + todo!() +} + +/// 3. Asset Management: +/// - create +/// - start_destroy +/// - destroy_accounts +/// - destroy_approvals +/// - finish_destroy +/// - set_metadata +/// - clear_metadata + +/// Create a new token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `admin` - The account that will administer the asset. +/// * `min_balance` - The minimum balance required for accounts holding this asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the creation fails. +fn create(id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::Create { + id: id.into(), + admin: admin.into(), + min_balance: Compact(min_balance), + }))?) +} + +/// Start the process of destroying a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +fn start_destroy(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { + id: id.into(), + }))?) +} + +/// Destroy all accounts associated with a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +fn destroy_accounts(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { + id: id.into(), + }))?) +} + +/// Destroy all approvals associated with a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +fn destroy_approvals(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { + id: id.into(), + }))?) +} + +/// Complete the process of destroying a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +fn finish_destroy(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { + id: id.into(), + }))?) +} + +/// Set the metadata for a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::SetMetadata { + id: id.into(), + name, + symbol, + decimals, + }))?) +} + +/// Clear the metadata for a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +fn clear_metadata(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { + id: id.into(), + }))?) +} + +pub fn asset_exists(id: AssetId) -> Result { + Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id)))?) +} + +// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected +// to be compact encoded. The pop api handles that for the developer. +// +// reference: https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development +// +// Asset id that is compact encoded. +type AssetIdParameter = Compact; +// Balance amount that is compact encoded. +type BalanceParameter = Compact; + +#[derive(Encode)] +pub(crate) enum AssetsCall { + #[codec(index = 0)] + Create { + id: AssetIdParameter, + admin: MultiAddress, + min_balance: BalanceParameter, + }, + #[codec(index = 2)] + StartDestroy { id: AssetIdParameter }, + #[codec(index = 3)] + DestroyAccounts { id: AssetIdParameter }, + #[codec(index = 4)] + DestroyApprovals { id: AssetIdParameter }, + #[codec(index = 5)] + FinishDestroy { id: AssetIdParameter }, + #[codec(index = 6)] + Mint { + id: AssetIdParameter, + beneficiary: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 7)] + Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, + #[codec(index = 8)] + Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, + #[codec(index = 9)] + TransferKeepAlive { + id: AssetIdParameter, + target: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 10)] + ForceTransfer { + id: AssetIdParameter, + source: MultiAddress, + dest: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 11)] + Freeze { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 12)] + Thaw { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 13)] + FreezeAsset { id: AssetIdParameter }, + #[codec(index = 14)] + ThawAsset { id: AssetIdParameter }, + #[codec(index = 15)] + TransferOwnership { id: AssetIdParameter, owner: MultiAddress }, + #[codec(index = 16)] + SetTeam { + id: AssetIdParameter, + issuer: MultiAddress, + admin: MultiAddress, + freezer: MultiAddress, + }, + #[codec(index = 17)] + SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, + #[codec(index = 18)] + ClearMetadata { id: AssetIdParameter }, + #[codec(index = 22)] + ApproveTransfer { + id: AssetIdParameter, + delegate: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 23)] + CancelApproval { id: AssetIdParameter, delegate: MultiAddress }, + #[codec(index = 24)] + ForceCancelApproval { + id: AssetIdParameter, + owner: MultiAddress, + delegate: MultiAddress, + }, + #[codec(index = 25)] + TransferApproved { + id: AssetIdParameter, + owner: MultiAddress, + destination: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 26)] + Touch { id: AssetIdParameter }, + #[codec(index = 27)] + Refund { id: AssetIdParameter, allow_burn: bool }, + #[codec(index = 28)] + SetMinBalance { id: AssetIdParameter, min_balance: BalanceParameter }, + #[codec(index = 29)] + TouchOther { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 30)] + RefundOther { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 31)] + Block { id: AssetIdParameter, who: MultiAddress }, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum Error { + /// Account balance must be greater than or equal to the transfer amount. + BalanceLow, + /// The account to alter does not exist. + NoAccount, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given asset ID is unknown. + Unknown, + /// The origin account is frozen. + Frozen, + /// The asset ID is already taken. + InUse, + /// Invalid witness data given. + BadWitness, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// Unable to increment the consumer reference counters on the account. Either no provider + /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one + /// fewer then the maximum number of consumers has been reached. + UnavailableConsumer, + /// Invalid metadata given. + BadMetadata, + /// No approval exists that would allow the transfer. + Unapproved, + /// The source account would not survive the transfer and it needs to stay alive. + WouldDie, + /// The asset-account already exists. + AlreadyExists, + /// The asset-account doesn't have an associated deposit. + NoDeposit, + /// The operation would result in funds being burned. + WouldBurn, + /// The asset is a live asset and is actively being used. Usually emit for operations such + /// as `start_destroy` which require the asset to be in a destroying state. + LiveAsset, + /// The asset is not live, and likely being destroyed. + AssetNotLive, + /// The asset status is not the expected status. + IncorrectStatus, + /// The asset should be frozen before the given operation. + NotFrozen, + /// Callback action resulted in error + CallbackFailed, +} + +impl TryFrom for Error { + type Error = PopApiError; + + fn try_from(status_code: u32) -> core::result::Result { + use Error::*; + match status_code { + 0 => Ok(BalanceLow), + 1 => Ok(NoAccount), + 2 => Ok(NoPermission), + 3 => Ok(Unknown), + 4 => Ok(Frozen), + 5 => Ok(InUse), + 6 => Ok(BadWitness), + 7 => Ok(MinBalanceZero), + 8 => Ok(UnavailableConsumer), + 9 => Ok(BadMetadata), + 10 => Ok(Unapproved), + 11 => Ok(WouldDie), + 12 => Ok(AlreadyExists), + 13 => Ok(NoDeposit), + 14 => Ok(WouldBurn), + 15 => Ok(LiveAsset), + 16 => Ok(AssetNotLive), + 17 => Ok(IncorrectStatus), + 18 => Ok(NotFrozen), + _ => Err(UnknownStatusCode(status_code)), + } + } +} + +impl From for Error { + fn from(error: PopApiError) -> Self { + match error { + PopApiError::Assets(e) => e, + _ => panic!("Unexpected pallet assets error. This error is unknown to pallet assets"), + } + } +} diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 7ad40f158..d6b0261ce 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1 +1 @@ -pub mod trust_backed; \ No newline at end of file +pub mod fungibles; \ No newline at end of file diff --git a/pop-api/src/v0/assets/trust_backed.rs b/pop-api/src/v0/assets/trust_backed.rs deleted file mode 100644 index fb413413b..000000000 --- a/pop-api/src/v0/assets/trust_backed.rs +++ /dev/null @@ -1,519 +0,0 @@ -use crate::{Balance, PopApiError::UnknownStatusCode, RuntimeCall, *}; -use ink::prelude::vec::Vec; -use primitives::{AssetId, MultiAddress}; -use scale::{Compact, Encode}; - -type Result = core::result::Result; - -/// https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/lib.rs -/// -/// Extrinsics within pallet assets (TrustBackedAssets Instance) that can be used via the pop api on Pop Network: -/// 1. create -/// 2. start_destroy -/// 3. destroy_accounts -/// 4. destroy_approvals -/// 5. finish_destroy -/// 6. mint -/// 7. burn -/// 8. transfer -/// 9. transfer_keep_alive -/// 10. force_transfer -/// 11. freeze -/// 12. thaw -/// 13. freeze_asset -/// 14. thaw_asset -/// 15. transfer_ownership -/// 16. set_team -/// 17. set_metadata -/// 18. clear_metadata -/// 19. approve_transfer -/// 20. cancel_approval -/// 21. force_cancel_approval -/// 22. transfer_approved -/// 23. touch -/// 24. refund -/// 25. set_min_balance -/// 26. touch_other -/// 27. refund_other -/// 28. block - - -/// Issue a new class of fungible assets from a public origin. -pub fn create( - id: AssetId, - admin: impl Into>, - min_balance: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Create { - id: id.into(), - admin: admin.into(), - min_balance: Compact(min_balance), - }))?) -} - -/// Start the process of destroying a fungible asset class. -pub fn start_destroy(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::StartDestroy { - id: id.into(), - }))?) -} - -/// Destroy all accounts associated with a given asset. -pub fn destroy_accounts(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::DestroyAccounts { - id: id.into(), - }))?) -} - -/// Destroy all approvals associated with a given asset up to the max (see runtime configuration TrustBackedAssets `RemoveItemsLimit`). -pub fn destroy_approvals(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::DestroyApprovals { - id: id.into(), - }))?) -} - -/// Complete destroying asset and unreserve currency. -pub fn finish_destroy(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::FinishDestroy { - id: id.into(), - }))?) -} - -/// Mint assets of a particular class. -pub fn mint( - id: AssetId, - beneficiary: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Mint { - id: id.into(), - beneficiary: beneficiary.into(), - amount: Compact(amount), - }))?) -} - -/// Reduce the balance of `who` by as much as possible up to `amount` assets of `id`. -pub fn burn( - id: AssetId, - who: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Burn { - id: id.into(), - who: who.into(), - amount: Compact(amount), - }))?) -} - -/// Move some assets from the sender account to another. -pub fn transfer( - id: AssetId, - target: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Transfer { - id: id.into(), - target: target.into(), - amount: Compact(amount), - }))?) -} - -/// Move some assets from the sender account to another, keeping the sender account alive. -pub fn transfer_keep_alive( - id: AssetId, - target: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TransferKeepAlive { - id: id.into(), - target: target.into(), - amount: Compact(amount), - }))?) -} - -/// Move some assets from one account to another. Sender should be the Admin of the asset `id`. -pub fn force_transfer( - id: AssetId, - source: impl Into>, - dest: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ForceTransfer { - id: id.into(), - source: source.into(), - dest: dest.into(), - amount: Compact(amount), - }))?) -} - -/// Disallow further unprivileged transfers of an asset `id` from an account `who`. `who` -/// must already exist as an entry in `Account`s of the asset. If you want to freeze an -/// account that does not have an entry, use `touch_other` first. -pub fn freeze(id: AssetId, who: impl Into>) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Freeze { - id: id.into(), - who: who.into(), - }))?) -} - -/// Allow unprivileged transfers to and from an account again. -pub fn thaw(id: AssetId, who: impl Into>) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Thaw { - id: id.into(), - who: who.into(), - }))?) -} - -/// Disallow further unprivileged transfers for the asset class. -pub fn freeze_asset(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::FreezeAsset { - id: id.into(), - }))?) -} - -/// Allow unprivileged transfers for the asset again. -pub fn thaw_asset(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ThawAsset { - id: id.into(), - }))?) -} - -/// Change the Owner of an asset. -pub fn transfer_ownership( - id: AssetId, - owner: impl Into>, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TransferOwnership { - id: id.into(), - owner: owner.into(), - }))?) -} - -/// Change the Issuer, Admin and Freezer of an asset. -pub fn set_team( - id: AssetId, - issuer: impl Into>, - admin: impl Into>, - freezer: impl Into>, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::SetTeam { - id: id.into(), - issuer: issuer.into(), - admin: admin.into(), - freezer: freezer.into(), - }))?) -} - -/// Set the metadata for an asset. -pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::SetMetadata { - id: id.into(), - name, - symbol, - decimals, - }))?) -} - -/// Clear the metadata for an asset. -pub fn clear_metadata(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ClearMetadata { - id: id.into(), - }))?) -} - -/// Approve an amount of asset for transfer by a delegated third-party account. -pub fn approve_transfer( - id: AssetId, - delegate: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ApproveTransfer { - id: id.into(), - delegate: delegate.into(), - amount: Compact(amount), - }))?) -} - -/// Cancel all of some asset approved for delegated transfer by a third-party account. -pub fn cancel_approval( - id: AssetId, - delegate: impl Into>, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::CancelApproval { - id: id.into(), - delegate: delegate.into(), - }))?) -} - -/// Cancel all of some asset approved for delegated transfer by a third-party account. -pub fn force_cancel_approval( - id: AssetId, - owner: impl Into>, - delegate: impl Into>, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ForceCancelApproval { - id: id.into(), - owner: owner.into(), - delegate: delegate.into(), - }))?) -} - -/// Transfer some asset balance from a previously delegated account to some third-party -/// account. -pub fn transfer_approved( - id: AssetId, - owner: impl Into>, - destination: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TransferApproved { - id: id.into(), - owner: owner.into(), - destination: destination.into(), - amount: Compact(amount), - }))?) -} - -/// Create an asset account for non-provider assets. -pub fn touch(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Touch { - id: id.into(), - }))?) -} - -/// Return the deposit (if any) of an asset account or a consumer reference (if any) of an -/// account. -pub fn refund(id: AssetId, allow_burn: bool) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Refund { - id: id.into(), - allow_burn, - }))?) -} - -/// Sets the minimum balance of an asset. -pub fn set_min_balance(id: AssetId, min_balance: Balance) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::SetMinBalance { - id: id.into(), - min_balance: Compact(min_balance), - }))?) -} - -/// Create an asset account for `who`. -pub fn touch_other(id: AssetId, who: impl Into>) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TouchOther { - id: id.into(), - who: who.into(), - }))?) -} - -/// Return the deposit (if any) of a target asset account. Useful if you are the depositor. -pub fn refund_other(id: AssetId, who: impl Into>) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::RefundOther { - id: id.into(), - who: who.into(), - }))?) -} - -/// Disallow further unprivileged transfers of an asset `id` to and from an account `who`. -pub fn block(id: AssetId, who: impl Into>) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Block { - id: id.into(), - who: who.into(), - }))?) -} - -pub fn asset_exists(id: AssetId) -> Result { - Ok(state::read(RuntimeStateKeys::TrustBackedAssets(TrustBackedAssetsKeys::AssetExists(id)))?) -} - -// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected -// to be compact encoded. The pop api handles that for the developer. -// -// reference: https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development -// -// Asset id that is compact encoded. -type AssetIdParameter = Compact; -// Balance amount that is compact encoded. -type BalanceParameter = Compact; - -#[derive(Encode)] -pub(crate) enum TrustBackedAssetsCalls { - #[codec(index = 0)] - Create { - id: AssetIdParameter, - admin: MultiAddress, - min_balance: BalanceParameter, - }, - #[codec(index = 2)] - StartDestroy { id: AssetIdParameter }, - #[codec(index = 3)] - DestroyAccounts { id: AssetIdParameter }, - #[codec(index = 4)] - DestroyApprovals { id: AssetIdParameter }, - #[codec(index = 5)] - FinishDestroy { id: AssetIdParameter }, - #[codec(index = 6)] - Mint { - id: AssetIdParameter, - beneficiary: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 7)] - Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, - #[codec(index = 8)] - Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, - #[codec(index = 9)] - TransferKeepAlive { - id: AssetIdParameter, - target: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 10)] - ForceTransfer { - id: AssetIdParameter, - source: MultiAddress, - dest: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 11)] - Freeze { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 12)] - Thaw { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 13)] - FreezeAsset { id: AssetIdParameter }, - #[codec(index = 14)] - ThawAsset { id: AssetIdParameter }, - #[codec(index = 15)] - TransferOwnership { id: AssetIdParameter, owner: MultiAddress }, - #[codec(index = 16)] - SetTeam { - id: AssetIdParameter, - issuer: MultiAddress, - admin: MultiAddress, - freezer: MultiAddress, - }, - #[codec(index = 17)] - SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, - #[codec(index = 18)] - ClearMetadata { id: AssetIdParameter }, - #[codec(index = 22)] - ApproveTransfer { - id: AssetIdParameter, - delegate: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 23)] - CancelApproval { id: AssetIdParameter, delegate: MultiAddress }, - #[codec(index = 24)] - ForceCancelApproval { - id: AssetIdParameter, - owner: MultiAddress, - delegate: MultiAddress, - }, - #[codec(index = 25)] - TransferApproved { - id: AssetIdParameter, - owner: MultiAddress, - destination: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 26)] - Touch { id: AssetIdParameter }, - #[codec(index = 27)] - Refund { id: AssetIdParameter, allow_burn: bool }, - #[codec(index = 28)] - SetMinBalance { id: AssetIdParameter, min_balance: BalanceParameter }, - #[codec(index = 29)] - TouchOther { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 30)] - RefundOther { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 31)] - Block { id: AssetIdParameter, who: MultiAddress }, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum Error { - /// Account balance must be greater than or equal to the transfer amount. - BalanceLow, - /// The account to alter does not exist. - NoAccount, - /// The signing account has no permission to do the operation. - NoPermission, - /// The given asset ID is unknown. - Unknown, - /// The origin account is frozen. - Frozen, - /// The asset ID is already taken. - InUse, - /// Invalid witness data given. - BadWitness, - /// Minimum balance should be non-zero. - MinBalanceZero, - /// Unable to increment the consumer reference counters on the account. Either no provider - /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one - /// fewer then the maximum number of consumers has been reached. - UnavailableConsumer, - /// Invalid metadata given. - BadMetadata, - /// No approval exists that would allow the transfer. - Unapproved, - /// The source account would not survive the transfer and it needs to stay alive. - WouldDie, - /// The asset-account already exists. - AlreadyExists, - /// The asset-account doesn't have an associated deposit. - NoDeposit, - /// The operation would result in funds being burned. - WouldBurn, - /// The asset is a live asset and is actively being used. Usually emit for operations such - /// as `start_destroy` which require the asset to be in a destroying state. - LiveAsset, - /// The asset is not live, and likely being destroyed. - AssetNotLive, - /// The asset status is not the expected status. - IncorrectStatus, - /// The asset should be frozen before the given operation. - NotFrozen, - /// Callback action resulted in error - CallbackFailed, -} - -impl TryFrom for Error { - type Error = PopApiError; - - fn try_from(status_code: u32) -> core::result::Result { - use Error::*; - match status_code { - 0 => Ok(BalanceLow), - 1 => Ok(NoAccount), - 2 => Ok(NoPermission), - 3 => Ok(Unknown), - 4 => Ok(Frozen), - 5 => Ok(InUse), - 6 => Ok(BadWitness), - 7 => Ok(MinBalanceZero), - 8 => Ok(UnavailableConsumer), - 9 => Ok(BadMetadata), - 10 => Ok(Unapproved), - 11 => Ok(WouldDie), - 12 => Ok(AlreadyExists), - 13 => Ok(NoDeposit), - 14 => Ok(WouldBurn), - 15 => Ok(LiveAsset), - 16 => Ok(AssetNotLive), - 17 => Ok(IncorrectStatus), - 18 => Ok(NotFrozen), - _ => Err(UnknownStatusCode(status_code)), - } - } -} - -impl From for Error { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::TrustBackedAssets(e) => e, - _ => panic!("Unexpected pallet assets error. This error is unknown to pallet assets"), - } - } -} diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index d914db249..2360c6d34 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -20,5 +20,5 @@ pub(crate) enum RuntimeCall { #[codec(index = 50)] Nfts(nfts::NftCalls), #[codec(index = 52)] - TrustBackedAssets(assets::trust_backed::TrustBackedAssetsCalls), + Assets(assets::fungibles::AssetsCall), } diff --git a/pop-api/wrappers/fungibles/.gitignore b/pop-api/wrappers/fungibles/.gitignore new file mode 100755 index 000000000..8de8f877e --- /dev/null +++ b/pop-api/wrappers/fungibles/.gitignore @@ -0,0 +1,9 @@ +# Ignore build artifacts from the local tests sub-crate. +/target/ + +# Ignore backup files creates by cargo fmt. +**/*.rs.bk + +# Remove Cargo.lock when creating an executable, leave it for libraries +# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock +Cargo.lock diff --git a/pop-api/wrappers/fungibles/Cargo.toml b/pop-api/wrappers/fungibles/Cargo.toml new file mode 100755 index 000000000..f07125745 --- /dev/null +++ b/pop-api/wrappers/fungibles/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "fungibles" +version = "0.1.0" +authors = ["[your_name] <[your_email]>"] +edition = "2021" + +[dependencies] +ink = { version = "5.0.0", default-features = false } +pop-api = { path = "../../../pop-api", default-features = false } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } + +[dev-dependencies] +ink_e2e = { version = "5.0.0" } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = [ + "ink/std", + "pop-api/std", + "scale/std", + "scale-info/std", +] +ink-as-dependency = [] +e2e-tests = [] diff --git a/pop-api/wrappers/fungibles/lib.rs b/pop-api/wrappers/fungibles/lib.rs new file mode 100755 index 000000000..8eeab937e --- /dev/null +++ b/pop-api/wrappers/fungibles/lib.rs @@ -0,0 +1,129 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +// Fungibles wrapper contract to allow contracts to interact with local fungibles without the pop api. +use pop_api::assets::fungibles::*; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum ContractError { + AssetsError(Error), + // UnknownAsset, +} + +impl From> for Result { + fn from(value: Error) -> Self { + ContractError::AssetsError(value) + } +} + +#[ink::contract] +mod fungibles { + use super::*; + + #[ink(storage)] + pub struct Fungibles { + id: u32, + } + + impl Fungibles { + #[ink(constructor)] + pub fn new(id: u32) -> Result { + asset_exists(id)?; + Ok(Self { id }) + } + + #[ink(message)] + pub fn total_supply(&mut self) -> Result { + total_supply(self.id).into() + } + + // #[ink(message)] + // pub fn get(&self) -> bool { + // self.value + // } + } + + #[cfg(test)] + mod tests { + /// Imports all the definitions from the outer scope so we can use them here. + use super::*; + + /// We test if the default constructor does its job. + #[ink::test] + fn default_works() { + let fungibles = Fungibles::default(); + assert_eq!(fungibles.get(), false); + } + + /// We test a simple use case of our contract. + #[ink::test] + fn it_works() { + let mut fungibles = Fungibles::new(false); + assert_eq!(fungibles.get(), false); + fungibles.flip(); + assert_eq!(fungibles.get(), true); + } + } + + #[cfg(all(test, feature = "e2e-tests"))] + mod e2e_tests { + use super::*; + + /// A helper function used for calling contract messages. + use ink_e2e::ContractsBackend; + + /// The End-to-End test `Result` type. + type E2EResult = std::result::Result>; + + /// We test that we can upload and instantiate the contract using its default constructor. + #[ink_e2e::test] + async fn default_works(mut client: ink_e2e::Client) -> E2EResult<()> { + // Given + let mut constructor = FungiblesRef::default(); + + // When + let contract = client + .instantiate("fungibles", &ink_e2e::alice(), &mut constructor) + .submit() + .await + .expect("instantiate failed"); + let call_builder = contract.call_builder::(); + + // Then + let get = call_builder.get(); + let get_result = client.call(&ink_e2e::alice(), &get).dry_run().await?; + assert!(matches!(get_result.return_value(), false)); + + Ok(()) + } + + /// We test that we can read and write a value from the on-chain contract contract. + #[ink_e2e::test] + async fn it_works(mut client: ink_e2e::Client) -> E2EResult<()> { + // Given + let mut constructor = FungiblesRef::new(false); + let contract = client + .instantiate("fungibles", &ink_e2e::bob(), &mut constructor) + .submit() + .await + .expect("instantiate failed"); + let mut call_builder = contract.call_builder::(); + + let get = call_builder.get(); + let get_result = client.call(&ink_e2e::bob(), &get).dry_run().await?; + assert!(matches!(get_result.return_value(), false)); + + // When + let flip = call_builder.flip(); + let _flip_result = + client.call(&ink_e2e::bob(), &flip).submit().await.expect("flip failed"); + + // Then + let get = call_builder.get(); + let get_result = client.call(&ink_e2e::bob(), &get).dry_run().await?; + assert!(matches!(get_result.return_value(), true)); + + Ok(()) + } + } +} diff --git a/primitives/src/storage_keys.rs b/primitives/src/storage_keys.rs index 46c9fd570..bd15f1a77 100644 --- a/primitives/src/storage_keys.rs +++ b/primitives/src/storage_keys.rs @@ -6,7 +6,7 @@ pub enum RuntimeStateKeys { Nfts(NftsKeys), ParachainSystem(ParachainSystemKeys), #[cfg(feature = "devnet")] - TrustBackedAssets(TrustBackedAssetsKeys), + Assets(AssetsKeys), } #[derive(Encode, Decode, Debug, MaxEncodedLen)] @@ -38,7 +38,15 @@ pub enum NftsKeys { #[cfg(feature = "devnet")] #[derive(Encode, Decode, Debug, MaxEncodedLen)] -pub enum TrustBackedAssetsKeys { +pub enum AssetsKeys { + /// Returns the total token supply for a given asset ID. + TotalSupply(AssetId), + /// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if + /// the account is non-existent.. + // BalanceOf(AssetId, AccountId), + /// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given + /// asset ID. Returns `0` if no allowance has been set. + // Allowance(AssetId, AccountId, AccountId), /// Check if the asset exists. AssetExists(AssetId), } diff --git a/runtime/devnet/src/config/assets.rs b/runtime/devnet/src/config/assets.rs index f51f8875b..2c8ea952f 100644 --- a/runtime/devnet/src/config/assets.rs +++ b/runtime/devnet/src/config/assets.rs @@ -1,6 +1,6 @@ use crate::{ - deposit, AccountId, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, - RuntimeHoldReason, TrustBackedAssets, DAYS, EXISTENTIAL_DEPOSIT, UNIT, + deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, + RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT, }; use frame_support::{ parameter_types, @@ -86,7 +86,7 @@ impl pallet_nft_fractionalization::Config for Runtime { type NftId = ::ItemId; type AssetBalance = >::Balance; type AssetId = >::AssetId; - type Assets = TrustBackedAssets; + type Assets = Assets; type Nfts = Nfts; type PalletId = NftFractionalizationPalletId; type WeightInfo = pallet_nft_fractionalization::weights::SubstrateWeight; @@ -96,7 +96,7 @@ impl pallet_nft_fractionalization::Config for Runtime { } pub type TrustBackedAssetsInstance = pallet_assets::Instance1; -pub(crate) type TrustBackedAssetsCall = pallet_assets::Call; +pub(crate) type AssetsCall = pallet_assets::Call; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; diff --git a/runtime/devnet/src/config/mod.rs b/runtime/devnet/src/config/mod.rs index a3a64c928..c370bb1db 100644 --- a/runtime/devnet/src/config/mod.rs +++ b/runtime/devnet/src/config/mod.rs @@ -1,4 +1,4 @@ -mod assets; +pub(crate) mod assets; mod contracts; mod proxy; // Public due to integration tests crate. diff --git a/runtime/devnet/src/config/proxy.rs b/runtime/devnet/src/config/proxy.rs index 79339565e..07d5f0f8e 100644 --- a/runtime/devnet/src/config/proxy.rs +++ b/runtime/devnet/src/config/proxy.rs @@ -1,4 +1,4 @@ -use super::assets::TrustBackedAssetsCall; +use super::assets::AssetsCall; use crate::{Balances, Runtime, RuntimeCall, RuntimeEvent}; use frame_support::traits::InstanceFilter; use pop_runtime_common::proxy::{ @@ -14,7 +14,7 @@ impl InstanceFilter for ProxyType { ProxyType::NonTransfer => !matches!( c, RuntimeCall::Balances { .. } - | RuntimeCall::TrustBackedAssets { .. } + | RuntimeCall::Assets { .. } | RuntimeCall::Nfts { .. } ), ProxyType::CancelProxy => matches!( @@ -26,7 +26,7 @@ impl InstanceFilter for ProxyType { ProxyType::Assets => { matches!( c, - RuntimeCall::TrustBackedAssets { .. } + RuntimeCall::Assets { .. } | RuntimeCall::Utility { .. } | RuntimeCall::Multisig { .. } | RuntimeCall::Nfts { .. } @@ -34,18 +34,16 @@ impl InstanceFilter for ProxyType { }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::create { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::start_destroy { .. }) - | RuntimeCall::TrustBackedAssets( - TrustBackedAssetsCall::destroy_accounts { .. } - ) | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::destroy_approvals { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::finish_destroy { .. }) - | RuntimeCall::TrustBackedAssets( - TrustBackedAssetsCall::transfer_ownership { .. } - ) | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::set_team { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::set_metadata { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::clear_metadata { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::set_min_balance { .. }) + RuntimeCall::Assets(AssetsCall::create { .. }) + | RuntimeCall::Assets(AssetsCall::start_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) + | RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) + | RuntimeCall::Assets(AssetsCall::set_team { .. }) + | RuntimeCall::Assets(AssetsCall::set_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) @@ -58,15 +56,15 @@ impl InstanceFilter for ProxyType { ), ProxyType::AssetManager => matches!( c, - RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::mint { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::burn { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::freeze { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::block { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::thaw { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::freeze_asset { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::thaw_asset { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::touch_other { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::refund_other { .. }) + RuntimeCall::Assets(AssetsCall::mint { .. }) + | RuntimeCall::Assets(AssetsCall::burn { .. }) + | RuntimeCall::Assets(AssetsCall::freeze { .. }) + | RuntimeCall::Assets(AssetsCall::block { .. }) + | RuntimeCall::Assets(AssetsCall::thaw { .. }) + | RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) + | RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) + | RuntimeCall::Assets(AssetsCall::touch_other { .. }) + | RuntimeCall::Assets(AssetsCall::refund_other { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) diff --git a/runtime/devnet/src/extensions.rs b/runtime/devnet/src/extensions.rs index c1842fab2..d95adc70f 100644 --- a/runtime/devnet/src/extensions.rs +++ b/runtime/devnet/src/extensions.rs @@ -10,7 +10,7 @@ use pallet_contracts::chain_extension::{ }; use pop_primitives::{ cross_chain::CrossChainMessage, - storage_keys::{NftsKeys, ParachainSystemKeys, RuntimeStateKeys, TrustBackedAssetsKeys}, + storage_keys::{AssetsKeys, NftsKeys, ParachainSystemKeys, RuntimeStateKeys}, AssetId, CollectionId, ItemId, }; use sp_core::crypto::UncheckedFrom; @@ -25,7 +25,7 @@ use xcm::{ }; use crate::{ - assets_config::TrustBackedAssetsInstance, AccountId, AllowedPopApiCalls, RuntimeCall, + config::assets::TrustBackedAssetsInstance, AccountId, AllowedPopApiCalls, RuntimeCall, RuntimeOrigin, UNIT, }; @@ -222,9 +222,7 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, - RuntimeStateKeys::TrustBackedAssets(key) => { - read_trust_backed_assets_state::(key, &mut env) - }, + RuntimeStateKeys::Assets(key) => read_trust_backed_assets_state::(key, &mut env), }? .encode(); @@ -301,7 +299,7 @@ where } fn read_trust_backed_assets_state( - key: TrustBackedAssetsKeys, + key: AssetsKeys, env: &mut Environment, ) -> Result, DispatchError> where @@ -310,7 +308,7 @@ where E: Ext, { match key { - TrustBackedAssetsKeys::AssetExists(id) => { + AssetsKeys::AssetExists(id) => { env.charge_weight(T::DbWeight::get().reads(1_u64))?; Ok(pallet_assets::Pallet::::asset_exists(id).encode()) }, @@ -915,7 +913,7 @@ mod tests { // Create asset with contract as owner. assert_eq!( - TrustBackedAssets::force_create( + Assets::force_create( RuntimeOrigin::root(), asset_id.into(), addr.clone().into(), @@ -926,7 +924,7 @@ mod tests { ); // Check Bob's asset balance before minting through contract. - let bob_balance_before = TrustBackedAssets::balance(asset_id, &BOB); + let bob_balance_before = Assets::balance(asset_id, &BOB); assert_eq!(bob_balance_before, 0); let result = Contracts::bare_call( @@ -952,7 +950,7 @@ mod tests { // Check for revert assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - let bob_balance_after = TrustBackedAssets::balance(asset_id, &BOB); + let bob_balance_after = Assets::balance(asset_id, &BOB); assert_eq!(bob_balance_after, bob_balance_before + amount); }); } diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index 52a0938fe..a82be8046 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -254,40 +254,40 @@ impl Contains for FilteredCalls { pub struct AllowedPopApiCalls; impl Contains for crate::AllowedPopApiCalls { fn contains(c: &RuntimeCall) -> bool { - use assets_config::TrustBackedAssetsCall; + use config::assets::AssetsCall; use pallet_nfts::Call as NftsCall; matches!( c, RuntimeCall::Balances(BalancesCall::transfer_keep_alive { .. }) - | RuntimeCall::TrustBackedAssets( - TrustBackedAssetsCall::create { .. } - | TrustBackedAssetsCall::start_destroy { .. } - | TrustBackedAssetsCall::destroy_accounts { .. } - | TrustBackedAssetsCall::destroy_approvals { .. } - | TrustBackedAssetsCall::finish_destroy { .. } - | TrustBackedAssetsCall::mint { .. } - | TrustBackedAssetsCall::burn { .. } - | TrustBackedAssetsCall::transfer { .. } - | TrustBackedAssetsCall::transfer_keep_alive { .. } - | TrustBackedAssetsCall::force_transfer { .. } - | TrustBackedAssetsCall::freeze { .. } - | TrustBackedAssetsCall::thaw { .. } - | TrustBackedAssetsCall::freeze_asset { .. } - | TrustBackedAssetsCall::thaw_asset { .. } - | TrustBackedAssetsCall::transfer_ownership { .. } - | TrustBackedAssetsCall::set_team { .. } - | TrustBackedAssetsCall::set_metadata { .. } - | TrustBackedAssetsCall::clear_metadata { .. } - | TrustBackedAssetsCall::approve_transfer { .. } - | TrustBackedAssetsCall::cancel_approval { .. } - | TrustBackedAssetsCall::force_cancel_approval { .. } - | TrustBackedAssetsCall::transfer_approved { .. } - | TrustBackedAssetsCall::touch { .. } - | TrustBackedAssetsCall::refund { .. } - | TrustBackedAssetsCall::set_min_balance { .. } - | TrustBackedAssetsCall::touch_other { .. } - | TrustBackedAssetsCall::refund_other { .. } - | TrustBackedAssetsCall::block { .. } + | RuntimeCall::Assets( + AssetsCall::create { .. } + | AssetsCall::start_destroy { .. } + | AssetsCall::destroy_accounts { .. } + | AssetsCall::destroy_approvals { .. } + | AssetsCall::finish_destroy { .. } + | AssetsCall::mint { .. } + | AssetsCall::burn { .. } + | AssetsCall::transfer { .. } + | AssetsCall::transfer_keep_alive { .. } + | AssetsCall::force_transfer { .. } + | AssetsCall::freeze { .. } + | AssetsCall::thaw { .. } + | AssetsCall::freeze_asset { .. } + | AssetsCall::thaw_asset { .. } + | AssetsCall::transfer_ownership { .. } + | AssetsCall::set_team { .. } + | AssetsCall::set_metadata { .. } + | AssetsCall::clear_metadata { .. } + | AssetsCall::approve_transfer { .. } + | AssetsCall::cancel_approval { .. } + | AssetsCall::force_cancel_approval { .. } + | AssetsCall::transfer_approved { .. } + | AssetsCall::touch { .. } + | AssetsCall::refund { .. } + | AssetsCall::set_min_balance { .. } + | AssetsCall::touch_other { .. } + | AssetsCall::refund_other { .. } + | AssetsCall::block { .. } ) | RuntimeCall::Nfts( NftsCall::create { .. } | NftsCall::destroy { .. } @@ -662,7 +662,7 @@ construct_runtime!( // Assets Nfts: pallet_nfts = 50, NftFractionalization: pallet_nft_fractionalization = 51, - TrustBackedAssets: pallet_assets:: = 52, + Assets: pallet_assets:: = 52, } ); diff --git a/runtime/testnet/src/config/assets.rs b/runtime/testnet/src/config/assets.rs index f51f8875b..2c8ea952f 100644 --- a/runtime/testnet/src/config/assets.rs +++ b/runtime/testnet/src/config/assets.rs @@ -1,6 +1,6 @@ use crate::{ - deposit, AccountId, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, - RuntimeHoldReason, TrustBackedAssets, DAYS, EXISTENTIAL_DEPOSIT, UNIT, + deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, + RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT, }; use frame_support::{ parameter_types, @@ -86,7 +86,7 @@ impl pallet_nft_fractionalization::Config for Runtime { type NftId = ::ItemId; type AssetBalance = >::Balance; type AssetId = >::AssetId; - type Assets = TrustBackedAssets; + type Assets = Assets; type Nfts = Nfts; type PalletId = NftFractionalizationPalletId; type WeightInfo = pallet_nft_fractionalization::weights::SubstrateWeight; @@ -96,7 +96,7 @@ impl pallet_nft_fractionalization::Config for Runtime { } pub type TrustBackedAssetsInstance = pallet_assets::Instance1; -pub(crate) type TrustBackedAssetsCall = pallet_assets::Call; +pub(crate) type AssetsCall = pallet_assets::Call; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; diff --git a/runtime/testnet/src/config/proxy.rs b/runtime/testnet/src/config/proxy.rs index 79339565e..07d5f0f8e 100644 --- a/runtime/testnet/src/config/proxy.rs +++ b/runtime/testnet/src/config/proxy.rs @@ -1,4 +1,4 @@ -use super::assets::TrustBackedAssetsCall; +use super::assets::AssetsCall; use crate::{Balances, Runtime, RuntimeCall, RuntimeEvent}; use frame_support::traits::InstanceFilter; use pop_runtime_common::proxy::{ @@ -14,7 +14,7 @@ impl InstanceFilter for ProxyType { ProxyType::NonTransfer => !matches!( c, RuntimeCall::Balances { .. } - | RuntimeCall::TrustBackedAssets { .. } + | RuntimeCall::Assets { .. } | RuntimeCall::Nfts { .. } ), ProxyType::CancelProxy => matches!( @@ -26,7 +26,7 @@ impl InstanceFilter for ProxyType { ProxyType::Assets => { matches!( c, - RuntimeCall::TrustBackedAssets { .. } + RuntimeCall::Assets { .. } | RuntimeCall::Utility { .. } | RuntimeCall::Multisig { .. } | RuntimeCall::Nfts { .. } @@ -34,18 +34,16 @@ impl InstanceFilter for ProxyType { }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::create { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::start_destroy { .. }) - | RuntimeCall::TrustBackedAssets( - TrustBackedAssetsCall::destroy_accounts { .. } - ) | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::destroy_approvals { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::finish_destroy { .. }) - | RuntimeCall::TrustBackedAssets( - TrustBackedAssetsCall::transfer_ownership { .. } - ) | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::set_team { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::set_metadata { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::clear_metadata { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::set_min_balance { .. }) + RuntimeCall::Assets(AssetsCall::create { .. }) + | RuntimeCall::Assets(AssetsCall::start_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) + | RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) + | RuntimeCall::Assets(AssetsCall::set_team { .. }) + | RuntimeCall::Assets(AssetsCall::set_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) @@ -58,15 +56,15 @@ impl InstanceFilter for ProxyType { ), ProxyType::AssetManager => matches!( c, - RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::mint { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::burn { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::freeze { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::block { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::thaw { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::freeze_asset { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::thaw_asset { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::touch_other { .. }) - | RuntimeCall::TrustBackedAssets(TrustBackedAssetsCall::refund_other { .. }) + RuntimeCall::Assets(AssetsCall::mint { .. }) + | RuntimeCall::Assets(AssetsCall::burn { .. }) + | RuntimeCall::Assets(AssetsCall::freeze { .. }) + | RuntimeCall::Assets(AssetsCall::block { .. }) + | RuntimeCall::Assets(AssetsCall::thaw { .. }) + | RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) + | RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) + | RuntimeCall::Assets(AssetsCall::touch_other { .. }) + | RuntimeCall::Assets(AssetsCall::refund_other { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 2e857cd78..66a5092ce 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -630,7 +630,7 @@ construct_runtime!( // Assets Nfts: pallet_nfts = 50, NftFractionalization: pallet_nft_fractionalization = 51, - TrustBackedAssets: pallet_assets:: = 52, + Assets: pallet_assets:: = 52, } );