1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

            
4
// Tanssi is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Tanssi is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Tanssi.  If not, see <http://www.gnu.org/licenses/>
16

            
17
//! RPC client for Author Noting pallet
18

            
19
pub use pallet_stream_payment_runtime_api::StreamPaymentApi as StreamPaymentRuntimeApi;
20
use {
21
    core::marker::PhantomData,
22
    jsonrpsee::{
23
        core::{async_trait, RpcResult},
24
        proc_macros::rpc,
25
    },
26
    pallet_stream_payment_runtime_api::{StreamPaymentApiError, StreamPaymentApiStatus},
27
    sp_api::ProvideRuntimeApi,
28
    sp_runtime::traits::Block as BlockT,
29
    std::sync::Arc,
30
};
31

            
32
/// Top-level error type for the RPC handler.
33
#[derive(Debug, thiserror::Error)]
34
pub enum Error {
35
    /// Failed to fetch API
36
    #[error("Failed to fetch API: {0}")]
37
    ApiError(sp_api::ApiError),
38

            
39
    /// Failed to fetch the current best header.
40
    #[error("Failed to fetch stream payment status: {0}")]
41
    StreamPaymentApiError(StreamPaymentApiError),
42
}
43

            
44
#[rpc(client, server)]
45
pub trait StreamPaymentApi<Hash, StreamId, Instant, Balance> {
46
    #[method(name = "tanssi_streamPaymentStatus")]
47
    async fn stream_payment_status(
48
        &self,
49
        block: Hash,
50
        stream_id: StreamId,
51
        now: Option<Instant>,
52
    ) -> RpcResult<StreamPaymentApiStatus<Balance>>;
53
}
54

            
55
pub struct StreamPayment<Client, Block> {
56
    client: Arc<Client>,
57
    _phantom: PhantomData<Block>,
58
}
59

            
60
impl<Client, Block> StreamPayment<Client, Block> {
61
388
    pub fn new(client: Arc<Client>) -> Self {
62
388
        Self {
63
388
            client,
64
388
            _phantom: PhantomData,
65
388
        }
66
388
    }
67
}
68

            
69
#[async_trait]
70
impl<Block, Hash, Client, StreamId, Instant, Balance>
71
    StreamPaymentApiServer<Hash, StreamId, Instant, Balance> for StreamPayment<Client, Block>
72
where
73
    Hash: Send + 'static,
74
    Block: BlockT<Hash = Hash>,
75
    Client: ProvideRuntimeApi<Block> + Sync + Send + 'static,
76
    Client::Api: StreamPaymentRuntimeApi<Block, StreamId, Instant, Balance>,
77
    StreamId: parity_scale_codec::Codec + Send + 'static,
78
    Instant: parity_scale_codec::Codec + Send + 'static,
79
    Balance: parity_scale_codec::Codec + Send + 'static,
80
{
81
    async fn stream_payment_status(
82
        &self,
83
        block: Hash,
84
        stream_id: StreamId,
85
        now: Option<Instant>,
86
18
    ) -> RpcResult<StreamPaymentApiStatus<Balance>> {
87
18
        let status = self
88
18
            .client
89
18
            .runtime_api()
90
18
            .stream_payment_status(block, stream_id, now)
91
18
            .map_err(|e| internal_err(Error::ApiError(e)))?
92
18
            .map_err(|e| internal_err(Error::StreamPaymentApiError(e)))?;
93

            
94
14
        Ok(status)
95
36
    }
96
}
97

            
98
4
pub fn internal_err<T: ToString>(message: T) -> jsonrpsee::types::ErrorObjectOwned {
99
4
    jsonrpsee::types::error::ErrorObject::borrowed(
100
4
        jsonrpsee::types::error::INTERNAL_ERROR_CODE,
101
4
        &message.to_string(),
102
4
        None,
103
4
    )
104
4
    .into_owned()
105
4
}