Skip to content

OpenZeppelin/openzeppelin-sui-marketplace

Warning

This is experimental UN-AUDITED code

Sui Oracle Market

End-to-end example of a small on-chain market on Sui: items are priced in USD cents (stablecoin-style), while buyers can pay in multiple currencies using oracle prices.

This repo is a pnpm workspace containing:

  • a Move package packages/dapp/contracts/oracle-market,
  • a CLI/script layer for localnet + seeding + owner/buyer flows dapp/scripts
  • state artefact captured in (packages/dapp/deployments)
  • a Next.js UI packages/ui,
  • a docs site with learning path to help transition from EVM/Solidity to Sui/Move packages/learn.
  • a tooling layer with integration test harness packages/tooling

More detail (workspace layering rules, folder layout): docs/01-repo-layout.md.

Prerequisites

Environment Setup

Set up your environment with an active address and a running localnet to publish and interact with the oracle-market package.

Full walkthrough: docs/05-localnet-workflow.md.

# 1) Clone and install
git clone [email protected]:OpenZeppelin/openzeppelin-sui-marketplace.git && cd openzeppelin-sui-marketplace
# (pnpm workspace install from the repo root)
pnpm install

# Create an address (it will be your shop owner address). Note the recovery phrase to import it later in your browser wallet.
sui client new-address ed25519

# Configure this address in ./packages/dapp/.env , Sui config file or export
export SUI_NETWORK=localnet
export SUI_ACCOUNT_ADDRESS=<0x...>
export SUI_ACCOUNT_PRIVATE_KEY=<base64 or hex>

# Optionally create a second address to represent the buyer (the owner address can also buy items) (take note of the recovery phrase)
sui client new-address ed25519

# Start localnet (new terminal) (--with-faucet is recommended as some script auto fund address if fund is missing, on first start it will fund your configured address)
pnpm script chain:localnet:start --with-faucet

# Seed mocks (coins + Pyth stub + price feeds) on localnet as there is no coins or published Pyth oracle on your blank localnet
pnpm script mock:setup --buyer-address <0x...> --network localnet

Publish and Seed

Load some shop data

# Publish oracle-market
pnpm script move:publish --package-path oracle-market

# In the output of the above command, after the success message, you will find the packageId for the shop contract.
# You can set the value as an environment variable:
export NEXT_PUBLIC_LOCALNET_CONTRACT_PACKAGE_ID=<0x...>

# or you can make it more permanent by adding it to ./packages/ui/.env file (there's a ./packages/ui/.env.example for reference)

# To continue setting up the shop, listings, discounts, accepted currencies follow appropriate scripts (find the list here docs/06-scripts-reference.md) or run the seed script that will load data for each model
pnpm script owner:shop:seed

# Run the UI
pnpm ui dev

Learning path

Start the docs website and follow along based on your goal:

pnpm --filter learn dev

and navigate to localhost:30006 on your browser

Quick gotos:

Frontend UI

Tests

  • Integration (localnet): pnpm dapp test:integration
  • Full testing guide: docs/15-testing.md

Docs (detailed)

The detailed docs live under docs/:

Repository layout

.
├── packages/
│   ├── dapp/
│   │   ├── contracts/                 # Move packages (oracle-market + mocks + examples)
│   │   │   ├── oracle-market/         # Main Move package (sui_oracle_market)
│   │   │   ├── pyth-mock/             # Local-only Pyth stub (dev/localnet)
│   │   │   ├── coin-mock/             # Local-only mock coins (dev/localnet)
│   │   │   └── item-examples/         # Example item types for listings/receipts
│   │   ├── src/
│   │   │   ├── scripts/               # CLI scripts (chain, owner, buyer)
│   │   │   └── utils/                 # Script-only helpers (e.g. CLI output formatting)
│   │   ├── deployments/               # Generated artifacts from scripts
│   │   ├── sui.config.ts              # Network + paths config for scripts
│   │   └── package.json               # Script entry points
│   ├── domain/
│   │   ├── core/                      # Browser-safe domain models + queries
│   │   └── node/                      # Node-only domain helpers (if needed)
│   ├── tooling/
│   │   ├── core/                      # Browser-safe utilities + types
│   │   └── node/                      # Node-only script helpers (fs/process/yargs/etc)
│   └── ui/
│       ├── src/app/                   # Next.js app router UI
│       ├── public/                    # Static assets
│       ├── dist/                      # Static export output (from `pnpm ui build`)
│       └── package.json               # UI scripts
├── pnpm-workspace.yaml                # Workspace definition
├── package.json                       # Root wrappers (`pnpm script`, `pnpm ui`)
├── tsconfig.json                      # TS project references
├── tsconfig.base.json                 # Shared TS config
├── tsconfig.node.json                 # Shared TS config for Node-only packages
└── eslint.config.mjs                  # Root lint config

What this means in practice:

  • packages/dapp owns Move packages, CLI scripts, and generated artifacts under packages/dapp/deployments.
  • packages/domain/* is the domain SDK split into browser-safe core and Node-only node.
  • packages/tooling/* is shared infra helpers split into browser-safe core and Node-only node.
  • packages/ui is a Next.js UI that uses the same package IDs and Shop objects created by scripts.

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages