19个版本 (8个稳定版)

新版本 2.0.0 2024年8月21日
1.2.4 2024年8月23日
1.2.2 2024年7月24日
0.21.1 2024年2月28日
0.18.0 2023年11月3日

#412 in 神奇豆

Download history 623/week @ 2024-05-05 1195/week @ 2024-05-12 859/week @ 2024-05-19 1525/week @ 2024-05-26 1681/week @ 2024-06-02 2090/week @ 2024-06-09 1365/week @ 2024-06-16 1974/week @ 2024-06-23 971/week @ 2024-06-30 2039/week @ 2024-07-07 1526/week @ 2024-07-14 1215/week @ 2024-07-21 1131/week @ 2024-07-28 844/week @ 2024-08-04 1200/week @ 2024-08-11 1393/week @ 2024-08-18

4,628 每月下载量
53 个crate中使用 (13个直接使用)

GPL-3.0-only

96KB
2K SLoC

cw-orchestrator

docs.rs Crates.io Codecov

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

本处的文档为您提供了cw-orchestrator提供的功能简短概述。我们还在orchestrator.abstract.money提供了更多文档。

工作原理

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

维护的接口

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

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

创建接口

为了生成合约的泛型接口,您可以将合约的消息类型传递到 cw_orch::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 宏可以添加到您的合约的 ExecuteMsg 定义中。这将生成一个特质,允许您直接调用消息的变体,而无需自己构建结构体。

ExecuteFns 宏仅在编译为非WASM目标时应用于消息。

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 派生宏与 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 本地支持以下链:🟥 本地网,🟦 测试网,🟩 主网

  • 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进行协议缓冲 gRPC通信。

依赖项

~13-26MB
~391K SLoC