39个版本 (14个破坏性版本)

0.25.0 2024年8月21日
0.24.1 2024年7月11日
0.23.0 2024年6月12日
0.21.2 2024年3月20日
0.13.3 2023年7月5日

#313 in 魔法豆

Download history 655/week @ 2024-05-04 1102/week @ 2024-05-11 802/week @ 2024-05-18 1568/week @ 2024-05-25 1660/week @ 2024-06-01 2054/week @ 2024-06-08 1668/week @ 2024-06-15 2043/week @ 2024-06-22 1416/week @ 2024-06-29 2392/week @ 2024-07-06 1814/week @ 2024-07-13 1469/week @ 2024-07-20 1162/week @ 2024-07-27 1120/week @ 2024-08-03 1344/week @ 2024-08-10 1054/week @ 2024-08-17

4,853 每月下载量
用于 47 个crate(39个直接)

GPL-3.0-only

165KB
2.5K SLoC

cw-orchestrator

docs.rs Crates.io Codecov

一个用于与CosmWasm智能合约交互的Rust工具。它提供对CosmWasm合约的类型安全接口,并允许您轻松地与它们交互。它通过提供一组宏来生成对您的合约的类型安全接口来实现这一点。然后,您可以将您的合约接口组合成一个单一的对象,与他人共享以简化集成工作并鼓励协作。

这里的文档为您提供了cw-orchestrator提供的功能的简要概述。我们在orchestrator.abstract.money提供了更多文档。

工作原理

CosmWasm合约的交互涉及到使用该端点的适当消息调用合约的端点(如ExecuteMsgInstantiateMsgQueryMsgMigrateMsg等)。cw-orchestrator为您的合约生成类型接口,允许它们在编译时进行类型检查。然后,这个通用接口允许您编写环境通用的代码,这意味着您可以将您为将应用程序部署到cw-multi-test而编写的代码重用于将应用程序部署到测试/主网。

维护的接口

我们维护了一组小型的接口,这些接口用于我们自己的项目。这些接口由抽象团队维护,是使用库的良好参考。

代码库 最新版本
cw-plus GitHub tag (latest SemVer)
AbstractSDK Crates.io

创建接口

为了生成对您的合约的强类型接口,您可以传递合约的消息类型到cw_orch::interface宏。

interface

将您的消息提供给以您的合约命名的新结构体。

use cw_orch::interface;
use cw20_base::msg::{InstantiateMsg, ExecuteMsg, QueryMsg, MigrateMsg};

// Provide the messages in the order Init, Exec, Query, Migrate.
#[interface(InstantiateMsg, ExecuteMsg, QueryMsg, MigrateMsg)]
pub struct Cw20;

该宏将生成一个new函数,它接受合约名称和您想要与之交互的链。然后,您可以使用此接口与合约进行交互。

用法

您可以使用此接口部署和交互合约

use cw_orch::interface;
use cw_orch::prelude::*;
use cw20::{Cw20Coin, BalanceResponse};

// Implement the Uploadable trait so it can be uploaded to the mock. 
impl <Chain> Uploadable for Cw20<Chain> {
    fn wrapper() -> Box<dyn MockContract<Empty>> {
        Box::new(
            ContractWrapper::new_with_empty(
                cw20_base::contract::execute,
                cw20_base::contract::instantiate,
                cw20_base::contract::query,
            )
            .with_migrate(cw20_base::contract::migrate),
        )
    }
}


fn example_test() {
  let sender = Addr::unchecked("sender");
  // Create a new mock chain (backed by cw-multi-test)
  let chain = Mock::new(&sender);
  
  // Create a new Cw20 interface
  let cw20_base: Cw20<Mock> = Cw20::new("my_token", chain);
  
  // Upload the contract
  cw20_base.upload().unwrap();

  // Instantiate a CW20 token
  let cw20_init_msg = InstantiateMsg {
      decimals: 6,
      name: "Test Token".to_string(),
      initial_balances: vec![Cw20Coin {
          address: sender.to_string(),
          amount: 10u128.into(),
      }],
      marketing: None,
      mint: None,
      symbol: "TEST".to_string(),
  };
  cw20_base.instantiate(&cw20_init_msg, None, None).unwrap();

  // Query the balance
  let balance: BalanceResponse = cw20_base.query(&QueryMsg::Balance { address: sender.to_string() }).unwrap();

  assert_eq!(balance.balance.u128(), 10u128);
}

功能

cw-orchestrator提供了两个额外的宏,可用于改进脚本体验。

ExecuteFns

ExecuteFns宏可以添加到您的合约的ExecuteMsg定义中。它将生成一个特质,允许您直接调用消息的变体,而无需自己构造结构体。

ExecuteFns宏仅在编译为非wasm目标时应用于Msg。

use cw_orch::prelude::*;

#[cosmwasm_schema::cw_serde]
#[derive(cw_orch::ExecuteFns)]
pub enum ExecuteMsg {
    Freeze {},
    UpdateAdmins { admins: Vec<String> },
    /// the `payable` attribute can be used to add a `coins` argument to the generated function.
    #[cw_orch(payable)]
    Deposit {}
}

生成的函数可以用于使用此ExecuteMsg的任何接口。

// Define the interface, which is generic over the CosmWasm environment (Chain)
#[cw_orch::interface(Empty,ExecuteMsg,Empty,Empty)]
struct Cw1<Chain>;

impl<Chain> Cw1<Chain> {
    pub fn test_macro(&self) {
        // Enjoy the nice API! 
        self.freeze().unwrap();
        self.update_admins(vec!["new_admin".to_string()]).unwrap();
        self.deposit(&[Coin::new(13,"juno")]).unwrap();
    }
}

QueryFns

QueryFns派生宏与ExecuteFns宏的工作方式相同,但它还使用来自cosmwasm-schema#[returns(QueryResponse)]属性来生成具有正确响应类型的查询。

嵌套类型

对于嵌套消息(执行和查询),您只需在底层结构上派生ExecuteFnsQueryFns。一般来说,每个实现合约消息的Into特质的结构体都将使该函数在合约上可用。为了使这一点更清晰,以下是一个示例

use cw_orch::interface;
use cw_orch::prelude::*;

// An execute message that is generic.
#[cosmwasm_schema::cw_serde]
pub enum GenericExecuteMsg<T> {
    Generic(T),
}

// A type that will fill the generic.
#[cosmwasm_schema::cw_serde]
#[derive(cw_orch::ExecuteFns)]
pub enum Foo {
    Bar { a: String },
}


// Now we construct the concrete type with `Foo` in place of the generic.
type ExecuteMsg = GenericExecuteMsg<Foo>;
// And we implement the `From` trait (which auto-implements `Into`).
impl From<Foo> for ExecuteMsg {
    fn from(msg: Foo) -> Self {
        ExecuteMsg::Generic(msg)
    }
}

#[interface(Empty, ExecuteMsg, Empty, Empty)]
struct Example<Chain>;

impl<Chain: CwEnv> Example<Chain> {
    pub fn test_macro(&self) {
        // Function `bar` is available because `Foo` implements `Into<GenericExecuteMsg<Foo>>`
        self.bar("hello".to_string()).unwrap();
    }
}

WASM标记

Cw-orch不能在智能合约内部使用。为了防止您需要在智能合约内添加功能标记,当构建WASM目标架构时,库会自动排除。如果您在构建过程中看到如下所示的错误,您将想要target-flag相关代码

error[E0432]: unresolved import `cw_orch::prelude`
 --> contracts/counter/src/interface.rs:4:26
  |
4 | use cw_orch::{interface, prelude::*};
  |                          ^^^^^^^ could not find `prelude` in `cw_orch`

error[E0432]: unresolved import `cw_orch::anyhow`
  --> contracts/counter/src/interface.rs:38:14
   |
38 | use cw_orch::anyhow::Result;
   |              ^^^^^^ could not find `anyhow` in `cw_orch`

error: cannot find macro `artifacts_dir_from_workspace` in this scope
  --> contracts/counter/src/interface.rs:19:9
   |
19 |         artifacts_dir_from_workspace!()
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0405]: cannot find trait `Uploadable` in this scope
  --> contracts/counter/src/interface.rs:16:13
   |
16 | impl<Chain> Uploadable for CounterContract<Chain> {
   |             ^^^^^^^^^^ not found in this scope

只需添加#[cfg(not(target_arch = "wasm32"))]来排除wasm构建中的代码

#[cfg(not(target_arch = "wasm32"))]
mod interface;

支持的链

Cw-orchestrator原生支持以下链:🟥 LocalNet、🟦 Testnet、🟩 Mainnet

  • Archway 🟦🟩
  • Injective 🟦🟩
  • Juno 🟥🟦🟩
  • Kujira 🟦
  • Migaloo 🟥🟦🟩
  • Neutron 🟦🟩
  • Nibiru 🟦
  • Osmosis 🟥🟦🟩
  • Sei 🟥🟦🟩
  • Terra 🟥🟦🟩
  • Rollkit 🟥🟦
  • Xion 🟦
  • Landslide 🟥

可以通过创建一个新的ChainInfo结构体来轻松集成额外的链。这可以直接在您的脚本中完成。如果您有额外的时间,请不要犹豫在这个仓库上提交一个PR。

使用OsmosisTestTube进行测试

OsmosisTestTube可在cw-orchestrator中进行测试。为了使用它,您可能需要安装clanggo来编译作为此环境后端的osmosis区块链。这个编译由cargo直接处理,但如果您没有安装正确的依赖项,可能会出现奇怪的错误。

安装

cw-orch依赖于外部工具才能正常工作。请访问INSTALL.md文件以获取cw-orch在您的机器上正常工作所需的依赖项和安装命令列表。

贡献

我们非常欢迎您的帮助!请阅读我们的贡献指南以开始。

文档

文档使用mdbook生成。编辑docs/src文件夹中的文件并运行

just serve-docs

以查看更改。

发布文档 开发文档

测试

要测试完整的应用程序,您可以运行以下命令

cargo test --jobs 1 --all-features

参考

喜欢轻松地编写智能合约吗?使用Abstract轻松构建您的合约。

免责声明

本软件按现状提供,不提供任何保证。

鸣谢

cw-orchestrator受terra-rust-api的启发,并使用cosmos-rust进行protocol buffer gRPC通信。

依赖项

~2–26MB
~366K SLoC