1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use cosmwasm_std::{from_binary, HumanAddr, QuerierWrapper, StdError, StdResult};
use serde::de::DeserializeOwned;
use crate::query::*;
use crate::types::{AttributeValueType, Attributes, Marker, Name, Names, ProvenanceRoute};
static QUERY_DATAFMT_VERSION: &str = "2.0.0";
pub struct ProvenanceQuerier<'a> {
querier: &'a QuerierWrapper<'a>,
}
impl<'a> ProvenanceQuerier<'a> {
pub fn new(querier: &'a QuerierWrapper) -> Self {
ProvenanceQuerier { querier }
}
fn query_name_module(&self, params: NameQueryParams) -> StdResult<Names> {
let request = ProvenanceQuery {
route: ProvenanceRoute::Name,
params: params.into(),
version: String::from(QUERY_DATAFMT_VERSION),
};
let res: Names = self.querier.custom_query(&request.into())?;
Ok(res)
}
pub fn resolve_name(&self, name: String) -> StdResult<Name> {
let res = self.query_name_module(NameQueryParams::Resolve { name })?;
if res.records.len() != 1 {
return Err(StdError::generic_err(
"expected only one address bound to name",
));
}
Ok(res.records[0].clone())
}
pub fn lookup_names(&self, address: HumanAddr) -> StdResult<Names> {
self.query_name_module(NameQueryParams::Lookup { address })
}
fn query_attributes(&self, params: AttributeQueryParams) -> StdResult<Attributes> {
let request = ProvenanceQuery {
route: ProvenanceRoute::Attribute,
params: params.into(),
version: String::from(QUERY_DATAFMT_VERSION),
};
let res: Attributes = self.querier.custom_query(&request.into())?;
Ok(res)
}
pub fn get_attributes(
&self,
address: HumanAddr,
name: Option<String>,
) -> StdResult<Attributes> {
match name {
None => self.query_attributes(AttributeQueryParams::GetAllAttributes { address }),
Some(name) => {
self.query_attributes(AttributeQueryParams::GetAttributes { address, name })
}
}
}
pub fn get_json_attributes<T: DeserializeOwned>(
&self,
address: HumanAddr,
name: String,
) -> StdResult<Vec<T>> {
let resp = self.query_attributes(AttributeQueryParams::GetAttributes { address, name })?;
resp.attributes
.iter()
.filter(|a| a.value_type == AttributeValueType::Json)
.map(|a| from_binary(&a.value))
.collect()
}
fn query_marker(&self, params: MarkerQueryParams) -> StdResult<Marker> {
let request = ProvenanceQuery {
route: ProvenanceRoute::Marker,
params: params.into(),
version: String::from(QUERY_DATAFMT_VERSION),
};
let res: Marker = self.querier.custom_query(&request.into())?;
Ok(res)
}
pub fn get_marker_by_address(&self, address: HumanAddr) -> StdResult<Marker> {
self.query_marker(MarkerQueryParams::GetMarkerByAddress { address })
}
pub fn get_marker_by_denom(&self, denom: String) -> StdResult<Marker> {
self.query_marker(MarkerQueryParams::GetMarkerByDenom { denom })
}
}