16个版本 (8个破坏性)

0.24.0 2024年8月21日
0.23.3 2024年7月24日
0.22.2 2024年6月18日
0.20.4 2024年3月26日
0.18.1 2023年11月22日

#3#cw

Download history 1111/week @ 2024-04-29 396/week @ 2024-05-06 628/week @ 2024-05-13 649/week @ 2024-05-20 1107/week @ 2024-05-27 1036/week @ 2024-06-03 1791/week @ 2024-06-10 1270/week @ 2024-06-17 1422/week @ 2024-06-24 891/week @ 2024-07-01 1557/week @ 2024-07-08 950/week @ 2024-07-15 1043/week @ 2024-07-22 803/week @ 2024-07-29 680/week @ 2024-08-05 650/week @ 2024-08-12

3,209 每月下载量
用于 15 个crate(3直接)

GPL-3.0-only

125KB
2.5K SLoC

cw-orchestrator

docs.rs Crates.io Codecov

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

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

工作原理

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

维护的接口

我们维护了一组小的接口,我们在自己的项目中使用它们。这些接口由Abstract团队维护,是使用库的好参考。

代码库 最新版本
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 通信。

依赖项

~13–26MB
~389K SLoC