This is the experimental NeonSoup developer tool dapp. It is used to test the P2P DeFi Kernel order book, GameChanger Wallet GCScript intents, asset metadata, wallet return handling, and protocol UX. It is not the production NeonSoup DEX frontend.
pnpm install
pnpm build
pnpm serve
pnpm exec tsc -p ./src/devtool/tsconfig.json
The build writes the Vite app to dist/ and keeps built protocol intents under
dist/intents/.
Copy the repo root .env.example to .env for local development.
Supported variables:
VITE_NEONSOUP_PREPROD_BLOCKFROST_URL=
VITE_NEONSOUP_PREPROD_BLOCKFROST_KEY=
VITE_NEONSOUP_MAINNET_BLOCKFROST_URL=
VITE_NEONSOUP_MAINNET_BLOCKFROST_KEY=
VITE_NEONSOUP_PREPROD_GRAPHQL_MK2_URL=
VITE_NEONSOUP_MAINNET_GRAPHQL_MK2_URL=
VITE_NEONSOUP_ENABLE_WALLET_URL_PATTERN_OVERRIDE=
VITE_NEONSOUP_GC_WALLET_URL_PATTERN=
VITE_NEONSOUP_BUILD_TAG=
NEONSOUP_GOOGLE_ANALYTICS_ID=
The Options view can still override provider URL/API key at runtime in browser localStorage. Source defaults should stay secret-free.
Set VITE_NEONSOUP_ENABLE_WALLET_URL_PATTERN_OVERRIDE=true only in trusted
local/dev builds to expose the GameChanger wallet URL pattern override. Set
VITE_NEONSOUP_GC_WALLET_URL_PATTERN to provide the initial option value. An
empty value lets the GC library use its official wallet URL. See the root
.env.example for the local wallet example.
Google Analytics is omitted from generated HTML unless
NEONSOUP_GOOGLE_ANALYTICS_ID is set at build or dev-server startup.
The persisted app-state version uses SemVer build metadata:
package.json version + VITE_NEONSOUP_BUILD_TAG (for example
0.0.1+20260604010551). When that string
changes, the app shows an update banner and stops persisting old state until the
user replaces incompatible local state with current defaults.
src/config/: app, network, and trusted asset defaultssrc/state/: serializable reducer/context app statesrc/services/: wallet, composable intent execution, storage, and network providerssrc/domain/: Cardano, asset, text, and quantity helperssrc/components/: Bootstrap 5 UI components
The app is intentionally pair-driven and context-aware: actions from tables should navigate to Trade and prefill the selected pair/action. Keep forms warning-based rather than hard-blocking invalid values; this is a protocol debugging tool.
Trade: pair selector, Open/Fill/Close forms, direct one-item composition, and pair offers.Orders: open offer table with Fill/Close actions.Activity: protocol UTxO activity and wallet-return transactions, with current-network Cardanoscan links.User: portfolio, user's open offers, and protocol transaction history.Options: network/provider settings, UI flags, and custom asset definitions.Developer: captured wallet return data and app state.
- The Asset Pair selector is the first step for protocol work and should remain prominent.
- Use Bootstrap alert tones correctly:
dangerfor errors,warningfor risky invalid-but-allowed input,successfor completed actions, andinfofor neutral status. - Inputs should warn rather than block when values exceed balances/offers.
- UTxO copy buttons must copy
<txHash>#<index>. - Asset metadata priority is: user overrides, app defaults, fetched metadata, then safe fallback identifiers.
- Fetched token metadata is untrusted. Keep strings truncated and only render safe icon formats.
- Configured assets and user overrides are keyed by canonical
policyId.assetNameHexstrings. ADA isada.ada; native assets with an empty asset name usepolicyId.. Do not use friendly aliases as dataset keys. - Use
assetIdfor provider/GC asset identifiers such aslovelaceorpolicyId + assetNameHex. - Do not add one-off migrations for old localStorage fields. Change the app version/build tag and rely on the centralized update banner for incompatible state shapes.
- Every Open, Fill, and Close run uses the same Cart-item composition pipeline. Direct actions are transient one-item compositions; Cart runs execute persisted selected items in bundle or parallel mode.
- Connect Wallet remains outside protocol composition and launches explicit GCScript through the same generic wallet-code transport.
- Opening or closing the wallet does not change Cart lifecycle state. A compact
returned
neonsoupExecutionreceipt moves matching items to tentative pending or failed status from wallet submission extras; provider/API chain data remains authoritative for final confirmation, failure, and classification. Pending transaction hashes are checked in bounded provider batches and atomically reconcile Cart and transaction-table status. - Generated protocol GCScripts keep signed transaction CBOR internal to wallet sign/submit steps. Return receipts are composed with GCScript macro/ISL from explicit args and wallet-runtime build results.
- Wallet-side free-fail submission handling returns rejected transaction details without blocking script completion, which removes the old zero-quantity full-fill devex blocker for fully consumed orders.
- Cardano GraphQL MKII and Blockfrost implement the same devtool provider contract. MKII uses bounded nested GraphQL queries to reduce request fan-out; it is the default provider. Blockfrost remains selectable for parity and fallback testing.