Skip to content

Commit

Permalink
sui: implement Hello Token example (#51)
Browse files Browse the repository at this point in the history
* sui: implement Hello Token Sui contracts and unit tests

* sui: add integration test suite

* sui: add documentation

* sui: add foreign contracts table directly to state object

* sui: remove parenthesis

---------

Co-authored-by: gator-boi <gator-boi@users.noreply.github.com>
  • Loading branch information
gator-boi and gator-boi authored Jun 21, 2023
1 parent 7756f51 commit bd73924
Show file tree
Hide file tree
Showing 46 changed files with 9,452 additions and 0 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ If your xChain app will require EVM smart contracts, we recommend using [Foundry

If your xChain app will require Solana programs, prepare your development environment by installing [Solana and Anchor dependencies](https://book.anchor-lang.com/getting_started/installation.html), which include `solana` and `anchor` CLI tools.

### SUI

Install the `Sui` CLI. This tool is used to compile the contracts and run the tests.

```sh
cargo install --locked --git https://github.com/MystenLabs/sui.git --rev 09b2081498366df936abae26eea4b2d5cafb2788 sui sui-faucet
```

### Worm CLI

First, checkout the [Wormhole](https://github.com/wormhole-foundation/wormhole) repo, then install the CLI tool by running:

```sh
wormhole/clients/js $ make install
```

`worm` is the swiss army knife for interacting with wormhole contracts on all
supported chains, and generating signed messages (VAAs) for testing.

## Build and Test

Each directory represents Wormhole integrations for specific blockchain networks. Please navigate
Expand Down
8 changes: 8 additions & 0 deletions sui/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
contracts/*/build
sui.log.*
deploy.out
dependencies/wormhole
dependencies/token_bridge
ts/tests/sui_config/authorities_db
ts/tests/sui_config/consensus_db
34 changes: 34 additions & 0 deletions sui/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
include env/testing.env

CONTRACTS := $(wildcard contracts/*/.)

.PHONY: dependencies all clean build test integration-test $(CONTRACTS)

all:

.PHONY: clean
clean:
rm -rf node_modules dependencies/wormhole dependencies/token_bridge ts/tests/sui_config/*_db/

dependencies: node_modules dependencies/wormhole/build dependencies/token_bridge/build

node_modules:
yarn

dependencies/token_bridge/build: dependencies/wormhole/build

dependencies/wormhole/build:
bash shell-scripts/fetch_wormhole_contracts.sh

.PHONY: test
test: unit-test integration-test

.PHONY: unit-test
unit-test: $(CONTRACTS)

$(CONTRACTS):
$(MAKE) -C $@ test

.PHONY: integration-test
integration-test: dependencies
bash shell-scripts/run_integration_tests.sh
58 changes: 58 additions & 0 deletions sui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Wormhole Integration in Sui

These programs are enumerated the same as the other smart contract
subdirectories (e.g. [solana](../solana)).

## Design Documents

Read the design documents for each example project (only `HelloToken` is implemented for Sui currently):

1. [HelloWorld](../docs/01_hello_world.md)
2. [HelloToken](../docs/02_hello_token.md)

## Dependencies

Install the `Sui` CLI. This tool is used to compile the contracts and run the tests.

```sh
cargo install --locked --git https://github.com/MystenLabs/sui.git --rev 09b2081498366df936abae26eea4b2d5cafb2788 sui sui-faucet
```

### Worm CLI

First, checkout the [Wormhole](https://github.com/wormhole-foundation/wormhole) repo, then install the CLI tool by running:

```sh
wormhole/clients/js $ make install
```

`worm` is the swiss army knife for interacting with wormhole contracts on all
supported chains, and generating signed messages (VAAs) for testing.

## Build

Run the following commands to install the necessary Wormhole and Token Bridge dependencies:

```
make dependencies
```

## Testing Environment

The testing environments can be found in the following locations:

- [Unit Tests](./contracts/hello_token/) (see the source code)
- [Integration Tests](./ts/tests/02_hello_token.ts)

You can run the tests with the following commands:

```
# Move-based Unit tests
make unit-test
# local-validator integration tests written in typescript
make integration-test
# unit tests and local-validator integration tests
make test
```
15 changes: 15 additions & 0 deletions sui/contracts/example_coins/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.PHONY: all clean test check

all: check

.PHONY: clean
clean:
rm -rf build

.PHONY: check
check:
sui move build -d

.PHONY: test
test:
sui move test -d
11 changes: 11 additions & 0 deletions sui/contracts/example_coins/Move.devnet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "ExampleCoins"
version = "0.1.0"

[dependencies.Sui]
git = "https://github.com/MystenLabs/sui.git"
subdir = "crates/sui-framework/packages/sui-framework"
rev = "09b2081498366df936abae26eea4b2d5cafb2788"

[addresses]
example_coins = "0xbfa8d913ccc41ca8522c2f0b3567097316a70ae0eb00bb290d08f9c9047056ce"
20 changes: 20 additions & 0 deletions sui/contracts/example_coins/Move.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# @generated by Move, please check-in and do not edit manually.

[move]
version = 0

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

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

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

dependencies = [
{ name = "MoveStdlib" },
]
14 changes: 14 additions & 0 deletions sui/contracts/example_coins/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "ExampleCoins"
version = "0.1.0"

[dependencies.Sui]
git = "https://github.com/MystenLabs/sui.git"
subdir = "crates/sui-framework/packages/sui-framework"
rev = "09b2081498366df936abae26eea4b2d5cafb2788"

[addresses]
example_coins = "_"

[dev-addresses]
example_coins = "0x0"
72 changes: 72 additions & 0 deletions sui/contracts/example_coins/sources/coin_10.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
module example_coins::coin_10 {
use std::option;
use sui::coin::{Self, TreasuryCap, CoinMetadata};
use sui::transfer;
use sui::tx_context::{Self, TxContext};

/// The type identifier of coin. The coin will have a type
/// tag of kind: `Coin<package_object::coin_10::COIN_10>`
/// Make sure that the name of the type matches the module's name.
struct COIN_10 has drop {}

/// Module initializer is called once on module publish. A treasury
/// cap is sent to the publisher, who then controls minting and burning
fun init(witness: COIN_10, ctx: &mut TxContext) {
let (treasury, metadata) = create_coin(witness, ctx);
transfer::public_freeze_object(metadata);
transfer::public_transfer(treasury, tx_context::sender(ctx));
}

fun create_coin(
witness: COIN_10,
ctx: &mut TxContext
): (TreasuryCap<COIN_10>, CoinMetadata<COIN_10>) {
coin::create_currency(
witness,
10, // decimals
b"COIN_10", // symbol
b"10-Decimal Coin", // name
b"", // description
option::none(), // icon_url
ctx
)
}

#[test_only]
public fun create_coin_test_only(
ctx: &mut TxContext
): (TreasuryCap<COIN_10>, CoinMetadata<COIN_10>) {
create_coin(COIN_10 {}, ctx)
}

#[test_only]
public fun init_test_only(ctx: &mut TxContext) {
init(COIN_10 {}, ctx)
}
}

#[test_only]
module example_coins::coin_10_tests {
use sui::test_scenario::{Self};

use example_coins::coin_10::{Self};

#[test]
public fun init_test() {
let my_scenario = test_scenario::begin(@0x0);
let scenario = &mut my_scenario;
let creator = @0xDEADBEEF;

// Proceed.
test_scenario::next_tx(scenario, creator);

// Init.
coin_10::init_test_only(test_scenario::ctx(scenario));

// Proceed.
test_scenario::next_tx(scenario, creator);

// Done.
test_scenario::end(my_scenario);
}
}
72 changes: 72 additions & 0 deletions sui/contracts/example_coins/sources/coin_8.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
module example_coins::coin_8 {
use std::option::{Self};
use sui::coin::{Self, TreasuryCap, CoinMetadata};
use sui::transfer::{Self};
use sui::tx_context::{Self, TxContext};

/// The type identifier of coin. The coin will have a type
/// tag of kind: `Coin<package_object::coin_8::COIN_8>`
/// Make sure that the name of the type matches the module's name.
struct COIN_8 has drop {}

/// Module initializer is called once on module publish. A treasury
/// cap is sent to the publisher, who then controls minting and burning
fun init(witness: COIN_8, ctx: &mut TxContext) {
let (treasury, metadata) = create_coin(witness, ctx);
transfer::public_freeze_object(metadata);
transfer::public_transfer(treasury, tx_context::sender(ctx));
}

fun create_coin(
witness: COIN_8,
ctx: &mut TxContext
): (TreasuryCap<COIN_8>, CoinMetadata<COIN_8>) {
coin::create_currency(
witness,
8, // decimals
b"COIN_8", // symbol
b"8-Decimal Coin", // name
b"", // description
option::none(), // icon_url
ctx
)
}

#[test_only]
public fun create_coin_test_only(
ctx: &mut TxContext
): (TreasuryCap<COIN_8>, CoinMetadata<COIN_8>) {
create_coin(COIN_8 {}, ctx)
}

#[test_only]
public fun init_test_only(ctx: &mut TxContext) {
init(COIN_8 {}, ctx)
}
}

#[test_only]
module example_coins::coin_8_tests {
use sui::test_scenario::{Self};

use example_coins::coin_8::{Self};

#[test]
public fun init_test() {
let my_scenario = test_scenario::begin(@0x0);
let scenario = &mut my_scenario;
let creator = @0xDEADBEEF;

// Proceed.
test_scenario::next_tx(scenario, creator);

// Init.
coin_8::init_test_only(test_scenario::ctx(scenario));

// Proceed.
test_scenario::next_tx(scenario, creator);

// Done.
test_scenario::end(my_scenario);
}
}
15 changes: 15 additions & 0 deletions sui/contracts/hello_token/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.PHONY: all clean test check

all: check

.PHONY: clean
clean:
rm -rf build

.PHONY: check
check:
sui move build -d

.PHONY: test
test:
sui move test -t 1
18 changes: 18 additions & 0 deletions sui/contracts/hello_token/Move.devnet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "HelloToken"
version = "0.1.0"
published-at = "0x3b17ab9de6f1f14ee30fc3150e66fb86dbde7cffcbe5e76c108b29633c372120"

[dependencies.Sui]
git = "https://github.com/MystenLabs/sui.git"
subdir = "crates/sui-framework/packages/sui-framework"
rev = "09b2081498366df936abae26eea4b2d5cafb2788"

[dependencies.Wormhole]
local = "../../dependencies/wormhole"

[dependencies.TokenBridge]
local = "../../dependencies/token_bridge"

[addresses]
hello_token = "0x3b17ab9de6f1f14ee30fc3150e66fb86dbde7cffcbe5e76c108b29633c372120"
Loading

0 comments on commit bd73924

Please sign in to comment.