ic_papi_guard/guards/
any.rs1use candid::{CandidType, Deserialize, Principal};
4use ic_papi_api::{
5 caller::{CallerPaysIcrc2Tokens, PatronPaysIcrc2Cycles, PatronPaysIcrc2Tokens, TokenAmount},
6 PaymentError, PaymentType,
7};
8
9use super::{
10 attached_cycles::AttachedCyclesPayment,
11 caller_pays_icrc2_cycles::CallerPaysIcrc2CyclesPaymentGuard,
12 caller_pays_icrc2_tokens::CallerPaysIcrc2TokensPaymentGuard,
13 patron_pays_icrc2_cycles::PatronPaysIcrc2CyclesPaymentGuard,
14 patron_pays_icrc2_tokens::PatronPaysIcrc2TokensPaymentGuard, PaymentGuardTrait,
15};
16
17pub struct PaymentGuard<const CAP: usize> {
19 pub supported: [VendorPaymentConfig; CAP],
20}
21
22#[derive(Debug, Clone, Eq, PartialEq)]
24pub enum VendorPaymentConfig {
25 AttachedCycles,
27 CallerPaysIcrc2Cycles,
29 PatronPaysIcrc2Cycles,
31 CallerPaysIcrc2Tokens { ledger: Principal },
33 PatronPaysIcrc2Tokens { ledger: Principal },
36}
37
38#[derive(Debug, Clone, Eq, PartialEq, CandidType, Deserialize)]
40pub enum PaymentWithConfig {
41 AttachedCycles,
42 CallerPaysIcrc2Cycles,
43 PatronPaysIcrc2Cycles(PatronPaysIcrc2Cycles),
44 CallerPaysIcrc2Tokens(CallerPaysIcrc2Tokens),
45 PatronPaysIcrc2Tokens(PatronPaysIcrc2Tokens),
46}
47
48impl<const CAP: usize> PaymentGuard<CAP> {
49 pub async fn deduct(&self, payment: PaymentType, fee: TokenAmount) -> Result<(), PaymentError> {
50 let payment_config = self
51 .config(payment)
52 .ok_or(PaymentError::UnsupportedPaymentType)?;
53 match payment_config {
54 PaymentWithConfig::AttachedCycles => AttachedCyclesPayment {}.deduct(fee).await,
55 PaymentWithConfig::CallerPaysIcrc2Cycles => {
56 CallerPaysIcrc2CyclesPaymentGuard {}.deduct(fee).await
57 }
58 PaymentWithConfig::PatronPaysIcrc2Cycles(patron) => {
59 PatronPaysIcrc2CyclesPaymentGuard { patron }
60 .deduct(fee)
61 .await
62 }
63 PaymentWithConfig::CallerPaysIcrc2Tokens(CallerPaysIcrc2Tokens { ledger }) => {
64 CallerPaysIcrc2TokensPaymentGuard { ledger }
65 .deduct(fee)
66 .await
67 }
68 PaymentWithConfig::PatronPaysIcrc2Tokens(payment_type) => {
69 PatronPaysIcrc2TokensPaymentGuard {
70 ledger: payment_type.ledger,
71 patron: payment_type.patron,
72 }
73 .deduct(fee)
74 .await
75 }
76 }
77 }
78}
79impl<const CAP: usize> PaymentGuard<CAP> {
80 #[must_use]
82 pub fn config(&self, payment: PaymentType) -> Option<PaymentWithConfig> {
83 match payment {
84 PaymentType::AttachedCycles => self
85 .supported
86 .iter()
87 .find(|&x| *x == VendorPaymentConfig::AttachedCycles)
88 .map(|_| PaymentWithConfig::AttachedCycles),
89 PaymentType::CallerPaysIcrc2Cycles => self
90 .supported
91 .iter()
92 .find(|&x| *x == VendorPaymentConfig::CallerPaysIcrc2Cycles)
93 .map(|_| PaymentWithConfig::CallerPaysIcrc2Cycles),
94 PaymentType::PatronPaysIcrc2Cycles(patron) => self
95 .supported
96 .iter()
97 .find(|&x| *x == VendorPaymentConfig::PatronPaysIcrc2Cycles)
98 .map(|_| PaymentWithConfig::PatronPaysIcrc2Cycles(patron)),
99 PaymentType::CallerPaysIcrc2Tokens(payment_type) => self
100 .supported
101 .iter()
102 .find(|&x| {
103 *x == VendorPaymentConfig::CallerPaysIcrc2Tokens {
104 ledger: payment_type.ledger,
105 }
106 })
107 .map(|_| PaymentWithConfig::CallerPaysIcrc2Tokens(payment_type)),
108 PaymentType::PatronPaysIcrc2Tokens(payment_type) => self
109 .supported
110 .iter()
111 .find(|&x| {
112 *x == VendorPaymentConfig::PatronPaysIcrc2Tokens {
113 ledger: payment_type.ledger,
114 }
115 })
116 .map(|_| PaymentWithConfig::PatronPaysIcrc2Tokens(payment_type)),
117 _ => None,
118 }
119 }
120}