Skip to main content

ic_papi_guard/guards/
caller_pays_icrc2_tokens.rs

1//! Code to receive any ICRC-2 token as payment.
2
3// Well known ICRC-2 tokens
4// TODO
5
6use super::{PaymentError, PaymentGuardTrait};
7use candid::{Nat, Principal};
8use ic_cycles_ledger_client::TransferFromArgs;
9use ic_papi_api::{caller::TokenAmount, Account};
10
11pub struct CallerPaysIcrc2TokensPaymentGuard {
12    /// The ledger for that specific token
13    pub ledger: Principal,
14}
15
16impl PaymentGuardTrait for CallerPaysIcrc2TokensPaymentGuard {
17    async fn deduct(&self, cost: TokenAmount) -> Result<(), PaymentError> {
18        let caller = ic_cdk::api::caller();
19        ic_cycles_ledger_client::Service(self.ledger)
20            .icrc_2_transfer_from(&TransferFromArgs {
21                from: Account {
22                    owner: caller,
23                    subaccount: None,
24                },
25                to: Account {
26                    owner: ic_cdk::api::id(),
27                    subaccount: None,
28                },
29                amount: Nat::from(cost),
30                spender_subaccount: None,
31                created_at_time: None,
32                memo: None,
33                fee: None,
34            })
35            .await
36            .map_err(|(rejection_code, string)| {
37                eprintln!(
38                    "Failed to reach ledger canister at {}: {rejection_code:?}: {string}",
39                    self.ledger
40                );
41                PaymentError::LedgerUnreachable {
42                    ledger: self.ledger,
43                }
44            })?
45            .0
46            .map_err(|error| {
47                eprintln!(
48                    "Failed to withdraw from ledger canister at {}: {error:?}",
49                    self.ledger
50                );
51                PaymentError::LedgerTransferFromError {
52                    ledger: self.ledger,
53                    error,
54                }
55            })
56            .map(|_| ())
57    }
58}