sei_cosmwasm/querier.rs
1use cosmwasm_std::{Addr, QuerierWrapper, StdResult, Uint128};
2use cw20::{BalanceResponse, TokenInfoResponse};
3
4use crate::query::{
5 DenomAuthorityMetadataResponse, DenomsFromCreatorResponse, DexTwapsResponse, EpochResponse,
6 Erc20AllowanceResponse, Erc721ApprovedResponse, Erc721IsApprovedForAllResponse,
7 Erc721NameSymbolResponse, Erc721OwnerResponse, Erc721UriResponse, ErcPayloadResponse,
8 EvmAddressResponse, ExchangeRatesResponse, GetLatestPriceResponse, GetOrderByIdResponse,
9 GetOrdersResponse, OracleTwapsResponse, OrderSimulationResponse, SeiAddressResponse, SeiQuery,
10 SeiQueryWrapper, StaticCallResponse,
11};
12use crate::route::SeiRoute;
13use crate::Order;
14
15/// This is a helper wrapper to easily use our custom queries
16pub struct SeiQuerier<'a> {
17 querier: &'a QuerierWrapper<'a, SeiQueryWrapper>,
18}
19
20impl<'a> SeiQuerier<'a> {
21 pub fn new(querier: &'a QuerierWrapper<SeiQueryWrapper>) -> Self {
22 SeiQuerier { querier }
23 }
24
25 /*
26 query oracle module
27 */
28 pub fn query_exchange_rates(&self) -> StdResult<ExchangeRatesResponse> {
29 let request = SeiQueryWrapper {
30 route: SeiRoute::Oracle,
31 query_data: SeiQuery::ExchangeRates {},
32 }
33 .into();
34
35 self.querier.query(&request)
36 }
37
38 pub fn query_oracle_twaps(&self, lookback_seconds: u64) -> StdResult<OracleTwapsResponse> {
39 let request = SeiQueryWrapper {
40 route: SeiRoute::Oracle,
41 query_data: SeiQuery::OracleTwaps { lookback_seconds },
42 }
43 .into();
44
45 self.querier.query(&request)
46 }
47
48 /*
49 query dex module
50 */
51 pub fn query_dex_twaps(
52 &self,
53 lookback_seconds: u64,
54 contract_address: Addr,
55 ) -> StdResult<DexTwapsResponse> {
56 let request = SeiQueryWrapper {
57 route: SeiRoute::Dex,
58 query_data: SeiQuery::DexTwaps {
59 contract_address,
60 lookback_seconds,
61 },
62 }
63 .into();
64
65 self.querier.query(&request)
66 }
67
68 pub fn query_order_simulation(
69 &self,
70 order: Order,
71 contract_address: Addr,
72 ) -> StdResult<OrderSimulationResponse> {
73 let request = SeiQueryWrapper {
74 route: SeiRoute::Dex,
75 query_data: SeiQuery::OrderSimulation {
76 contract_address,
77 order,
78 },
79 }
80 .into();
81
82 self.querier.query(&request)
83 }
84
85 pub fn query_get_orders(
86 &self,
87 contract_address: Addr,
88 account: Addr,
89 ) -> StdResult<GetOrdersResponse> {
90 let request = SeiQueryWrapper {
91 route: SeiRoute::Dex,
92 query_data: SeiQuery::GetOrders {
93 contract_address,
94 account,
95 },
96 }
97 .into();
98 self.querier.query(&request)
99 }
100
101 pub fn query_get_order_by_id(
102 &self,
103 contract_address: Addr,
104 price_denom: String,
105 asset_denom: String,
106 order_id: u64,
107 ) -> StdResult<GetOrderByIdResponse> {
108 let request = SeiQueryWrapper {
109 route: SeiRoute::Dex,
110 query_data: SeiQuery::GetOrderById {
111 contract_address,
112 price_denom,
113 asset_denom,
114 id: order_id,
115 },
116 }
117 .into();
118 self.querier.query(&request)
119 }
120
121 /*
122 query epoch module
123 */
124 pub fn query_epoch(&self) -> StdResult<EpochResponse> {
125 let request = SeiQueryWrapper {
126 route: SeiRoute::Epoch,
127 query_data: SeiQuery::Epoch {},
128 }
129 .into();
130 self.querier.query(&request)
131 }
132
133 pub fn query_get_latest_price(
134 &self,
135 contract_address: Addr,
136 price_denom: String,
137 asset_denom: String,
138 ) -> StdResult<GetLatestPriceResponse> {
139 let request = SeiQueryWrapper {
140 route: SeiRoute::Dex,
141 query_data: SeiQuery::GetLatestPrice {
142 contract_address,
143 price_denom,
144 asset_denom,
145 },
146 }
147 .into();
148 self.querier.query(&request)
149 }
150
151 /*
152 query tokenfactory module
153 */
154 pub fn query_denom_authority_metadata(
155 &self,
156 denom: String,
157 ) -> StdResult<DenomAuthorityMetadataResponse> {
158 let request = SeiQueryWrapper {
159 route: SeiRoute::Tokenfactory,
160 query_data: SeiQuery::DenomAuthorityMetadata { denom },
161 }
162 .into();
163 self.querier.query(&request)
164 }
165
166 pub fn query_denoms_from_creator(&self, creator: Addr) -> StdResult<DenomsFromCreatorResponse> {
167 let request = SeiQueryWrapper {
168 route: SeiRoute::Tokenfactory,
169 query_data: SeiQuery::DenomsFromCreator { creator },
170 }
171 .into();
172 self.querier.query(&request)
173 }
174
175 /// Calls the EVM contract deployed at the `to` address with the given `data`.
176 /// The from address is the caller's Sei native (bech32-encoded 'sei*') address.
177 /// Please note that the CW contract has to be in the allow list in order to execute a delegate
178 /// call.
179 ///
180 /// The EVM (Solidity) contract `msg.sender` in this case will be the caller's address.
181 ///
182 /// # Arguments
183 /// * `from` - Sei native (bech32-encoded 'sei*') address of the caller.
184 /// * `to` - The address of the EVM contract to call.
185 /// * `data` - Base64 encoded data to pass to the contract.
186 ///
187 /// # Returns
188 ///
189 /// * `StdResult<StaticCallResponse>` - A standard result that wraps the `StaticCallResponse`
190 /// struct.
191 ///
192 /// # Errors
193 /// This function will return an error if the query to the EVM fails.
194 pub fn static_call(
195 &self,
196 from: String,
197 to: String,
198 data: String,
199 ) -> StdResult<StaticCallResponse> {
200 let request = SeiQueryWrapper {
201 route: SeiRoute::Evm,
202 query_data: SeiQuery::StaticCall { from, to, data },
203 }
204 .into();
205
206 self.querier.query(&request)
207 }
208
209 /// Query to get hex payload for the ERC-20 `transfer` function
210 ///
211 /// # Arguments
212 /// * `recipient` - Recipient Sei native (bech32-encoded 'sei*') address.
213 /// * `amount` - The amount to transfer.
214 ///
215 /// # Returns
216 ///
217 /// * `StdResult<ErcPayloadResponse>` - A standard result that wraps the `ErcPayloadResponse`
218 /// struct. The `ErcPayloadResponse` struct contains the base64-encoded bytes.
219 ///
220 /// # Errors
221 /// This function will return an error if the query fails.
222 pub fn erc20_transfer_payload(
223 &self,
224 recipient: String,
225 amount: Uint128,
226 ) -> StdResult<ErcPayloadResponse> {
227 let request = SeiQueryWrapper {
228 route: SeiRoute::Evm,
229 query_data: SeiQuery::Erc20TransferPayload { recipient, amount },
230 }
231 .into();
232
233 self.querier.query(&request)
234 }
235
236 /// Query to get hex payload for the ERC-20 `transferFrom` function
237 ///
238 /// # Arguments
239 /// * `owner` - Owner Sei native (bech32-encoded 'sei*') address.
240 /// * `recipient` - Recipient Sei native (bech32-encoded 'sei*') address.
241 /// * `amount` - The amount to transfer.
242 ///
243 /// # Returns
244 ///
245 /// * `StdResult<ErcPayloadResponse>` - A standard result that wraps the `ErcPayloadResponse`
246 /// struct. The `ErcPayloadResponse` struct contains the base64-encoded bytes.
247 ///
248 /// # Errors
249 /// This function will return an error if the query fails.
250 pub fn erc20_transfer_from_payload(
251 &self,
252 owner: String,
253 recipient: String,
254 amount: Uint128,
255 ) -> StdResult<ErcPayloadResponse> {
256 let request = SeiQueryWrapper {
257 route: SeiRoute::Evm,
258 query_data: SeiQuery::Erc20TransferFromPayload {
259 owner,
260 recipient,
261 amount,
262 },
263 }
264 .into();
265
266 self.querier.query(&request)
267 }
268
269 /// Query to get hex payload for the ERC-20 `approve` function
270 ///
271 /// # Arguments
272 /// * `spender` - Spender Sei native (bech32-encoded 'sei*') address.
273 /// * `amount` - The amount to approve.
274 ///
275 /// # Returns
276 /// * `StdResult<ErcPayloadResponse>` - A standard result that wraps the `ErcPayloadResponse`
277 /// struct. The `ErcPayloadResponse` struct contains the base64-encoded bytes.
278 ///
279 /// # Errors
280 /// This function will return an error if the query fails.
281 pub fn erc20_approve_payload(
282 &self,
283 spender: String,
284 amount: Uint128,
285 ) -> StdResult<ErcPayloadResponse> {
286 let request = SeiQueryWrapper {
287 route: SeiRoute::Evm,
288 query_data: SeiQuery::Erc20ApprovePayload { spender, amount },
289 }
290 .into();
291
292 self.querier.query(&request)
293 }
294
295 /// Query to get the remaining number of tokens that spender will be allowed to spend on behalf
296 /// of owner through
297 ///
298 /// # Arguments
299 /// * `contract_address` - The contract address of the ERC-20 token.
300 /// * `owner` - Owner Sei native (bech32-encoded 'sei*') address.
301 /// * `spender` - Spender Sei native (bech32-encoded 'sei*') address.
302 ///
303 /// # Returns
304 /// * `StdResult<Erc20AllowanceResponse>` - A standard result that wraps the
305 /// `Erc20AllowanceResponse`. `Erc20AllowanceResponse` contains the amount which spender
306 /// is still allowed to withdraw from owner
307 ///
308 /// # Errors
309 /// This function will return an error if the query fails.
310 pub fn erc20_allowance(
311 &self,
312 contract_address: String,
313 owner: String,
314 spender: String,
315 ) -> StdResult<Erc20AllowanceResponse> {
316 let request = SeiQueryWrapper {
317 route: SeiRoute::Evm,
318 query_data: SeiQuery::Erc20Allowance {
319 contract_address,
320 owner,
321 spender,
322 },
323 }
324 .into();
325
326 self.querier.query(&request)
327 }
328
329 /// Query to get the token info, including the name, symbol, decimals and total supply
330 ///
331 /// # Arguments
332 /// * `contract_address` - The contract address of the ERC-20 token.
333 /// * `caller` - Caller Sei native (bech32-encoded 'sei*') address.
334 ///
335 /// # Returns
336 /// * `StdResult<TokenInfoResponse>` - A standard result that wraps the `TokenInfoResponse`.
337 ///
338 /// # Errors
339 /// This function will return an error if the query fails.
340 pub fn erc20_token_info(
341 &self,
342 contract_address: String,
343 caller: String,
344 ) -> StdResult<TokenInfoResponse> {
345 let request = SeiQueryWrapper {
346 route: SeiRoute::Evm,
347 query_data: SeiQuery::Erc20TokenInfo {
348 contract_address,
349 caller,
350 },
351 }
352 .into();
353
354 self.querier.query(&request)
355 }
356
357 /// Query to get the balance of the account with the given address.
358 /// Executes the `balanceOf` ERC-20 function under the hood.
359 ///
360 /// # Arguments
361 /// * `contract_address` - The contract address of the ERC-20 token.
362 /// * `account` - Sei native (bech32-encoded 'sei*') account address.
363 ///
364 /// # Returns
365 /// * `StdResult<BalanceResponse>` - A standard result that wraps the `BalanceResponse`.
366 ///
367 /// # Errors
368 /// This function will return an error if the query fails.
369 pub fn erc20_balance(
370 &self,
371 contract_address: String,
372 account: String,
373 ) -> StdResult<BalanceResponse> {
374 let request = SeiQueryWrapper {
375 route: SeiRoute::Evm,
376 query_data: SeiQuery::Erc20Balance {
377 contract_address,
378 account,
379 },
380 }
381 .into();
382
383 self.querier.query(&request)
384 }
385
386 /// Query to get the address of the owner of the NFT.
387 /// Executes ERC-721 `ownerOf` function under the hood.
388 ///
389 /// # Arguments
390 /// * `caller` - Caller Sei native (bech32-encoded 'sei*') address.
391 /// * `contract_address` - The contract address of the ERC-721 token.
392 /// * `token_id` - The identifier for an NFT. String representation of the token ID.
393 ///
394 /// # Returns
395 /// * `StdResult<Erc721OwnerResponse>` - A standard result that wraps the `Erc721OwnerResponse`.
396 ///
397 /// # Errors
398 /// This function will return an error if the query fails.
399 pub fn erc721_owner(
400 &self,
401 caller: String,
402 contract_address: String,
403 token_id: String,
404 ) -> StdResult<Erc721OwnerResponse> {
405 let request = SeiQueryWrapper {
406 route: SeiRoute::Evm,
407 query_data: SeiQuery::Erc721Owner {
408 caller,
409 contract_address,
410 token_id,
411 },
412 }
413 .into();
414
415 self.querier.query(&request)
416 }
417
418 /// Query to get the approved address for a single NFT. Executes ERC-721 `getApproved` function.
419 ///
420 /// # Arguments
421 /// * `caller` - Caller Sei native (bech32-encoded 'sei*') address.
422 /// * `contract_address` - The contract address of the ERC-721 token.
423 /// * `token_id` - The identifier for an NFT. String representation of the token ID.
424 ///
425 /// # Returns
426 /// * `StdResult<Erc721ApprovedResponse>` - A standard result that wraps the
427 /// `Erc721ApprovedResponse`.
428 ///
429 /// # Errors
430 /// This function will return an error if the query fails.
431 pub fn erc721_approved(
432 &self,
433 caller: String,
434 contract_address: String,
435 token_id: String,
436 ) -> StdResult<Erc721ApprovedResponse> {
437 let request = SeiQueryWrapper {
438 route: SeiRoute::Evm,
439 query_data: SeiQuery::Erc721Approved {
440 caller,
441 contract_address,
442 token_id,
443 },
444 }
445 .into();
446
447 self.querier.query(&request)
448 }
449
450 /// Query if an address is an authorized operator for another address. Executes ERC-721
451 /// `isApprovedForAll` function.
452 ///
453 /// # Arguments
454 /// * `caller` - Caller Sei native (bech32-encoded 'sei*') address.
455 /// * `contract_address` - The contract address of the ERC-721 token.
456 /// * `owner` - The owner of the NFT Sei native (bech32-encoded 'sei*') address
457 /// * `operator` - The operator Sei address that acts on behalf of the owner
458 ///
459 /// # Returns
460 /// * `StdResult<Erc721IsApprovedForAllResponse>` - A standard result that wraps the
461 /// `Erc721IsApprovedForAllResponse`.
462 ///
463 /// # Errors
464 /// This function will return an error if the query fails.
465 pub fn erc721_is_approved_for_all(
466 &self,
467 caller: String,
468 contract_address: String,
469 owner: String,
470 operator: String,
471 ) -> StdResult<Erc721IsApprovedForAllResponse> {
472 let request = SeiQueryWrapper {
473 route: SeiRoute::Evm,
474 query_data: SeiQuery::Erc721IsApprovedForAll {
475 caller,
476 contract_address,
477 owner,
478 operator,
479 },
480 }
481 .into();
482
483 self.querier.query(&request)
484 }
485
486 /// Query to get the name and symbol of the ERC-721 contract. Executes ERC-721 `name` and
487 /// `symbol` functions under the hood.
488 ///
489 /// # Arguments
490 /// * `caller` - Caller Sei native (bech32-encoded 'sei*') address.
491 /// * `contract_address` - The contract address of the ERC-721 token.
492 ///
493 /// # Returns
494 /// * `StdResult<Erc721NameSymbolResponse>` - A standard result that wraps the
495 /// `Erc721NameSymbolResponse`.
496 ///
497 /// # Errors
498 /// This function will return an error if the query fails.
499 pub fn erc721_name_symbol(
500 &self,
501 caller: String,
502 contract_address: String,
503 ) -> StdResult<Erc721NameSymbolResponse> {
504 let request = SeiQueryWrapper {
505 route: SeiRoute::Evm,
506 query_data: SeiQuery::Erc721NameSymbol {
507 caller,
508 contract_address,
509 },
510 }
511 .into();
512
513 self.querier.query(&request)
514 }
515
516 /// Query to get the URI for a given NFT. Executes ERC-721 `tokenURI` function under the hood.
517 ///
518 /// # Arguments
519 /// * `caller` - Caller Sei native (bech32-encoded 'sei*') address.
520 /// * `contract_address` - The contract address of the ERC-721 token.
521 /// * `token_id` - The identifier for an NFT. String representation of the token ID.
522 ///
523 /// # Returns
524 /// * `StdResult<Erc721UriResponse>` - A standard result that wraps the `Erc721UriResponse`.
525 ///
526 /// # Errors
527 /// This function will return an error if the query fails.
528 pub fn erc721_uri(
529 &self,
530 caller: String,
531 contract_address: String,
532 token_id: String,
533 ) -> StdResult<Erc721UriResponse> {
534 let request = SeiQueryWrapper {
535 route: SeiRoute::Evm,
536 query_data: SeiQuery::Erc721Uri {
537 caller,
538 contract_address,
539 token_id,
540 },
541 }
542 .into();
543
544 self.querier.query(&request)
545 }
546
547 /// Query to get the hex payload for the ERC-721 `transferFrom` function
548 ///
549 /// # Arguments
550 /// * `from` - Sender Sei native (bech32-encoded 'sei*') address.
551 /// * `recipient` - Recipient Sei native (bech32-encoded 'sei*') address.
552 /// * `token_id` - The identifier for an NFT. String representation of the token ID.
553 ///
554 /// # Returns
555 /// * `StdResult<ErcPayloadResponse>` - A standard result that wraps the `ErcPayloadResponse`.
556 /// `ErcPayloadResponse` contains the base64-encoded bytes.
557 ///
558 /// # Errors
559 /// This function will return an error if the query fails.
560 pub fn erc721_transfer_payload(
561 &self,
562 from: String,
563 recipient: String,
564 token_id: String,
565 ) -> StdResult<ErcPayloadResponse> {
566 let request = SeiQueryWrapper {
567 route: SeiRoute::Evm,
568 query_data: SeiQuery::Erc721TransferPayload {
569 from,
570 recipient,
571 token_id,
572 },
573 }
574 .into();
575
576 self.querier.query(&request)
577 }
578
579 /// Query to get the hex payload for the ERC-721 `approve` function
580 ///
581 /// # Arguments
582 /// * `spender` - Spender Sei native (bech32-encoded 'sei*') address.
583 /// * `token_id` - The identifier for an NFT. String representation of the token ID.
584 ///
585 /// # Returns
586 /// * `StdResult<ErcPayloadResponse>` - A standard result that wraps the `ErcPayloadResponse`.
587 /// `ErcPayloadResponse` contains the base64-encoded bytes.
588 ///
589 /// # Errors
590 /// This function will return an error if the query fails.
591 pub fn erc721_approve_payload(
592 &self,
593 spender: String,
594 token_id: String,
595 ) -> StdResult<ErcPayloadResponse> {
596 let request = SeiQueryWrapper {
597 route: SeiRoute::Evm,
598 query_data: SeiQuery::Erc721ApprovePayload { spender, token_id },
599 }
600 .into();
601
602 self.querier.query(&request)
603 }
604
605 /// Query to get the hex payload for the ERC-721 `setApprovalForAll` function.
606 ///
607 /// # Arguments
608 /// * `to` - Sei native (bech32-encoded 'sei*') address of the operator
609 /// * `approved` - Boolean representing the status to set
610 ///
611 /// # Returns
612 /// * `StdResult<ErcPayloadResponse>` - A standard result that wraps the `ErcPayloadResponse`.
613 /// `ErcPayloadResponse` contains the base64-encoded bytes.
614 ///
615 /// # Errors
616 /// This function will return an error if the query fails.
617 pub fn erc721_set_approval_all_payload(
618 &self,
619 to: String,
620 approved: bool,
621 ) -> StdResult<ErcPayloadResponse> {
622 let request = SeiQueryWrapper {
623 route: SeiRoute::Evm,
624 query_data: SeiQuery::Erc721SetApprovalAllPayload { to, approved },
625 }
626 .into();
627
628 self.querier.query(&request)
629 }
630
631 /// Queries the EVM (Ethereum Virtual Machine) address associated with a given Sei address.
632 ///
633 /// This function takes a `sei_address` as a parameter, which is a `String` representing the
634 /// SEI address. It returns a `StdResult<EvmAddressResponse>`, which is a standard result type
635 /// in the `cosmwasm_std` library. The `EvmAddressResponse` struct contains the EVM address and
636 /// a boolean indicating whether the EVM address is associated.
637 ///
638 /// # Arguments
639 ///
640 /// * `sei_address` - A `String` that represents the Sei native (bech32-encoded 'sei*') address.
641 ///
642 /// # Returns
643 ///
644 /// * `StdResult<EvmAddressResponse>` - A standard result that wraps the `EvmAddressResponse`
645 /// struct. `EvmAddressResponse` contains the EVM address and a boolean indicating whether the
646 /// EVM address is associated. If the Sei address is not associated with any EVM address,
647 /// the EVM address will be an empty string.
648 ///
649 ///
650 /// # Errors
651 ///
652 /// This function will return an error if the query to the EVM fails.
653 pub fn get_evm_address(&self, sei_address: String) -> StdResult<EvmAddressResponse> {
654 let request = SeiQueryWrapper {
655 route: SeiRoute::Evm,
656 query_data: SeiQuery::GetEvmAddress { sei_address },
657 }
658 .into();
659
660 self.querier.query(&request)
661 }
662
663 /// Queries the Sei address associated with a given EVM address.
664 ///
665 /// This function takes an `evm_address` as a parameter, which is a `String` representing the
666 /// EVM address. It returns a `StdResult<SeiAddressResponse>`, which is a standard result type
667 /// in the `cosmwasm_std` library. The `SeiAddressResponse` struct contains the Sei address.
668 /// If the EVM address is not associated with any Sei address, the Sei address will be an empty
669 /// string.
670 ///
671 /// # Arguments
672 ///
673 /// * `evm_address` - A `String` that represents the EVM address.
674 ///
675 /// # Returns
676 ///
677 /// * `StdResult<SeiAddressResponse>` - A standard result that wraps the `SeiAddressResponse`
678 /// struct. `SeiAddressResponse` contains the Sei address. If the EVM address is not associated
679 /// with any Sei address, the Sei address will be an empty string.
680 ///
681 /// # Errors
682 ///
683 /// This function will return an error if the query to the EVM fails.
684 pub fn get_sei_address(&self, evm_address: String) -> StdResult<SeiAddressResponse> {
685 let request = SeiQueryWrapper {
686 route: SeiRoute::Evm,
687 query_data: SeiQuery::GetSeiAddress { evm_address },
688 }
689 .into();
690
691 self.querier.query(&request)
692 }
693}