1use std::{fmt::Display, str::FromStr};
4
5use url::Url;
6
7use crate::{
8 transport::{
9 FacilitatorPaymentRequest, FacilitatorSettleResponse, FacilitatorSupportedResponse,
10 FacilitatorVerifyResponse, PaymentRequirements,
11 },
12 types::{AmountValue, AnyJson, OutputSchema},
13};
14
15pub trait NetworkFamily {
17 fn network_name(&self) -> &str;
19}
20
21pub trait Address: FromStr + Display + Copy {
23 type Network: NetworkFamily;
24}
25
26pub trait Scheme {
28 type Network: NetworkFamily;
29 type Payload;
30 const SCHEME_NAME: &'static str;
31
32 fn network(&self) -> &Self::Network;
33
34 fn select<A: Address<Network = Self::Network>>(
35 &self,
36 pr: &PaymentRequirements,
37 ) -> Option<PaymentSelection<A>>
38 where
39 Self: Sized,
40 {
41 if pr.scheme == Self::SCHEME_NAME && pr.network == self.network().network_name() {
42 Some(PaymentSelection {
43 max_amount_required: pr.max_amount_required,
44 resource: pr.resource.clone(),
45 description: pr.description.clone(),
46 mime_type: pr.mime_type.clone(),
47 pay_to: pr.pay_to.parse().ok()?,
48 max_timeout_seconds: pr.max_timeout_seconds,
49 asset: pr.asset.parse().ok()?,
50 output_schema: pr.output_schema.clone(),
51 extra: pr.extra.clone(),
52 })
53 } else {
54 None
55 }
56 }
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61pub struct Asset<A: Address> {
62 pub address: A,
63 pub decimals: u8,
64 pub name: &'static str,
65 pub symbol: &'static str,
66}
67
68#[derive(Debug, Clone)]
70pub struct PaymentSelection<A: Address> {
71 pub max_amount_required: AmountValue,
73 pub resource: Url,
75 pub description: String,
77 pub mime_type: String,
79 pub pay_to: A,
81 pub max_timeout_seconds: u64,
83 pub asset: A,
85 pub output_schema: Option<OutputSchema>,
87 pub extra: Option<AnyJson>,
89}
90
91pub trait SchemeSigner<A: Address<Network = <Self::Scheme as Scheme>::Network>> {
93 type Scheme: Scheme;
94 type Error: std::error::Error;
95
96 fn sign(
97 &self,
98 selected: &PaymentSelection<A>,
99 ) -> impl Future<Output = Result<<Self::Scheme as Scheme>::Payload, Self::Error>>;
100}
101
102pub trait Facilitator {
104 type Error: std::error::Error;
105
106 fn supported(&self) -> impl Future<Output = Result<FacilitatorSupportedResponse, Self::Error>>;
107
108 fn verify(
109 &self,
110 request: FacilitatorPaymentRequest,
111 ) -> impl Future<Output = Result<FacilitatorVerifyResponse, Self::Error>>;
112
113 fn settle(
114 &self,
115 request: FacilitatorPaymentRequest,
116 ) -> impl Future<Output = Result<FacilitatorSettleResponse, Self::Error>>;
117}