Installation and setup

The ordered path from a licensed install to your first swap. Every step depends on the one before it, and step 11 is the one that catches the failure that costs money silently.

14 min readUpdated 1 September 2026

The order below is the deliverable. Each step depends on the one before it, and doing them out of order produces a console that looks configured and a swap surface that refuses everything.

Every chain you enable needs a fee recipient before you raise the platform fee. A chain with a fee and no recipient refuses to quote — it does not quote at zero. Doing steps 9 and 6 in the wrong order takes your swap surface down.

Before you begin

You need:

  • A working Bicrypto install on v6.6 or later.
  • The purchase code for Web3 Wallet & On-Chain Trading, from your MashDiv dashboard.
  • A WalletConnect project id — free, from cloud.reown.com. Without it no wallet can connect.
  • At least one aggregator API key. See Providers for which ones permit commercial use on their free tier; several do not, and you will not find out until you are invoiced.
  • An RPC endpoint per chain you intend to enable.
  • An address you control to receive fees, per chain.
  • A shell on the server, for the one command that applies the install.

The path

  1. Open the Extension Manager and activate the licence. Go to Admin → System → Extension Manager. On the Extensions tab (or by searching for Web3) find the Web3 Wallet & On-Chain Trading card — product ID 62100000 — and click it. Until its licence is activated the card reads Activate and its switch is disabled.

    1. The Web3 Wallet & On-Chain Trading card — click it to open the product page
    2. Its switch stays disabled until the licence is activated

    On the product page press Activate License. Paste the purchase code, optionally an email address for update notifications, and press Activate License. The screen confirms License Activated! and sends you back to the product page a couple of seconds later. If the server has no outbound access, the License File tab on the same screen takes the licence certificate downloaded from your MashDiv dashboard instead.

    1. Paste the purchase code here
    2. Activate License — then wait for the redirect back to the product page
    3. The offline route, for a server with no outbound HTTPS
  2. Install the release. Back on the product page, now licensed, the Overview tab has a release panel. If it offers Install v…, press it; if it says Up to date on a product you have only just licensed, press Check for Updates once, then install whatever it offers. The Releases tab holds the notes for the version you are being offered — read them first.

    Install downloads the release, verifies it and extracts it over the project root. It runs no migrations, builds nothing and restarts nothing, so finish it from a shell on the server:

    pnpm updator

    That is the finalise chain — stop, dependencies, schema, seed data, frontend build, start — and it is what makes the addon's tables, routes and screens exist. If the panel still says Up to date after the check there is nothing to download; go straight to the next step.

    1. Check for Updates, then Install v… when it is offered
    2. Releases — the notes for the version you are about to install
    3. The Enabled switch — step 3, not yet
  3. Switch it on. Turn the Enabled switch on — in the product page heading, or on the card in the Extension Manager, which is usable now that the licence is verified. This is what makes Web3 Trading appear under Admin → Extensions and Swap appear in the user navigation; until it is on, neither exists and the addon's API refuses every call. It takes effect without a restart.

  4. Fill in .env, then rebuild.

    # Wallet connections. NEXT_PUBLIC_ — it ships in the browser bundle.
    NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=your-project-id
    
    # At least one aggregator. These two 401 without a key; the rest are
    # rate-limit keys for vendors that also answer unauthenticated.
    APP_DEX_ZEROEX_API_KEY=
    APP_DEX_ONEINCH_API_KEY=
    APP_DEX_LIFI_API_KEY=
    APP_DEX_JUPITER_API_KEY=
    APP_DEX_TRON_API_KEY=
    APP_DEX_TON_API_KEY=
    
    # Server-side RPC, one per chain you enable. The suffix is the chain's
    # slug, uppercased. These may carry a provider key in the path.
    APP_DEX_RPC_ETHEREUM=
    APP_DEX_RPC_BASE=
    APP_DEX_RPC_ARBITRUM=
    APP_DEX_RPC_OPTIMISM=
    APP_DEX_RPC_POLYGON=
    APP_DEX_RPC_BSC=

    APP_ZEROEX_API_KEY, APP_ONEINCH_API_KEY, APP_ODOS_API_KEY and the six APP_<CHAIN>_RPC_URL names appear nowhere in the codebase. They set nothing, and no console reports them missing because nothing looks for them. If you copied that block, replace it with the one above — the symptom is six chains that will not quote and two aggregators that 401, with a .env that looks complete.

    Every name Swap actually reads is in Environment variables. Where to get each account is in Getting your vendor accounts.

    NEXT_PUBLIC_* values are inlined into the frontend bundle at build time. Restarting the backend changes nothing. Run your frontend build again, or wallet connection will keep failing with the old value. With no value at all the terminal does not render: from Core 6.7.5 it shows a "Wallet connection is not set up yet" card (an admin sees the variable to set on it), and on Core 6.6.2 – 6.7.4 the page was the platform's whole-page 500 "Something went wrong!" card with nothing in the backend log — see Troubleshooting. The variable is in .env.example from Core 6.7.5, empty; older installs have to add the line.

  5. ProvidersAdmin → Swap → Providers. Activate at least one, press Test credentials, and read the verdict. It is four-valued: configured, not configured, configured-but-unverified, and unknown. Only the first means a quote will succeed.

    1. Activate at least one adapter
    2. Credential — three states, not two
  6. ChainsAdmin → Swap → Chains. Per chain, in this order:

    • set the fee recipient (an address you control — see Fees and revenue for the EOA-vs-Safe decision);
    • set the public RPC if you want browser-side reads;
    • then switch the chain on.

    The Fee status column tells you whether the chain will earn, refuse, or run at zero fee. Do not move on while any enabled chain reads Refusing.

    1. Fee recipient — set this first, per chain
    2. Only then switch the chain on
    3. Do not move on while any enabled chain reads Refusing

    Alchemy and Infura both put the API key in the URL path. The public RPC field ships to every visitor's browser. The server-side override is write-only from the console for exactly this reason — it is never read back into a response.

  7. TokensAdmin → Swap → Tokens. Import a token list, confirm the token policy is CURATED, and allowlist the majors. Imported tokens land PENDING and disabled: importing never allowlists, and nothing that is PENDING is quotable.

    1. Axis 2 — PENDING, ALLOWLISTED or DENYLISTED
    2. Axis 1 — the operator switch
    3. Axis 3 — the screener; risk flags show on hover
  8. PairsAdmin → Swap → Pairs. Create the featured pairs users see first.

  9. SettingsAdmin → Swap → Settings. Set dexFeeBps, the slippage ceilings and the geographic block list. Confirm the risk disclosure is on.

    The fee defaults to 0 so a fresh install quotes. Raise it only after step 6 is complete on every enabled chain.

    1. The seven tabs
  10. Turn it on — set dexEnabled to true. This is a Super-Admin-only setting, changed in system settings rather than here, because it is the switch that exposes an irreversible on-chain action to your users.

  11. Do one 1-USDC swap yourself, end to end, on the cheapest chain.

    Confirm it appears in Swap history with a confirmed hash, and that the fee appears in the fee ledger. If the swap succeeded and the fee did not appear, stop and go back to step 6. That is the failure that costs money silently — the trades settle, the users are happy, and you earn nothing on any of them, permanently, because the fee is baked into calldata they have already signed.

Turning it off again

Four independent switches, ordered by how much they take down. All of them are instant and none needs a deploy.

Switch Effect
dexQuoteOnly Quotes still render; nothing can be signed. This is the one you want at 3 a.m. — the page does not vanish, users see prices, nobody can execute.
dexEnabledChains Drops one chain. A misbehaving RPC or aggregator on one network does not take the product down.
Chain / provider status Per-integration and per-chain.
dexEnabled The whole surface, including the websocket streams.

The fifth is the Enabled switch in the Extension Manager, which removes the addon's screens and navigation entirely. It leaves the licence in place, so switching it back on needs no reactivation.

Updates extract over the existing install and never delete, and every page.tsx under the frontend app directory is a route — so a leftover page from a removed version keeps building and keeps failing. A code rollback needs the stale-file clean as well as the revert. Database migrations here are forward-only by design: none of them drops a table holding on-chain records.