Skip to content

Commit

Permalink
wasm: Debugging instantiate2.
Browse files Browse the repository at this point in the history
  • Loading branch information
dowlandaiello committed Aug 15, 2024
1 parent 6272c78 commit 970049e
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ sha2 = "0.10.8"

[dev-dependencies]
env_logger = "0.11.3"
hex = "0.4.3"
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,17 @@ Note that most `tx_*` helper functions expose a `.with_key(key: &str)` builder f
* No required builder calls
* No notable optional builder calls

#### Wasm

* `.build_tx_instantiate2` - Predictably instantiates a CosmWasm contract.
* Required builder calls:
* `.with_code_id(code_id: u64)` - Should be the raw code ID of the contract being instantiated
* `.with_salt(salt: &str)` - Should be a **hex-encoded** salt for instantiation
* `.with_msg(msg: serde_json::Value)`
* `.with_label(label: &str)`
* Notable optional builder calls:
* `.with_chain_name(chain_name: impl Into<String>)` - Should be on of `"osmosis" | "neutron" | "stride"` or one of the registered chain names from `.with_chain`

#### Tokens

* `.build_tx_create_tokenfactory_token` - Creates a tokenfactory token from `acc0` on Neutron by default.
Expand Down
18 changes: 18 additions & 0 deletions examples/neutron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,23 @@ fn main() -> Result<(), Box<dyn Error>> {
.with_liq_token_receiver(ACC_0_ADDR)
.send()?;

let factory_contract_code_id = ctx
.get_contract("astroport_whitelist")
.unwrap()
.code_id
.unwrap();

// Instantiate a contract predictably
ctx.build_tx_instantiate2()
.with_code_id(factory_contract_code_id)
.with_msg(serde_json::json!({
"admins": [],
"mutable": false,
}))
.with_salt(hex::encode("examplesalt").as_str())
.with_label("test_contract")
.send()
.unwrap();

Ok(())
}
1 change: 1 addition & 0 deletions src/utils/setup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ pub mod osmosis;
pub mod stride;
pub mod tokens;
pub mod valence;
pub mod wasm;
152 changes: 152 additions & 0 deletions src/utils/setup/wasm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
use super::super::{
super::{error::Error, DEFAULT_KEY, NEUTRON_CHAIN_NAME},
test_context::TestContext,
};
use cosmwasm_std::Coin;
use serde_json::Value;

pub struct Instantiate2TxBuilder<'a> {
key: &'a str,
chain_name: &'a str,
admin: Option<&'a str>,
code_id: Option<u64>,
label: Option<&'a str>,
msg: Option<Value>,
funds: Option<Coin>,

// Not automatically hex-encoded.
// Assume the user performs hex encoding
salt: Option<&'a str>,
fix_msg: Option<bool>,
test_ctx: &'a mut TestContext,
}

impl<'a> Instantiate2TxBuilder<'a> {
pub fn with_key(&mut self, key: &'a str) -> &mut Self {
self.key = key;

self
}

pub fn with_chain_name(&mut self, chain_name: &'a str) -> &mut Self {
self.chain_name = chain_name;

self
}

pub fn with_admin(&mut self, admin: &'a str) -> &mut Self {
self.admin = Some(admin);

self
}

pub fn with_code_id(&mut self, code_id: u64) -> &mut Self {
self.code_id = Some(code_id);

self
}

pub fn with_label(&mut self, label: &'a str) -> &mut Self {
self.label = Some(label);

self
}

pub fn with_msg(&mut self, msg: Value) -> &mut Self {
self.msg = Some(msg);

self
}

pub fn with_funds(&mut self, funds: Coin) -> &mut Self {
self.funds = Some(funds);

self
}

/// Sets the salt. Value must be hex encoded.
pub fn with_salt(&mut self, salt: &'a str) -> &mut Self {
self.salt = Some(salt);

self
}

pub fn with_fix_msg(&mut self, fix_msg: bool) -> &mut Self {
self.fix_msg = Some(fix_msg);

self
}

/// Sends the built instantiate 2 tx.
pub fn send(&mut self) -> Result<(), Error> {
self.test_ctx.tx_instantiate2(
self.key,
self.chain_name,
self.admin,
self.code_id.expect("missing builder param code_id"),
self.label.expect("missing builder param label"),
self.msg.as_ref().expect("missing builder param msg"),
self.funds.as_ref(),
self.salt.as_ref().expect("missing builder param salt"),
self.fix_msg,
)
}
}

impl TestContext {
pub fn build_tx_instantiate2<'a>(&'a mut self) -> Instantiate2TxBuilder<'a> {
Instantiate2TxBuilder {
key: DEFAULT_KEY,
chain_name: NEUTRON_CHAIN_NAME,
admin: None,
code_id: None,
label: None,
msg: None,
funds: None,
salt: None,
fix_msg: None,
test_ctx: self,
}
}

fn tx_instantiate2(
&mut self,
key: &str,
chain_name: &str,
admin: Option<&str>,
code_id: u64,
label: &str,
msg: &Value,
funds: Option<&Coin>,
salt: &str,
fix_msg: Option<bool>,
) -> Result<(), Error> {
let chain = self.get_chain(chain_name);

// Optional flags
let admin_part = admin
.map(|admin| format!("--admin {admin}"))
.unwrap_or(String::from("--no-admin"));
let amt_part = funds
.map(|funds| format!("--amount {funds}"))
.unwrap_or_default();
let fix_msg_part = fix_msg
.map(|fix_msg| format!("--fix_msg {fix_msg}"))
.unwrap_or_default();

let receipt = chain.rb.tx(
&format!("tx wasm instantiate2 {code_id} {msg} {salt} --label {label} {admin_part} {amt_part} {fix_msg_part} --from {key}"),
true,
)?;

self.guard_tx_errors(
chain_name,
receipt
.get("txhash")
.and_then(|receipt| receipt.as_str())
.ok_or(Error::TxMissingLogs)?,
)?;

Ok(())
}
}

0 comments on commit 970049e

Please sign in to comment.