Skip to content
Open
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
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: sui move test
run: docker run -i -v $(pwd):/sui $SUI_IMAGE sui move test
run: |
cd contracts/gateway
docker run -i -v $(pwd):/sui $SUI_IMAGE sui move test

ci-ok:
runs-on: ubuntu-22.04
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,19 @@ jobs:

- name: sui move build --doc
run: |
cd contracts/gateway
docker run -i -v $(pwd):/sui $SUI_IMAGE sui move build --doc
yarn docs

- name: Check if docs/ changed
id: changes
run: |
git add docs/
git diff --staged --quiet docs/ || echo "docs_changed=true" >> $GITHUB_OUTPUT
git add contracts/gateway/docs/
git diff --staged --quiet contracts/gateway/docs/ || echo "docs_changed=true" >> $GITHUB_OUTPUT

- name: Print warning if docs changed
if: steps.changes.outputs.docs_changed == 'true'
run: |
echo "⚠️ Changes detected in docs/"
echo "⚠️ Changes detected in contracts/gateway/docs/"
git status
git diff --staged docs/
git diff --staged contracts/gateway/docs/
6 changes: 4 additions & 2 deletions .github/workflows/publish-npm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ jobs:

- name: Build and Generate Gateway JSON
run: |
cd contracts/gateway
docker run -i -v $(pwd):/sui -v ~/.sui:/root/.sui $SUI_IMAGE sh -c "sui client -y && sui move build --dump-bytecode-as-base64 | tee /sui/gateway.json"

- name: Fix permissions
run: sudo chown $(whoami) gateway.json
run: sudo chown $(whoami) contracts/gateway/gateway.json

- name: Verify gateway.json
run: cat gateway.json
run: cat contracts/gateway/gateway.json

- name: Determine NPM Tag
id: determine-npm-tag
Expand All @@ -39,6 +40,7 @@ jobs:

- name: Publish to NPM
run: |
cd contracts/gateway
yarn publish --access public --new-version ${GITHUB_REF#refs/tags/v} --tag ${{
steps.determine-npm-tag.outputs.NPM_TAG }} --no-git-tag-version
env:
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.idea
.vscode

build/*
.DS_Store
7 changes: 7 additions & 0 deletions contracts/example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.idea
.vscode

build/*
source/dependencies
*.key
.DS_Store
16 changes: 16 additions & 0 deletions contracts/example/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.PHONY: clean build

# Clean build directory
clean:
rm -rf Move.lock build/

# Build the package and generate bytecode
build:
sui move build

# Help target
help:
@echo "Available targets:"
@echo " clean - Remove build directory"
@echo " build - Build the example package and generate bytecode"
@echo " help - Show this help message"
68 changes: 68 additions & 0 deletions contracts/example/Move.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# @generated by Move, please check-in and do not edit manually.

[move]
version = 3
manifest_digest = "540B90B0BDF4F208EEEE9D76F38DE4C9240A0190640DD30688D3D5E828802CC7"
deps_digest = "397E6A9F7A624706DBDFEE056CE88391A15876868FD18A88504DA74EB458D697"
dependencies = [
{ id = "Bridge", name = "Bridge" },
{ id = "MoveStdlib", name = "MoveStdlib" },
{ id = "Sui", name = "Sui" },
{ id = "SuiSystem", name = "SuiSystem" },
{ id = "gateway", name = "gateway" },
]

[[move.package]]
id = "Bridge"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "494fa6ede17f366f1cd850f01ccb9f42dc75c470", subdir = "crates/sui-framework/packages/bridge" }

dependencies = [
{ id = "MoveStdlib", name = "MoveStdlib" },
{ id = "Sui", name = "Sui" },
{ id = "SuiSystem", name = "SuiSystem" },
]

[[move.package]]
id = "MoveStdlib"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "494fa6ede17f366f1cd850f01ccb9f42dc75c470", subdir = "crates/sui-framework/packages/move-stdlib" }

[[move.package]]
id = "Sui"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "494fa6ede17f366f1cd850f01ccb9f42dc75c470", subdir = "crates/sui-framework/packages/sui-framework" }

dependencies = [
{ id = "MoveStdlib", name = "MoveStdlib" },
]

[[move.package]]
id = "SuiSystem"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "494fa6ede17f366f1cd850f01ccb9f42dc75c470", subdir = "crates/sui-framework/packages/sui-system" }

dependencies = [
{ id = "MoveStdlib", name = "MoveStdlib" },
{ id = "Sui", name = "Sui" },
]

[[move.package]]
id = "gateway"
source = { local = "../gateway" }

dependencies = [
{ id = "Bridge", name = "Bridge" },
{ id = "MoveStdlib", name = "MoveStdlib" },
{ id = "Sui", name = "Sui" },
{ id = "SuiSystem", name = "SuiSystem" },
]

[move.toolchain-version]
compiler-version = "1.59.1"
edition = "2024.beta"
flavor = "sui"

[env]

[env.testnet]
chain-id = "4c78adac"
original-published-id = "0xb8341e97cd48794aad9877297923586c137942f1647dd8b3ce70182113c1008c"
latest-published-id = "0xb8341e97cd48794aad9877297923586c137942f1647dd8b3ce70182113c1008c"
published-version = "1"
37 changes: 37 additions & 0 deletions contracts/example/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[package]
name = "example"
edition = "2024.beta" # edition = "legacy" to use legacy (pre-2024) Move
published-at = "0xb8341e97cd48794aad9877297923586c137942f1647dd8b3ce70182113c1008c"
# license = "" # e.g., "MIT", "GPL", "Apache 2.0"
# authors = ["..."] # e.g., ["Joe Smith ([email protected])", "John Snow ([email protected])"]

[dependencies]
gateway = { local = "../gateway"}

# For remote import, use the `{ git = "...", subdir = "...", rev = "..." }`.
# Revision can be a branch, a tag, and a commit hash.
# MyRemotePackage = { git = "https://some.xwremote/host.git", subdir = "remote/path", rev = "main" }

# For local dependencies use `local = path`. Path is relative to the package root
# Local = { local = "../path/to" }

# To resolve a version conflict and force a specific version for dependency
# override use `override = true`
# Override = { local = "../conflicting/version", override = true }

[addresses]
example = "0x0"

# Named addresses will be accessible in Move as `@name`. They're also exported:
# for example, `std = "0x1"` is exported by the Standard Library.
# alice = "0xA11CE"

[dev-dependencies]
# The dev-dependencies section allows overriding dependencies for `--test` and
# `--dev` modes. You can introduce test-only dependencies here.
# Local = { local = "../path/to/dev-build" }

[dev-addresses]
# The dev-addresses section allows overwriting named addresses for the `--test`
# and `--dev` modes.
# alice = "0xB0B"
95 changes: 95 additions & 0 deletions contracts/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# SUI WithdrawAndCall with PTB Transactions

This document explains how the SUI `withdrawAndCall` functionality works using Programmable Transaction Blocks (PTB) in the ZetaChain protocol.

## Overview

The `withdrawAndCall` operation in ZetaChain allows users to withdraw tokens from ZEVM to the Sui blockchain and simultaneously calls a `on_call` function in the `connected` module on the Sui side.

This is implemented as a single atomic transaction using Sui's Programmable Transaction Blocks (PTB).

## Transaction Flow

1. **User Initiates Withdrawal**: A user initiates a withdrawal from ZEVM to Sui with a `on_call` payload.

2. **ZEVM Processing**: The ZEVM gateway processes the withdrawal request and prepares the transaction.

3. **PTB Construction**: A Programmable Transaction Block is constructed with the following steps:
- **Withdraw**: The first command in the PTB is the `withdraw_impl` function call, which:
- Verifies the withdrawal parameters
- Withdraw and returns two coin objects: the main withdrawn coins and the gas budget coins
- **Gas Budget Transfer**: The second command transfers the gas budget coins to the TSS address to cover transaction fees.
- The gas budget is the SUI coin withdrawn from sui vault, together with withdrawn CCTX's coinType.
- The gas budget needs to be forwarded to TSS address to cover the transaction fee.
- **Set Message Context**: The third command in the PTB is `set_message_context`
- It sets the `sender` and `target` in message context object right before calling `on_call` function in the `target` package.
- It allows the `on_call` function to perform authentication checks for the call.
- **Connected Module Call**: The fourth command calls the `on_call` function in the connected module, passing:
- The withdrawn coins
- The call payload from the user
- Any additional parameters required by the connected module
- **Reset Message Context**: The fifth command in the PTB is `reset_message_context`
- It clears the `sender` and `target` in message context object right after calling `on_call` function in the `target` package.
- This is to ensure that each `withdrawAndCall` use independent message context information.

4. **Transaction Execution**: The entire PTB is executed atomically on the Sui blockchain.

## PTB Structure

The PTB for a `withdrawAndCall` transaction consists of five commands:

```text
PTB {
// Command 0: Withdraw Implementation
MoveCall {
package: gateway_package_id,
module: gateway_module,
function: withdraw_impl,
arguments: [
gateway_object_ref,
withdraw_cap_object_ref,
coin_type,
amount,
nonce,
gas_budget
]
}

// Command 1: Gas Budget Transfer
TransferObjects {
from: withdraw_impl_result[1], // Gas budget coins
to: tss_address
}

// Command 2: Set Message Context
MoveCall {
package: gateway_package_id,
module: gateway_module,
function: set_message_context,
arguments: [
message_context,
zevm_sender,
target_package_id
]
}

// Command 3: Connected Module Call
MoveCall {
package: target_package_id,
module: connected_module,
function: on_call,
arguments: [
withdraw_impl_result[0], // Main withdrawn coins
on_call_payload
]
}

// Command 4: Reset Message Context
MoveCall {
package: gateway_package_id,
module: gateway_module,
function: reset_message_context,
arguments: [message_context]
}
}
```
Loading