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}