-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add developer docs for connecting apps (#3603)
- [X] ucs03 Asset Transfer - CosmWasm - [x] ucs03 Asset Transfer - Solidity - ~~ucs03 Data Transfer - CosmWasm~~ (#3622) - ~~ucs03 Data Transfer - Solidity~~ (#3622) - ~~Connecting New Chains~~ (#3465)
- Loading branch information
Showing
7 changed files
with
477 additions
and
29 deletions.
There are no files selected for viewing
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
280 changes: 280 additions & 0 deletions
280
docs/src/content/docs/connect/app/asset-transfer/cosmwasm.mdx
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,280 @@ | ||
--- | ||
title: "ucs03-zkgm Asset Transfer Tutorial - CosmWasm" | ||
description: "Transfer assets using Union's ucs03 protocol in a CosmWasm contract" | ||
template: doc | ||
--- | ||
|
||
import { Tabs, TabItem, FileTree, Steps, Badge } from '@astrojs/starlight/components' | ||
|
||
# Prerequisites | ||
|
||
This tutorial assumes that you have experience creating contracts in CosmWasm. If you need to familiarize yourself with CosmWasm, you should start with the [CosmWasm book](https://book.cosmwasm.com/) and the other [resources listed by the CosmWasm team](https://cosmwasm.com/build). | ||
|
||
The Union team uses [Nix](https://nixos.org/) to manage developer environments. While this tutorial may mention different developer tools, it will not guide you through setting each one up. | ||
|
||
This tutorial will assume that you have a working rust tool chain, including `cargo`. | ||
|
||
You will also need a chain that supports CosmWasm running where you plan to deploy ucs03 and your app. This tutorial will assume you are deploying your contract on `union-testnet-9`. | ||
|
||
Users will need to find a valid RPC node to use as `RPC_URL` throughout the tutorial. | ||
|
||
# Tutorial | ||
|
||
1. Write your contract | ||
2. Deploy your contract | ||
3. Example transfer | ||
|
||
## Write Your Contract | ||
|
||
To demonstrate asset transfers with ucs03, this tutorial will walk you through creating a simple contract that sends a single token. | ||
|
||
### Project Bootstrapping | ||
|
||
If you don't already have a project folder for your contract, make one now and navigate inside. | ||
|
||
```sh | ||
cargo new --lib example-ucs03-cosmwasm | ||
cd example-ucs03-cosmwasm | ||
``` | ||
|
||
Add required dependencies to the `Cargo.toml` file. | ||
|
||
```toml title="Cargo.toml" | ||
[package] | ||
name = "example-ucs03-cosmwasm" # name of the project | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[lib] | ||
crate-type = ["cdylib", 'rlib'] | ||
|
||
[dependencies] | ||
cosmwasm-schema = { version = "2.1.4" } | ||
cosmwasm-std = { version = "2.1.4", default-features = false, features = ["std", "staking", "stargate"] } | ||
serde = { version = "1.0.210", default-features = false, features = ["derive"] } | ||
thiserror = { version = "1.0.64", default-features = false } | ||
|
||
[features] | ||
library = [] | ||
|
||
[profile.release] | ||
opt-level = "z" | ||
strip = true | ||
``` | ||
|
||
Below is a sample contract that can be pasted into `lib.rs`. | ||
|
||
This contract exposes the transfer message from ucs03-zkgm (`Ucs03ExecuteMsg`), then sends that message to the deployed ucs03-zkgm. To see all the messages exposed by ucs03-zkgm, refer to the contract in our [repository](https://github.com/unionlabs/union/blob/49dfa17d04b52509e5122d13e79bfc4a65d4a811/cosmwasm/ibc-union/app/ucs03-zkgm/src/msg.rs#L16) | ||
|
||
```rust title="src/lib.rs" | ||
use cosmwasm_schema::cw_serde; | ||
#[cfg(not(feature = "library"))] | ||
use cosmwasm_std::entry_point; | ||
use cosmwasm_std::{ | ||
to_json_binary, Coin, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, Uint256, WasmMsg, | ||
}; | ||
|
||
#[cw_serde] | ||
pub struct InstantiateMsg {} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize)] | ||
#[serde(rename_all = "snake_case")] | ||
pub enum ExecuteMsg { | ||
Transfer { | ||
channel_id: u32, | ||
receiver: String, | ||
base_token: String, | ||
base_amount: Uint128, | ||
quote_token: String, | ||
quote_amount: Uint256, | ||
contract_address: String, | ||
}, | ||
} | ||
|
||
#[derive(serde::Serialize, serde::Deserialize)] | ||
#[serde(rename_all = "snake_case")] | ||
pub enum Ucs03ExecuteMsg { | ||
Transfer { | ||
channel_id: u32, | ||
receiver: String, | ||
base_token: String, | ||
base_amount: Uint128, | ||
quote_token: String, | ||
quote_amount: Uint256, | ||
timeout_height: u64, | ||
timeout_timestamp: u64, | ||
salt: String, | ||
}, | ||
} | ||
|
||
#[cfg_attr(not(feature = "library"), entry_point)] | ||
pub fn instantiate( | ||
_deps: DepsMut, | ||
_env: Env, | ||
_info: MessageInfo, | ||
_msg: InstantiateMsg, | ||
) -> StdResult<Response> { | ||
Ok(Response::default()) | ||
} | ||
|
||
#[cfg_attr(not(feature = "library"), entry_point)] | ||
pub fn execute( | ||
deps: DepsMut, | ||
env: Env, | ||
_info: MessageInfo, | ||
msg: ExecuteMsg, | ||
) -> StdResult<Response> { | ||
match msg { | ||
ExecuteMsg::Transfer { | ||
channel_id, | ||
receiver, | ||
base_token, | ||
base_amount, | ||
quote_token, | ||
quote_amount, | ||
contract_address, | ||
} => transfer( | ||
deps, | ||
env, | ||
channel_id, | ||
receiver, | ||
base_token, | ||
base_amount, | ||
quote_token, | ||
quote_amount, | ||
contract_address, | ||
), | ||
} | ||
} | ||
|
||
fn transfer( | ||
_deps: DepsMut, | ||
_env: Env, | ||
channel_id: u32, | ||
receiver: String, | ||
base_token: String, | ||
base_amount: Uint128, | ||
quote_token: String, | ||
quote_amount: Uint256, | ||
contract_address: String, | ||
) -> StdResult<Response> { | ||
let msg = WasmMsg::Execute { | ||
contract_addr: contract_address, | ||
msg: to_json_binary(&Ucs03ExecuteMsg::Transfer { | ||
channel_id, | ||
receiver: receiver.clone(), | ||
base_token: base_token.clone(), | ||
base_amount, | ||
quote_token, | ||
quote_amount, | ||
timeout_height: 1000000000000, | ||
timeout_timestamp: 2737670312, | ||
salt: "0x5dbda6be8b35e888c9d4e64c3ce080fbc735e8b907ca5a38222ac522d085ec2b".to_string(), | ||
}) | ||
.expect("can convert into json binary"), | ||
funds: vec![Coin { | ||
denom: base_token, | ||
amount: base_amount, | ||
}], | ||
}; | ||
|
||
Ok(Response::new() | ||
.add_message(msg) | ||
.add_attribute("action", "transfer") | ||
.add_attribute("recipient", receiver) | ||
.add_attribute("amount", base_amount.to_string())) | ||
} | ||
``` | ||
### Building the Contract | ||
|
||
With this contract code ready, the WASM blob can be built. | ||
|
||
```sh | ||
RUSTFLAGS='-C target-cpu=mvp -C opt-level=z' cargo build \ | ||
--target wasm32-unknown-unknown \ | ||
--no-default-features \ | ||
--lib \ | ||
--release \ | ||
-Z build-std=std,panic_abort \ | ||
-Z build-std-features=panic_immediate_abort | ||
|
||
mkdir -p build | ||
``` | ||
|
||
The contract can now be deployed. | ||
|
||
## Deploying your Contract | ||
|
||
With the WASM blob ready, the contract can be deployed. | ||
|
||
```sh | ||
uniond tx wasm store ./build/contract.wasm \ | ||
--from $KEY_NAME \ | ||
--gas auto \ | ||
--gas-adjustment 1.4 \ | ||
--chain-id union-testnet-9 \ | ||
--node $RPC_URL \ | ||
--yes | ||
|
||
TX_HASH=.. | ||
``` | ||
|
||
Be sure to copy the `CODE_ID` of the newly stored code. Using the previous transaction hash, you can see it by running this command: | ||
```sh | ||
uniond query tx $TX_HASH --node $RPC_URL | rg -C 1 "code_id" | ||
``` | ||
|
||
Next, submit a transaction to instantiate the contract. Copy the value of the **NEW** transaction hash into a shell variable (`TX_HASH`). | ||
|
||
```sh | ||
uniond tx wasm instantiate $CODE_ID "{}" \ | ||
--node $RPC_URL \ | ||
--from $KEY_NAME \ | ||
--label $CONTRACT_NAME \ | ||
--no-admin \ | ||
--gas auto \ | ||
--gas-adjustment 1.4 \ | ||
--chain-id union-testnet-9 | ||
|
||
TX_HASH=.. | ||
``` | ||
|
||
You can then get the contract address by running: | ||
```sh | ||
uniond query tx $TX_HASH --node $RPC_URL | rg -C 1 "_contract_address" | ||
``` | ||
|
||
## Example Transfer | ||
|
||
With the address of your contract in hand, a sample transfer can now be conducted. | ||
|
||
First, prepare a `payload.json` that will hold the main message of the transfer. | ||
|
||
This will send UNO to a Holesky address of your choice | ||
|
||
```json title="payload.json" | ||
{ | ||
"transfer": { | ||
"channel_id": 7, | ||
"receiver": "<RECEIVER_ADDRESS_HEX_PREFIXED>", | ||
"base_token": "muno", | ||
"base_amount": 1000000, | ||
"quote_token": "0xf2865969cf99a28bb77e25494fe12d5180fe0efd", | ||
"quote_amount": "1000000", | ||
"contract_address": "union19hspxmypfxsdsnxttma8rxvp7dtcmzhl9my0ee64avg358vlpawsdvucqa", | ||
} | ||
} | ||
``` | ||
|
||
The message can then be sent to the contract for execution. | ||
|
||
```sh | ||
uniond \ | ||
tx wasm execute $CONTRACT_ADDRESS "$(jq -c '.' payload.json)" \ | ||
--from $KEY_NAME \ | ||
--gas auto \ | ||
--gas-adjustment 1.4 \ | ||
--chain-id union-testnet-9 \ | ||
--node $RPC_URL \ | ||
--amount 2000000muno | ||
``` |
10 changes: 10 additions & 0 deletions
10
docs/src/content/docs/connect/app/asset-transfer/index.mdx
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 @@ | ||
--- | ||
title: "Asset Transfer Tutorial" | ||
description: "Transfer assets using Union's ZKGM protocol" | ||
template: doc | ||
--- | ||
|
||
This tutorial will walk you through creating a smart contract to send assets with Union. Asset transfer can be achieved through the message passing exposed by ZKGM (aka ucs03-zkgm). | ||
|
||
At this point, you can continue the tutorial with either our [CosmWasm](/connect/app/asset-transfer/cosmwasm) or [Solidity](/connect/app/asset-transfer/solidity) specific tutorials. | ||
|
Oops, something went wrong.