Skip to content

Commit

Permalink
Bindings for getiting (#75)
Browse files Browse the repository at this point in the history
* draft working version of getting EVM address

* draft of evm to sei address

* working draft

* uncommented attr

* formatting

* Added missing docs

* Update README

* cargo formatting

* remove ethaddr due to unstable deps

* address auto comments
  • Loading branch information
dssei authored Apr 9, 2024
1 parent e4b06b7 commit 7ac6c83
Show file tree
Hide file tree
Showing 10 changed files with 290 additions and 41 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[workspace]
members = ["packages/*", "contracts/*"]
resolver = "2"

[profile.release.package.sei-cosmwasm]
opt-level = 3
Expand Down
46 changes: 37 additions & 9 deletions contracts/sei-tester/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ use crate::{
use protobuf::Message;
use sei_cosmwasm::{
BulkOrderPlacementsResponse, Cancellation, DenomAuthorityMetadataResponse, DenomUnit,
DenomsFromCreatorResponse, DepositInfo, DexTwapsResponse, EpochResponse, ExchangeRatesResponse,
GetLatestPriceResponse, GetOrderByIdResponse, GetOrdersResponse, Metadata,
MsgPlaceOrdersResponse, OracleTwapsResponse, Order, OrderSimulationResponse, OrderType,
PositionDirection, SeiMsg, SeiQuerier, SeiQueryWrapper, SettlementEntry, SudoMsg,
DenomsFromCreatorResponse, DepositInfo, DexTwapsResponse, EpochResponse, EvmAddressResponse,
ExchangeRatesResponse, GetLatestPriceResponse, GetOrderByIdResponse, GetOrdersResponse,
Metadata, MsgPlaceOrdersResponse, OracleTwapsResponse, Order, OrderSimulationResponse,
OrderType, PositionDirection, SeiAddressResponse, SeiMsg, SeiQuerier, SeiQueryWrapper,
SettlementEntry, SudoMsg,
};

const PLACE_ORDER_REPLY_ID: u64 = 1;
Expand All @@ -33,7 +34,7 @@ pub fn validate_migration(
let ver = cw2::get_contract_version(deps.storage)?;
// ensure we are migrating from an allowed contract
if ver.contract != contract_name {
return Err(StdError::generic_err("Can only upgrade from same type").into());
return Err(StdError::generic_err("Can only upgrade from same type"));
}
Ok(())
}
Expand Down Expand Up @@ -275,13 +276,13 @@ pub fn set_metadata(
symbol: "SUB".to_string(),
denom_units: vec![
DenomUnit {
denom: tokenfactory_denom.clone(),
exponent: 0 as u32,
denom: tokenfactory_denom,
exponent: 0,
aliases: vec!["usubdenom".to_string()],
},
DenomUnit {
denom: "SUBDENOM".to_string(),
exponent: 6 as u32,
exponent: 6,
aliases: vec!["subdenom".to_string()],
},
],
Expand Down Expand Up @@ -337,7 +338,7 @@ pub fn process_bulk_order_placements(
response = response.set_data(binary);
deps.api
.debug(&format!("process_bulk_order_placements: {:?}", response));
return Ok(Response::new());
Ok(Response::new())
}

pub fn process_bulk_order_cancellations(
Expand Down Expand Up @@ -436,6 +437,12 @@ pub fn query(deps: Deps<SeiQueryWrapper>, _env: Env, msg: QueryMsg) -> StdResult
QueryMsg::GetDenomsFromCreator { creator } => {
to_json_binary(&query_denoms_from_creator(deps, creator)?)
}
QueryMsg::GetEvmAddressBySeiAddress { sei_address } => {
to_json_binary(&query_evm_address(deps, sei_address)?)
}
QueryMsg::GetSeiAddressByEvmAddress { evm_address } => {
to_json_binary(&query_sei_address(deps, evm_address)?)
}
}
}

Expand Down Expand Up @@ -549,3 +556,24 @@ pub fn query_denoms_from_creator(

Ok(res)
}

pub fn query_evm_address(
deps: Deps<SeiQueryWrapper>,
sei_address: String,
) -> StdResult<EvmAddressResponse> {
let valid_addr = deps.api.addr_validate(&sei_address)?;
let querier = SeiQuerier::new(&deps.querier);
let res = querier.get_evm_address(valid_addr.to_string())?;

Ok(res)
}

pub fn query_sei_address(
deps: Deps<SeiQueryWrapper>,
evm_address: String,
) -> StdResult<SeiAddressResponse> {
let querier = SeiQuerier::new(&deps.querier);
let res = querier.get_sei_address(evm_address)?;

Ok(res)
}
6 changes: 6 additions & 0 deletions contracts/sei-tester/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,10 @@ pub enum QueryMsg {
GetDenomsFromCreator {
creator: String,
},
GetEvmAddressBySeiAddress {
sei_address: String,
},
GetSeiAddressByEvmAddress {
evm_address: String,
},
}
98 changes: 90 additions & 8 deletions contracts/sei-tester/tests/sei_tester_integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use cosmwasm_std::{
coin, from_binary,
coin, from_json,
testing::{MockApi, MockStorage},
Addr, Api, BalanceResponse, Coin, CosmosMsg, Decimal, Empty, GovMsg, IbcMsg, IbcQuery,
QueryRequest, StdError, Storage, Uint128,
Expand All @@ -9,15 +9,16 @@ use cw_multi_test::{
App, BankKeeper, ContractWrapper, DistributionKeeper, Executor, FailingModule, Router,
StakeKeeper, WasmKeeper,
};

use sei_cosmwasm::{
Cancellation, DenomOracleExchangeRatePair, DexPair, DexTwap, DexTwapsResponse, EpochResponse,
ExchangeRatesResponse, GetOrderByIdResponse, GetOrdersResponse, OracleExchangeRate,
OracleTwapsResponse, Order, OrderSimulationResponse, OrderStatus, OrderType, PositionDirection,
SeiMsg, SeiQuery, SeiQueryWrapper, SeiRoute, SudoMsg as SeiSudoMsg,
EvmAddressResponse, ExchangeRatesResponse, GetOrderByIdResponse, GetOrdersResponse,
OracleExchangeRate, OracleTwapsResponse, Order, OrderSimulationResponse, OrderStatus,
OrderType, PositionDirection, SeiAddressResponse, SeiMsg, SeiQuery, SeiQueryWrapper, SeiRoute,
};
use sei_integration_tests::{
helper::{get_balance, mock_app},
module::SeiModule,
module::{SeiModule, EVM_ADDRESS, SEI_ADDRESS},
};
use sei_tester::{
contract::{execute, instantiate, query},
Expand Down Expand Up @@ -142,7 +143,7 @@ fn test_tokenfactory_integration_foundation() {
let res = arr.first().unwrap().clone().data;
let data = res.unwrap();

let out: String = from_binary(&data).unwrap();
let out: String = from_json(&data).unwrap();
assert_eq!(out.to_string(), "factory/admin/test");

app.execute_multi(
Expand Down Expand Up @@ -306,7 +307,7 @@ fn test_dex_module_integration_orders() {
.unwrap();
let res = arr.first().unwrap().clone().data;
let data = res.unwrap();
let out: String = from_binary(&data).unwrap();
let out: String = from_json(&data).unwrap();
assert_eq!(out.to_string(), contract_addr.to_string());

// Query GetOrders() after order 1
Expand Down Expand Up @@ -466,7 +467,7 @@ fn test_dex_module_integration_orders() {
.unwrap();
let res = arr.first().unwrap().clone().data;
let data = res.unwrap();
let out: String = from_binary(&data).unwrap();
let out: String = from_json(&data).unwrap();
assert_eq!(out.to_string(), contract_addr.to_string());

// Query GetOrders() after order 0 cancelled
Expand Down Expand Up @@ -931,3 +932,84 @@ fn test_dex_module_query_dex_twap() {

assert_eq!(res, expected_twap);
}

/// EVM Module - query EVM address
#[test]
fn test_evm_address_query() {
let mut app = mock_app(init_default_balances, vec![]);
let sei_tester_addr = setup_test(&mut app);

// Test associated EVM address
let res: EvmAddressResponse = app
.wrap()
.query_wasm_smart(
sei_tester_addr.clone(),
&QueryMsg::GetEvmAddressBySeiAddress {
sei_address: SEI_ADDRESS.to_string(),
},
)
.unwrap();

let expected_res = EvmAddressResponse {
evm_address: EVM_ADDRESS.to_string(),
associated: true,
};
assert_eq!(res, expected_res);

// Test non-associated EVM address
let res: EvmAddressResponse = app
.wrap()
.query_wasm_smart(
sei_tester_addr.clone(),
&QueryMsg::GetEvmAddressBySeiAddress {
sei_address: "fake_address".to_string(),
},
)
.unwrap();

let expected_res = EvmAddressResponse {
evm_address: String::new(),
associated: false,
};
assert_eq!(res, expected_res);
}

#[test]
fn test_sei_address_query() {
let mut app = mock_app(init_default_balances, vec![]);
let sei_tester_addr = setup_test(&mut app);

// // Test associated SEI address
let res: SeiAddressResponse = app
.wrap()
.query_wasm_smart(
sei_tester_addr.clone(),
&QueryMsg::GetSeiAddressByEvmAddress {
evm_address: "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B".to_string(),
},
)
.unwrap();

let expected_res = SeiAddressResponse {
sei_address: SEI_ADDRESS.to_string(),
associated: true,
};
assert_eq!(res, expected_res);

// Test non-associated SEI address
let res: SeiAddressResponse = app
.wrap()
.query_wasm_smart(
sei_tester_addr.clone(),
&QueryMsg::GetSeiAddressByEvmAddress {
evm_address: "0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E".to_string(),
},
)
.unwrap();

let expected_res = SeiAddressResponse {
sei_address: String::new(),
associated: false,
};
assert_eq!(res, expected_res);
}
4 changes: 4 additions & 0 deletions packages/sei-cosmwasm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ Currently, Sei Bindings support query and message support for the sei custom mod
- Gets the Erc721 name and symbol based on the `caller` and `contract address`
- Erc721Uri
- Gets the Erc721 URI based on `caller`, `contract_address` and `token_id`
- GetEvmAddress
- Get the EVM address associated with a Sei address
- GetSeiAddress
- Get the Sei address associated with an EVM address
- Message
- DelegateCallEvm
- Performs an EVM delegate call. Requires `to` and `data`
Expand Down
5 changes: 3 additions & 2 deletions packages/sei-cosmwasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ pub use proto_structs::{
pub use querier::SeiQuerier;
pub use query::{
DenomAuthorityMetadataResponse, DenomsFromCreatorResponse, DexTwapsResponse, EpochResponse,
ExchangeRatesResponse, GetLatestPriceResponse, GetOrderByIdResponse, GetOrdersResponse,
OracleTwapsResponse, OrderSimulationResponse, PriceResponse, SeiQuery, SeiQueryWrapper,
EvmAddressResponse, ExchangeRatesResponse, GetLatestPriceResponse, GetOrderByIdResponse,
GetOrdersResponse, OracleTwapsResponse, OrderSimulationResponse, PriceResponse,
SeiAddressResponse, SeiQuery, SeiQueryWrapper,
};
pub use route::SeiRoute;
pub use sei_types::{
Expand Down
68 changes: 66 additions & 2 deletions packages/sei-cosmwasm/src/querier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use crate::query::{
DenomAuthorityMetadataResponse, DenomsFromCreatorResponse, DexTwapsResponse, EpochResponse,
Erc20AllowanceResponse, Erc721ApprovedResponse, Erc721IsApprovedForAllResponse,
Erc721NameSymbolResponse, Erc721OwnerResponse, Erc721UriResponse, ErcPayloadResponse,
ExchangeRatesResponse, GetLatestPriceResponse, GetOrderByIdResponse, GetOrdersResponse,
OracleTwapsResponse, OrderSimulationResponse, SeiQuery, SeiQueryWrapper, StaticCallResponse,
EvmAddressResponse, ExchangeRatesResponse, GetLatestPriceResponse, GetOrderByIdResponse,
GetOrdersResponse, OracleTwapsResponse, OrderSimulationResponse, SeiAddressResponse, SeiQuery,
SeiQueryWrapper, StaticCallResponse,
};
use crate::route::SeiRoute;
use crate::Order;
Expand Down Expand Up @@ -433,4 +434,67 @@ impl<'a> SeiQuerier<'a> {

self.querier.query(&request)
}

/// Queries the EVM (Ethereum Virtual Machine) address associated with a given Sei address.
///
/// This function takes a `sei_address` as a parameter, which is a `String` representing the
/// SEI address. It returns a `StdResult<EvmAddressResponse>`, which is a standard result type
/// in the `cosmwasm_std` library. The `EvmAddressResponse` struct contains the EVM address and
/// a boolean indicating whether the EVM address is associated.
///
/// # Arguments
///
/// * `sei_address` - A `String` that represents the Sei address.
///
/// # Returns
///
/// * `StdResult<EvmAddressResponse>` - A standard result that wraps the `EvmAddressResponse`
/// struct. `EvmAddressResponse` contains the EVM address and a boolean indicating whether the
/// EVM address is associated. If the Sei address is not associated with any EVM address,
/// the EVM address will be an empty string.
///
///
/// # Errors
///
/// This function will return an error if the query to the EVM fails.
pub fn get_evm_address(&self, sei_address: String) -> StdResult<EvmAddressResponse> {
let request = SeiQueryWrapper {
route: SeiRoute::Evm,
query_data: SeiQuery::GetEvmAddress { sei_address },
}
.into();

self.querier.query(&request)
}

/// Queries the Sei address associated with a given EVM address.
///
/// This function takes an `evm_address` as a parameter, which is a `String` representing the
/// EVM address. It returns a `StdResult<SeiAddressResponse>`, which is a standard result type
/// in the `cosmwasm_std` library. The `SeiAddressResponse` struct contains the Sei address.
/// If the EVM address is not associated with any Sei address, the Sei address will be an empty
/// string.
///
/// # Arguments
///
/// * `evm_address` - A `String` that represents the EVM address.
///
/// # Returns
///
/// * `StdResult<SeiAddressResponse>` - A standard result that wraps the `SeiAddressResponse`
/// struct. `SeiAddressResponse` contains the Sei address. If the EVM address is not associated
/// with any Sei address, the Sei address will be an empty string.
///
/// # Errors
///
/// This function will return an error if the query to the EVM fails.
pub fn get_sei_address(&self, evm_address: String) -> StdResult<SeiAddressResponse> {
let request = SeiQueryWrapper {
route: SeiRoute::Evm,
query_data: SeiQuery::GetSeiAddress { evm_address },
}
.into();

self.querier.query(&request)
}
}
29 changes: 29 additions & 0 deletions packages/sei-cosmwasm/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ pub enum SeiQuery {
contract_address: String,
token_id: String,
},
GetEvmAddress {
sei_address: String,
},
GetSeiAddress {
evm_address: String,
},
}

/// ExchangeRatesResponse is data format returned from OracleRequest::ExchangeRates query
Expand Down Expand Up @@ -236,3 +242,26 @@ pub struct Erc721NameSymbolResponse {
pub struct Erc721UriResponse {
pub uri: String,
}

/// `EvmAddressResponse` is a struct that represents a response containing an EVM address.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct EvmAddressResponse {
/// The 20-byte EVM address associated to Sei address that's derived from the public part of a
/// public-private key pair. It's represented as a hex string.
/// Address is empty if the Sei address is not associated with any EVM address.
pub evm_address: String,

/// A boolean value indicating whether the EVM address is associated.
pub associated: bool,
}

/// `SeiAddressResponse` is a struct that represents a response containing a SEI address.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct SeiAddressResponse {
/// The SEI address associated to EVM address. Empty if the EVM address is not associated with
/// any SEI address.
pub sei_address: String,

/// A boolean value indicating whether the SEI address is associated to EVM address.
pub associated: bool,
}
Loading

0 comments on commit 7ac6c83

Please sign in to comment.