Skip to content

Local Test Environment

A full local Internet Computer world for the OhShii Launcher and Locker, built on PocketIC — the official IC testing engine. It boots the real ICP ledger, the Cycles Minting Canister, NNS governance, Internet Identity, the real ICPSwap V3 stack, and every launcher + locker canister at the exact mainnet canister ids, all inside a simulation on your machine.

Anyone in the DAO can reproduce this environment from a clone of the repositories. Nothing here touches mainnet: the world runs entirely on 127.0.0.1, tokens are simulated, and identical canister ids do not mean identical canisters — mainnet and the test world are disjoint universes.

RequirementNotes
macOS or Linuxverified on macOS (Apple Silicon); other platforms download the matching PocketIC binary
git, curlfor the pinned-source bootstrap downloads
Rust toolchain (cargo)with the wasm target: rustup target add wasm32-unknown-unknown — the harness compiles the canisters from source
Node.js 20+ and npmfor the two frontends
dfx on PATHused ONLY by the one-time ICPSwap build (0.24.3 recommended); the environment itself never starts a dfx replica
Both repositories cloned as siblingsdev-ohshii-launcher and dev-ohshii-locker in the same parent folder. Without the locker repo the world still boots, but every Locker flow (locks, vesting via Locker, LP locks) is absent

One-time setup after cloning:

Terminal window
cd dev-ohshii-launcher
npm install
cd ../dev-ohshii-locker
npm install
Terminal window
cd dev-ohshii-launcher
./test-env/start.sh

The first run bootstraps automatically (~a few minutes): it downloads the pinned PocketIC server, builds the ICPSwap V3 canisters from a pinned source commit, compiles the launcher + locker canisters, boots the world, and starts both frontends. Later runs resume in seconds.

When the banner appears, the environment is live:

DappURL
Launcherhttp://localhost:5173/
Lockerhttp://localhost:5174/
Internet Identityhttp://rdmx6-jaaaa-aaaaa-aaadq-cai.localhost:8080/
IC HTTP gateway (API)http://127.0.0.1:8080
ICPSwap UI (optional)http://localhost:5175/ — run ./test-env/icpswap-ui.sh in another terminal

First login: create a NEW Internet Identity. The test world runs its own II instance — anchors and passkeys from mainnet do not exist here. On the login page choose Create Internet Identity and register a fresh one; trying to reuse a mainnet anchor is the most common first-run error.

Terminal window
./test-env/stop.sh

This performs a clean shutdown and saves the world state to test-env/state/ — balances, campaigns, pools, and governance survive. The next ./test-env/start.sh resumes the same world. To start completely fresh, delete test-env/state/ while the environment is stopped.

Connect a wallet in the Launcher, open the wallet page (/wallet) and use the LOCAL TEST TOOLS card:

  • Claim 1000 ICP + 1,000,000 OHSHII — one click, no terminal. The anonymous principal is the token whale of the test world and transfers the tokens to your connected wallet.

Alternatives from the terminal:

Terminal window
./test-env/faucet.sh <principal>
./test-env/faucet.sh <principal> icp 5000000000
./test-env/faucet.sh <principal> ohshii 100000000000

(The faucet.sh path requires icp-cli; the amounts are in e8s.)

On the same LOCAL TEST TOOLS card, click Make this wallet admin: the connected principal is promoted to admin on every launcher + locker canister of the test world, unlocking all admin views and controls after a reload.

Next to the admin button, Make this wallet guardian sets the connected principal as the ONS guardian of the test world. It goes through the same writer and cross-canister fanout the real admin/governance guardian change uses, so SONS canisters and the launcher/locker guardian caches all see the new guardian — guardian-gated flows (veto, Guardian Panel, rebuilds) behave exactly as on mainnet after a reload.

This works exclusively in the local test environment. The backing canister methods are compiled in only by the test harness build; the production WASMs deployed on mainnet export none of these methods, and the buttons themselves render only when the frontend is not on mainnet.

Mark a principal as verified — test world only

Section titled “Mark a principal as verified — test world only”

Real proof-of-personhood (World ID, DecideID) cannot run against a local world. The LOCAL TEST TOOLS card provides Verify via World ID and Verify via DecideID buttons that mark the connected principal as verified using the same internal writers the real verification flows use — so verification-gated features (LGE creation, verified purchase tiers, voting gates) behave exactly as they would after a real verification.

Like the admin promotion, these buttons and their backing methods exist only in the test build, never on mainnet.

ICP→cycles conversion rate in the test world

Section titled “ICP→cycles conversion rate in the test world”

The Cycles Minting Canister in the world is the real CMC WASM with its default simulated rate: 35 200 XDR-permyriad per ICP → 3.52T cycles per ICP. All creation-cost quotes (LGE, token, index canister) are computed from this rate. Verify it live:

Terminal window
icp canister call rkp4c-7iaaa-aaaaa-aaaca-cai get_icp_xdr_conversion_rate '()' -n testenv

Talking to the world from the CLI (optional)

Section titled “Talking to the world from the CLI (optional)”

With icp-cli configured (the repo ships the testenv network mapping):

Terminal window
icp canister status ohshii_launcher_backend -e testenv
icp canister call -n testenv <canister-id> <method> '(...)'

To pick up a code change inside the live world without rebuilding the whole environment (or losing a persisted session), upgrade the canister in place:

Terminal window
./test-env/dev-upgrade.sh [launcher|locker|both|<package>] # world already up
./test-env/start.sh --rebuild # resume, then rebuild the fleet

dev-upgrade.sh rebuilds with the local dev-admin feature and installs each canister with --mode upgrade, preserving stable state (heap is reset).

Do not use icp deploy <name> -e testenv to iterate on a test canister: it rebuilds without the dev-admin feature (that build also targets a real mainnet deployment, where the local-only test methods must never exist), which strips the in-app “Local Test Tools” from the canister and makes them fail with a method-not-found error.

SymptomFix
Port 8080 is already in use on startrun ./test-env/stop.sh first (also stops any leftover world), then start again
Login fails / identity errorscreate a NEW Internet Identity in the test world instead of reusing a mainnet anchor
Locker pages empty / locker flows failclone dev-ohshii-locker as a sibling of the launcher repo and restart
Want a clean slatestop, delete test-env/state/, start again
World is up but a frontend is notcheck the logs in test-env/.run/logs/

For the full technical reference (deterministic Rust integration tests, sessions, icp-cli coexistence, the security FAQ, caveats), see test-env/README.md in the repository.