use candid::CandidType;
use serde::{Deserialize, Serialize};
use crate::{
canister::{call::call_canister, fetch_tuple0, types::CanisterCallResult},
identity::CanisterId,
};
use super::{
icrc1::Icrc1Memo,
types::{Icrc1Account, Icrc1Subaccount},
};
#[derive(CandidType, Serialize, Deserialize, Debug, Clone)]
pub struct Icrc2AllowanceArgs {
pub account: Icrc1Account,
pub spender: Icrc1Account,
}
#[derive(CandidType, Serialize, Deserialize, Debug, Clone)]
pub struct Icrc2Allowance {
pub allowance: candid::Nat,
pub expires_at: Option<u64>,
}
#[allow(unused)]
pub async fn icrc2_allowance(
canister_id: CanisterId,
args: Icrc2AllowanceArgs,
) -> CanisterCallResult<Icrc2Allowance> {
call_canister::<_, (Icrc2Allowance,)>(canister_id, "icrc2_allowance", (args,))
.await
.map(fetch_tuple0)
}
#[derive(CandidType, Serialize, Deserialize, Debug, Clone)]
pub struct Icrc2ApproveArgs {
pub from_subaccount: Option<Icrc1Subaccount>,
pub spender: Icrc1Account,
pub amount: candid::Nat,
pub fee: Option<candid::Nat>,
pub memo: Option<Icrc1Memo>,
pub created_at_time: Option<u64>,
pub expected_allowance: Option<candid::Nat>,
pub expires_at: Option<u64>,
}
#[derive(CandidType, Serialize, Deserialize, Debug, Clone)]
pub enum Icrc2ApproveError {
GenericError {
error_code: candid::Nat,
message: String,
},
TemporarilyUnavailable,
Duplicate {
duplicate_of: candid::Nat,
},
BadFee {
expected_fee: candid::Nat,
},
AllowanceChanged {
current_allowance: candid::Nat,
},
CreatedInFuture {
ledger_time: u64,
},
TooOld,
Expired {
ledger_time: u64,
},
InsufficientFunds {
balance: candid::Nat,
},
}
pub type Icrc2ApproveResult = Result<candid::Nat, Icrc2ApproveError>;
#[allow(unused)]
pub async fn icrc2_approve(
canister_id: CanisterId,
args: Icrc2ApproveArgs,
) -> CanisterCallResult<Icrc2ApproveResult> {
call_canister::<_, (Icrc2ApproveResult,)>(canister_id, "icrc2_approve", (args,))
.await
.map(fetch_tuple0)
}
#[derive(CandidType, Serialize, Deserialize, Debug, Clone)]
pub struct Icrc2TransferFromArgs {
spender_subaccount: Option<Icrc1Subaccount>,
from: Icrc1Account,
to: Icrc1Account,
amount: candid::Nat,
fee: Option<candid::Nat>,
memo: Option<Icrc1Memo>,
created_at_time: Option<u64>,
}
#[derive(CandidType, Serialize, Deserialize, Debug, Clone)]
pub enum Icrc2TransferFromError {
GenericError {
error_code: candid::Nat,
message: String,
},
TemporarilyUnavailable,
InsufficientAllowance {
allowance: candid::Nat,
},
BadBurn {
min_burn_amount: candid::Nat,
},
Duplicate {
duplicate_of: candid::Nat,
},
BadFee {
expected_fee: candid::Nat,
},
CreatedInFuture {
ledger_time: u64,
},
TooOld,
InsufficientFunds {
balance: candid::Nat,
},
}
pub type Icrc1TransferFromResult = Result<candid::Nat, Icrc2TransferFromError>;
#[allow(unused)]
pub async fn icrc2_transfer_from(
canister_id: CanisterId,
args: Icrc2TransferFromArgs,
) -> CanisterCallResult<Icrc1TransferFromResult> {
call_canister::<_, (Icrc1TransferFromResult,)>(canister_id, "icrc2_transfer_from", (args,))
.await
.map(fetch_tuple0)
}