1use crate::root::RootBucket;
7use crate::router::Router;
8use cap_common::{
9 GetIndexCanistersResponse, GetTokenContractRootBucketArg, GetTokenContractRootBucketResponse,
10 GetUserRootBucketsArg, GetUserRootBucketsResponse, WithWitnessArg,
11};
12use ic_kit::ic::call;
13use ic_kit::{Principal, RejectionCode};
14use thiserror::Error;
15
16#[derive(Clone)]
18pub struct Index(Principal);
19
20impl Index {
21 pub fn new(principal: Principal) -> Self {
23 Self(principal)
24 }
25
26 pub async fn get_token_contract_root_bucket(
28 &self,
29 contract: Principal,
30 ) -> Result<RootBucket, GetContractRootError> {
31 let result: (GetTokenContractRootBucketResponse,) = call(
32 self.0,
33 "get_token_contract_root_bucket",
34 (GetTokenContractRootBucketArg {
35 canister: contract,
36 witness: false,
37 },),
38 )
39 .await
40 .map_err(|err| GetContractRootError::Rejected(err.0, err.1))?;
41
42 if let Some(canister) = result.0.canister {
43 Ok(RootBucket(canister))
44 } else {
45 Err(GetContractRootError::InvalidContract)
46 }
47 }
48
49 pub async fn get_user_root_buckets(
51 &self,
52 user: Principal,
53 ) -> Result<Vec<RootBucket>, (RejectionCode, String)> {
54 let result: (GetUserRootBucketsResponse,) = call(
55 self.0,
56 "get_user_root_buckets",
57 (GetUserRootBucketsArg {
58 user,
59 witness: false,
60 },),
61 )
62 .await?;
63
64 Ok(result
65 .0
66 .contracts
67 .iter()
68 .map(|canister| RootBucket(*canister))
69 .collect())
70 }
71
72 pub async fn get_router_canisters(&self) -> Result<Vec<Router>, (RejectionCode, String)> {
74 let result: (GetIndexCanistersResponse,) = call(
75 self.0,
76 "get_router_canisters",
77 (WithWitnessArg { witness: false },),
78 )
79 .await?;
80
81 Ok(result
82 .0
83 .canisters
84 .iter()
85 .map(|canister| Router(*canister))
86 .collect())
87 }
88}
89
90impl From<Router> for Index {
91 fn from(router: Router) -> Self {
92 Index(router.0)
93 }
94}
95
96#[derive(Error, Debug)]
98pub enum GetContractRootError {
99 #[error("the query was rejected (TODO: Display here)")]
101 Rejected(RejectionCode, String),
102 #[error("no root found for the given contract")]
104 InvalidContract,
105}