Skip to content

Commit

Permalink
fix: pallet api error + missing docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Daanvdplas committed Jul 22, 2024
1 parent 68264da commit 2481773
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pallets/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ frame-system.workspace = true
pallet-assets.workspace = true
primitives.workspace = true
sp-runtime.workspace = true
sp-std.workspace = true

[dev-dependencies]
pallet-balances.workspace = true
Expand All @@ -46,6 +47,7 @@ std = [
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
]
try-runtime = [
"frame-support/try-runtime",
Expand Down
101 changes: 94 additions & 7 deletions pallets/api/src/fungibles/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![cfg_attr(not(feature = "std"), no_std)]

/// The fungibles pallet serves as a wrapper around the pallet_assets, offering a streamlined
/// interface for interacting with fungible assets. The goal is to provide a simplified, consistent
/// API that adheres to standards in the smart contract space.
pub use pallet::*;

#[cfg(test)]
Expand All @@ -17,6 +18,7 @@ pub mod pallet {
use frame_system::pallet_prelude::*;
use pallet_assets::WeightInfo;
use sp_runtime::{traits::StaticLookup, Saturating};
use sp_std::vec::Vec;

pub(crate) type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
pub(crate) type AssetIdOf<T> = <pallet_assets::Pallet<T, AssetsInstanceOf<T>> as Inspect<
Expand Down Expand Up @@ -60,6 +62,16 @@ pub mod pallet {

#[pallet::call]
impl<T: Config> Pallet<T> {
/// 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.
#[pallet::call_index(0)]
#[pallet::weight(AssetsWeightInfo::<T>::transfer_keep_alive())]
pub fn transfer(
Expand All @@ -72,15 +84,25 @@ pub mod pallet {
Assets::<T>::transfer_keep_alive(origin, id.into(), target, amount)
}

/// 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.
#[pallet::call_index(2)]
#[pallet::weight(AssetsWeightInfo::<T>::cancel_approval() + AssetsWeightInfo::<T>::approve_transfer())]
#[pallet::weight(T::DbWeight::get().reads(2) + AssetsWeightInfo::<T>::cancel_approval() + AssetsWeightInfo::<T>::approve_transfer())]
pub fn approve(
origin: OriginFor<T>,
id: AssetIdOf<T>,
spender: AccountIdOf<T>,
mut value: BalanceOf<T>,
) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin.clone())?;
let who = ensure_signed(origin.clone())
.map_err(|e| e.with_weight(T::DbWeight::get().reads(1)))?;
let current_allowance = Assets::<T>::allowance(id.clone(), &who, &spender);
let spender = T::Lookup::unlookup(spender);
let id: AssetIdParameterOf<T> = id.into();
Expand All @@ -91,17 +113,35 @@ pub mod pallet {
// If the new value is greater than the current allowance, approve the difference.
if value > current_allowance {
value.saturating_reduce(current_allowance);
Assets::<T>::approve_transfer(origin, id, spender, value)?;
Assets::<T>::approve_transfer(origin, id, spender, value).map_err(|e| {
e.with_weight(
T::DbWeight::get().reads(2) + AssetsWeightInfo::<T>::approve_transfer(),
)
})?;
} else {
// If the new value is less than the current allowance, cancel the approval and set the new value
Assets::<T>::cancel_approval(origin.clone(), id.clone(), spender.clone())
.map_err(|e| e.with_weight(AssetsWeightInfo::<T>::cancel_approval()))?;
Assets::<T>::cancel_approval(origin.clone(), id.clone(), spender.clone()).map_err(
|e| {
e.with_weight(
T::DbWeight::get().reads(2) + AssetsWeightInfo::<T>::cancel_approval(),
)
},
)?;
Assets::<T>::approve_transfer(origin, id, spender, value)?;
}

Ok(().into())
}

/// 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.
#[pallet::call_index(3)]
#[pallet::weight(AssetsWeightInfo::<T>::approve_transfer())]
pub fn increase_allowance(
Expand All @@ -116,14 +156,40 @@ pub mod pallet {
}

impl<T: Config> Pallet<T> {
/// 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: AssetIdOf<T>) -> BalanceOf<T> {
Assets::<T>::total_supply(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.
pub fn balance_of(id: AssetIdOf<T>, owner: &AccountIdOf<T>) -> BalanceOf<T> {
Assets::<T>::balance(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.
pub fn allowance(
id: AssetIdOf<T>,
owner: &AccountIdOf<T>,
Expand All @@ -132,14 +198,35 @@ pub mod pallet {
Assets::<T>::allowance(id, owner, spender)
}

/// 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.
pub fn token_name(id: AssetIdOf<T>) -> Vec<u8> {
<Assets<T> as MetadataInspect<AccountIdOf<T>>>::name(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.
pub fn token_symbol(id: AssetIdOf<T>) -> Vec<u8> {
<Assets<T> as MetadataInspect<AccountIdOf<T>>>::symbol(id)
}

/// 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.
pub fn token_decimals(id: AssetIdOf<T>) -> u8 {
<Assets<T> as MetadataInspect<AccountIdOf<T>>>::decimals(id)
}
Expand Down

0 comments on commit 2481773

Please sign in to comment.