-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Hyperlane Transfer Action Support (#149)
* add execute action * add action and recover logic * add cw20 logic * update schema * add tests for execute action * implement hyperlane adapter * implement hyperlane transfer action in entrypoint * make schema * remove unused import
- Loading branch information
1 parent
c3757cb
commit e2bffe6
Showing
19 changed files
with
559 additions
and
35 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
[package] | ||
name = "skip-go-hyperlane-adapter" | ||
version = { workspace = true } | ||
rust-version = { workspace = true } | ||
authors = { workspace = true } | ||
edition = { workspace = true } | ||
license = { workspace = true } | ||
homepage = { workspace = true } | ||
repository = { workspace = true } | ||
documentation = { workspace = true } | ||
keywords = { workspace = true } | ||
|
||
[lib] | ||
crate-type = ["cdylib", "rlib"] | ||
|
||
[features] | ||
# for more explicit tests, cargo test --features=backtraces | ||
backtraces = ["cosmwasm-std/backtraces"] | ||
# use library feature to disable all instantiate/execute/query exports | ||
library = [] | ||
|
||
[dependencies] | ||
cosmwasm-schema = { workspace = true } | ||
cosmwasm-std = { workspace = true } | ||
cw2 = { workspace = true } | ||
cw-storage-plus = { workspace = true } | ||
cw-utils = { workspace = true } | ||
hpl-interface = { workspace = true } | ||
prost = { workspace = true } | ||
serde-json-wasm = { workspace = true } | ||
serde-cw-value = { workspace = true } | ||
skip = { workspace = true } | ||
thiserror = { workspace = true } | ||
|
||
[dev-dependencies] | ||
test-case = { workspace = true } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
use cosmwasm_schema::write_api; | ||
use skip::ibc::{ExecuteMsg, InstantiateMsg, QueryMsg}; | ||
|
||
fn main() { | ||
write_api! { | ||
instantiate: InstantiateMsg, | ||
execute: ExecuteMsg, | ||
query: QueryMsg | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
use crate::{ | ||
error::{ContractError, ContractResult}, | ||
state::ENTRY_POINT_CONTRACT_ADDRESS, | ||
}; | ||
use cosmwasm_std::{entry_point, to_json_binary, DepsMut, Env, HexBinary, MessageInfo, Response}; | ||
use cw2::set_contract_version; | ||
use cw_utils::one_coin; | ||
use hpl_interface::warp::native::ExecuteMsg::TransferRemote; | ||
use skip::{ | ||
asset::Asset, | ||
hyperlane::{ExecuteMsg, InstantiateMsg, MigrateMsg}, | ||
}; | ||
|
||
/////////////// | ||
/// MIGRATE /// | ||
/////////////// | ||
|
||
#[cfg_attr(not(feature = "library"), entry_point)] | ||
pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> ContractResult<Response> { | ||
// Set contract version | ||
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; | ||
|
||
// Validate entry point contract address | ||
let checked_entry_point_contract_address = | ||
deps.api.addr_validate(&msg.entry_point_contract_address)?; | ||
|
||
// Store the entry point contract address | ||
ENTRY_POINT_CONTRACT_ADDRESS.save(deps.storage, &checked_entry_point_contract_address)?; | ||
|
||
Ok(Response::new() | ||
.add_attribute("action", "migrate") | ||
.add_attribute( | ||
"entry_point_contract_address", | ||
checked_entry_point_contract_address.to_string(), | ||
)) | ||
} | ||
|
||
/////////////////// | ||
/// INSTANTIATE /// | ||
/////////////////// | ||
|
||
// Contract name and version used for migration. | ||
const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); | ||
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); | ||
|
||
#[cfg_attr(not(feature = "library"), entry_point)] | ||
pub fn instantiate( | ||
deps: DepsMut, | ||
_env: Env, | ||
_info: MessageInfo, | ||
msg: InstantiateMsg, | ||
) -> ContractResult<Response> { | ||
// Set contract version | ||
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; | ||
|
||
// Validate entry point contract address | ||
let checked_entry_point_contract_address = | ||
deps.api.addr_validate(&msg.entry_point_contract_address)?; | ||
|
||
// Store the entry point contract address | ||
ENTRY_POINT_CONTRACT_ADDRESS.save(deps.storage, &checked_entry_point_contract_address)?; | ||
|
||
Ok(Response::new() | ||
.add_attribute("action", "instantiate") | ||
.add_attribute( | ||
"entry_point_contract_address", | ||
checked_entry_point_contract_address.to_string(), | ||
)) | ||
} | ||
|
||
/////////////// | ||
/// EXECUTE /// | ||
/////////////// | ||
|
||
#[cfg_attr(not(feature = "library"), entry_point)] | ||
pub fn execute( | ||
deps: DepsMut, | ||
_env: Env, | ||
info: MessageInfo, | ||
msg: ExecuteMsg, | ||
) -> ContractResult<Response> { | ||
match msg { | ||
ExecuteMsg::HplTransfer { | ||
dest_domain, | ||
recipient, | ||
hook, | ||
metadata, | ||
warp_address, | ||
} => execute_hpl_transfer( | ||
deps, | ||
info, | ||
dest_domain, | ||
recipient, | ||
hook, | ||
metadata, | ||
warp_address, | ||
), | ||
} | ||
} | ||
|
||
// Converts the given info and coin into a Hyperlane remote transfer | ||
fn execute_hpl_transfer( | ||
deps: DepsMut, | ||
info: MessageInfo, | ||
dest_domain: u32, | ||
recipient: HexBinary, | ||
hook: Option<String>, | ||
metadata: Option<HexBinary>, | ||
warp_address: String, | ||
) -> ContractResult<Response> { | ||
// Get entry point contract address from storage | ||
let entry_point_contract_address = ENTRY_POINT_CONTRACT_ADDRESS.load(deps.storage)?; | ||
|
||
// Enforce the caller is the entry point contract | ||
if info.sender != entry_point_contract_address { | ||
return Err(ContractError::Unauthorized); | ||
} | ||
|
||
// Get the asset from the info | ||
let asset: Asset = one_coin(&info)?.into(); | ||
|
||
// Create the Hyperlane remote transfer message | ||
let msg = to_json_binary(&TransferRemote { | ||
dest_domain, | ||
recipient, | ||
amount: asset.amount(), | ||
hook, | ||
metadata, | ||
})?; | ||
|
||
// Convert the hyperlane transfer message into a wasm message | ||
let hpl_msg = asset.into_wasm_msg(warp_address, msg)?; | ||
|
||
Ok(Response::new() | ||
.add_message(hpl_msg) | ||
.add_attribute("action", "execute_hyperlane_transfer")) | ||
} |
Oops, something went wrong.