Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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