Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ The format is based on [Keep a Changelog], and this project adheres to

## [Unreleased]

## [0.2.0] - 2026-08-27

### Changed

- Correct crate documentation and examples for the stable release.

## [0.2.0-rc.1] - 2026-08-27

### Added
Expand All @@ -29,12 +35,11 @@ The format is based on [Keep a Changelog], and this project adheres to

### Changed

- Publish the workspace under the `talus-sui-move-*` crates.io package names owned by Talus and use
the matching `talus_sui_move*` Rust library names.
- Generated package scopes now resolve type identity by module and datatype while calls continue to
use the current package address.

[Keep a Changelog]: https://keepachangelog.com/en/1.1.0/
[Semantic Versioning]: https://semver.org/spec/v2.0.0.html
[Unreleased]: https://github.com/Talus-Network/move-binding/compare/v0.2.0-rc.1...HEAD
[Unreleased]: https://github.com/Talus-Network/move-binding/compare/v0.2.0...HEAD
[0.2.0]: https://github.com/Talus-Network/move-binding/compare/v0.2.0-rc.1...v0.2.0
[0.2.0-rc.1]: https://github.com/Talus-Network/move-binding/compare/v0.1.0...v0.2.0-rc.1
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 7 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,19 @@ members = [
]

[workspace.package]
version = "0.2.0-rc.1"
version = "0.2.0"
edition = "2021"
rust-version = "1.90"
license = "Apache-2.0"
repository = "https://github.com/Talus-Network/move-binding"
homepage = "https://github.com/Talus-Network/move-binding"

[workspace.dependencies]
talus-sui-move = { version = "=0.2.0-rc.1", path = "sui-move" }
talus-sui-move-derive = { version = "=0.2.0-rc.1", path = "sui-move-derive" }
talus-sui-move-call = { version = "=0.2.0-rc.1", path = "sui-move-call" }
talus-sui-move-ptb = { version = "=0.2.0-rc.1", path = "sui-move-ptb" }
talus-sui-move-runtime = { version = "=0.2.0-rc.1", path = "sui-move-runtime" }
talus-sui-move-codegen = { version = "=0.2.0-rc.1", path = "sui-move-codegen" }
talus-sui-move = { version = "=0.2.0", path = "sui-move" }
talus-sui-move-derive = { version = "=0.2.0", path = "sui-move-derive" }
talus-sui-move-call = { version = "=0.2.0", path = "sui-move-call" }
talus-sui-move-ptb = { version = "=0.2.0", path = "sui-move-ptb" }
talus-sui-move-runtime = { version = "=0.2.0", path = "sui-move-runtime" }
talus-sui-move-codegen = { version = "=0.2.0", path = "sui-move-codegen" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
Expand Down
18 changes: 8 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,22 @@

Layered crates for writing typed, ergonomic Move interactions on Sui from Rust.

This workspace is intentionally “deep”: each crate is a small abstraction that solves one problem,
and higher layers build on lower ones.
Each crate is a small abstraction that solves one problem, and the crates can be adopted
individually.

The primary mental model is **Read → Tx → Commit** with a **cursor** that advances your local
frontier by applying transaction effects. See `MODEL.md`.

## Status

The `0.2.0-rc.1` release candidate is the first release under crates.io package names owned by Talus.
Public APIs may change before `1.0`; treat the crate boundaries and the `MODEL.md` invariants as
more stable than individual function names.
This is a pre-1.0 project. Public APIs may change before `1.0`; treat the crate boundaries and the
`MODEL.md` invariants as more stable than individual function names.

## Packages (low → high)
## Crates

The crates.io package names and Rust library names use the same Talus prefix. This gives consumers
one consistent name in Cargo and source code.
Cargo package names use hyphens, while Rust imports use underscores.

| crates.io package | Rust crate | Role |
| Cargo package | Rust import | Role |
| --- | --- | --- |
| `talus-sui-move` | `talus_sui_move` | Rust representations of Move types, abilities, and decoding helpers |
| `talus-sui-move-derive` | `talus_sui_move_derive` | Derive macros for Rust structs that represent Move structs |
Expand All @@ -32,7 +30,7 @@ For example:

```toml
[dependencies]
talus-sui-move = { version = "=0.2.0-rc.1", features = ["derive"] }
talus-sui-move = { version = "=0.2.0", features = ["derive"] }
```

```rust
Expand Down
3 changes: 1 addition & 2 deletions sui-move-call/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ readme = "README.md"
publish = ["crates-io"]
license.workspace = true
repository.workspace = true
homepage.workspace = true
documentation = "https://docs.rs/talus-sui-move-call"
keywords = ["sui", "move", "blockchain", "transactions"]
keywords = ["sui", "move", "blockchain", "transactions", "talus"]
categories = ["api-bindings", "development-tools"]

[dependencies]
Expand Down
34 changes: 20 additions & 14 deletions sui-move-call/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,21 @@

Typed building blocks for describing Move calls on Sui.

The crates.io package is `talus-sui-move-call`; Rust code imports it as `talus_sui_move_call`.

This crate builds on top of [`talus-sui-move`](https://docs.rs/talus-sui-move) and solves one problem:
**describe a Move call in a typed way** (object handles + type arguments + arguments) without
building or executing transactions.

## Where it fits
## Relationship to the other crates

`talus-sui-move-call` is the “Call” layer in the repository’s
[Read → Tx → Commit model](https://github.com/Talus-Network/move-binding/blob/main/MODEL.md):
`talus-sui-move-call` uses `MoveType` and `MoveStruct` from `talus-sui-move` to build call
descriptions whose types are checked by Rust:

- **Read** (runtime) fetches objects and classifies ownership from chain state.
- **Call** (this crate) describes *what* to call and how to encode arguments.
- **PTB** builds a `ProgrammableTransaction` from a `CallSpec`.
- **Commit** (runtime) submits and applies effects to advance the cursor.
- `talus-sui-move-call` describes what to call and how to encode arguments.
- `talus-sui-move-ptb` can turn a `CallSpec` into a `ProgrammableTransaction`.
- `talus-sui-move-runtime` can submit that transaction and update typed handles.

This crate sits directly above `talus-sui-move`: it uses `MoveType` and `MoveStruct` to build call
descriptions (`CallSpec`) whose types are checked by Rust. Transaction building and execution are
intentionally out of scope.
This crate can be used independently when an application only needs typed call descriptions.
Transaction building and execution are intentionally out of scope.

## Core types

Expand Down Expand Up @@ -78,9 +74,14 @@ use talus_sui_move::prelude::*;
use talus_sui_move_call::{CallSpec, MoveObject};
use sui_sdk_types::{Address, Digest, ObjectReference, TypeTag};

#[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "copy, drop, store")]
pub struct ID {
pub bytes: Address,
}

#[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "store")]
pub struct UID {
pub id: u64,
pub id: ID,
}

#[talus_sui_move::move_struct(address = "0x1", module = "vault", abilities = "key")]
Expand Down Expand Up @@ -122,9 +123,14 @@ use std::str::FromStr;
use talus_sui_move_call::{CallArg, CallSpec, ReceivingMoveObject, SharedMoveObject};
use sui_sdk_types::{Address, Digest, ObjectReference};

#[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "copy, drop, store")]
struct ID {
bytes: Address,
}

#[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "store")]
struct UID {
id: u64,
id: ID,
}

#[talus_sui_move::move_struct(address = "0x1", module = "demo", abilities = "key")]
Expand Down
20 changes: 16 additions & 4 deletions sui-move-call/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ pub use sui_sdk_types::Input as CallArg;
/// use talus_sui_move_call::MoveObject;
/// use sui_sdk_types::{Address, Digest, ObjectReference};
///
/// # #[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "copy, drop, store")]
/// # struct ID { bytes: Address }
/// #
/// # #[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "store")]
/// # struct UID { id: u64 }
/// # struct UID { id: ID }
/// #
/// #[talus_sui_move::move_struct(address = "0x1", module = "demo", abilities = "key")]
/// struct Demo {
Expand Down Expand Up @@ -85,8 +88,11 @@ impl<T: MoveStruct + HasKey> MoveObject<T> {
/// use talus_sui_move_call::SharedMoveObject;
/// use sui_sdk_types::Address;
///
/// # #[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "copy, drop, store")]
/// # struct ID { bytes: Address }
/// #
/// # #[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "store")]
/// # struct UID { id: u64 }
/// # struct UID { id: ID }
/// #
/// #[talus_sui_move::move_struct(address = "0x1", module = "demo", abilities = "key")]
/// struct SharedThing {
Expand Down Expand Up @@ -174,8 +180,11 @@ impl<T: MoveStruct + HasKey> SharedMoveObject<T> {
/// use talus_sui_move_call::ReceivingMoveObject;
/// use sui_sdk_types::{Address, Digest, ObjectReference};
///
/// # #[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "copy, drop, store")]
/// # struct ID { bytes: Address }
/// #
/// # #[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "store")]
/// # struct UID { id: u64 }
/// # struct UID { id: ID }
/// #
/// #[talus_sui_move::move_struct(address = "0x1", module = "demo", abilities = "key")]
/// struct ReceivingThing {
Expand Down Expand Up @@ -427,8 +436,11 @@ impl CallTarget {
/// use talus_sui_move_call::{CallSpec, MoveObject};
/// use sui_sdk_types::{Address, Digest, ObjectReference, TypeTag};
///
/// # #[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "copy, drop, store")]
/// # struct ID { bytes: Address }
/// #
/// # #[talus_sui_move::move_struct(address = "0x2", module = "object", abilities = "store")]
/// # struct UID { id: u64 }
/// # struct UID { id: ID }
/// #
/// #[talus_sui_move::move_struct(address = "0x1", module = "vault", abilities = "key")]
/// struct Vault {
Expand Down
3 changes: 1 addition & 2 deletions sui-move-codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ readme = "README.md"
publish = ["crates-io"]
license.workspace = true
repository.workspace = true
homepage.workspace = true
documentation = "https://docs.rs/talus-sui-move-codegen"
keywords = ["sui", "move", "blockchain", "codegen"]
keywords = ["sui", "move", "blockchain", "codegen", "talus"]
categories = ["api-bindings", "development-tools"]

[dependencies]
Expand Down
13 changes: 6 additions & 7 deletions sui-move-codegen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

Generate typed Rust bindings for a Move package on Sui.

The crates.io package is `talus-sui-move-codegen`; Rust code imports it as `talus_sui_move_codegen`.

This crate solves one problem: **turn Move package metadata fetched from Sui into Rust source
code** that fits the layered `talus-sui-move*` stack.
code** compatible with the Talus Sui Move crates:

- `talus-sui-move`: Rust representations of Move types (`MoveType`, `MoveStruct`, abilities)
- `talus-sui-move-call`: `CallSpec` + typed argument traits (`ToCallArg`, `ObjectArg<T>`)
Expand Down Expand Up @@ -80,7 +78,8 @@ Given a `NormalizedPackage` (either fetched from gRPC or loaded from JSON), this
- (optional) A `TxExt` trait implemented for `talus_sui_move_runtime::Tx` (enable with
`RenderOptions::emit_tx_ext`)

Those generated call builders are designed to be used directly in higher layers:
Those generated call builders can be used directly with:

- `talus-sui-move-ptb` can consume `CallSpec` to build a `ProgrammableTransaction`
- `talus-sui-move-runtime` can consume `CallSpec` via its tx builder (or `talus_sui_move_runtime::tx!`)

Expand Down Expand Up @@ -525,9 +524,9 @@ expects these crates in the consumer’s `Cargo.toml`:

```toml
[dependencies]
talus-sui-move = "=0.2.0-rc.1"
talus-sui-move-derive = "=0.2.0-rc.1"
talus-sui-move-call = "=0.2.0-rc.1"
talus-sui-move = "=0.2.0"
talus-sui-move-derive = "=0.2.0"
talus-sui-move-call = "=0.2.0"
```

If you want to execute calls, add higher layers (`talus-sui-move-ptb`,
Expand Down
2 changes: 1 addition & 1 deletion sui-move-codegen/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! - commit that IR as JSON (optional),
//! - render Rust source from the IR in CI/builds (offline).
//!
//! The generated code is designed to plug into the rest of the workspace:
//! The generated code is designed to work with the other Talus Sui Move crates:
//! - generated types implement `talus-sui-move` traits (`MoveType` / `MoveStruct`) and ability markers
//! - generated call targets identify Move functions for PTB builders
//! - generated call specification builders can return `talus-sui-move-call::CallSpec`
Expand Down
3 changes: 1 addition & 2 deletions sui-move-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ readme = "README.md"
publish = ["crates-io"]
license.workspace = true
repository.workspace = true
homepage.workspace = true
documentation = "https://docs.rs/talus-sui-move-derive"
keywords = ["sui", "move", "blockchain", "proc-macro"]
keywords = ["sui", "move", "blockchain", "proc-macro", "talus"]
categories = ["development-tools::procedural-macro-helpers"]

[lib]
Expand Down
20 changes: 11 additions & 9 deletions sui-move-derive/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
# talus-sui-move-derive

Procedural macros for [`talus-sui-move`](https://docs.rs/talus-sui-move): define Rust types that
represent Move types with minimal boilerplate. The package is `talus-sui-move-derive`; Rust code
imports it as `talus_sui_move_derive`.
represent Move types with minimal boilerplate.

This crate exists to solve one problem: **turn a Rust struct into a representation of a Move type**
with the correct `TypeTag`, `StructTag`, and ability markers. It can then use the type tag plumbing
and verified decoding in `talus-sui-move`.

## Where it fits
## Relationship to `talus-sui-move`

In the repository’s layered
[stack](https://github.com/Talus-Network/move-binding/blob/main/MODEL.md),
`talus-sui-move-derive` is a convenience layer for the bottom type system (`talus-sui-move`):
`talus-sui-move-derive` is the optional procedural macro companion to `talus-sui-move`:

- you describe the Move identity (`address`, `module`, `abilities`) as attributes,
- the macro generates the corresponding `talus_sui_move::MoveType` / `talus_sui_move::MoveStruct` impls and
Expand Down Expand Up @@ -57,7 +54,7 @@ Most users should depend on `talus-sui-move` and enable its `derive` feature, wh

```toml
[dependencies]
talus-sui-move = { version = "=0.2.0-rc.1", features = ["derive"] }
talus-sui-move = { version = "=0.2.0", features = ["derive"] }
```

Then use:
Expand Down Expand Up @@ -172,12 +169,17 @@ pub struct MissingId {
Similarly, invalid ability combinations are rejected:

```rust,compile_fail
use talus_sui_move::prelude::Address;
use talus_sui_move_derive::move_struct;

/// Minimal UID fixture defined by a package for the compilation failure example.
#[move_struct(address = "0x2", module = "object", abilities = "copy, drop, store")]
pub struct ID {
pub bytes: Address,
}

#[move_struct(address = "0x2", module = "object", abilities = "store")]
pub struct UID {
pub id: u64,
pub id: ID,
}

// A struct cannot be both `key` and `copy`.
Expand Down
Loading
Loading