Install and enable
What must exist before the NFT Marketplace addon works — the Ecosystem prerequisite, licence activation, master wallets and gas, the first marketplace contract, categories, and the settings that decide whether anyone can trade.
Activating the licence is the quick part. The addon is not usable until a marketplace contract exists on at least one chain, and that deployment spends real gas from an Ecosystem master wallet. Read this page end to end before you start, because two of the steps cost money and one of them cannot be undone cleanly.
Prerequisites
- A working Bicrypto install — see Core setup
- The Ecosystem addon licensed, installed and enabled
- At least one Ecosystem chain configured with a reachable RPC endpoint
- An enabled Ecosystem master wallet for that chain
- Native currency in that master wallet to pay deployment gas
- The cron process running — offers and auctions are settled by scheduled jobs
- The NFT Marketplace purchase code, from your MashDiv dashboard
Why Ecosystem is mandatory
The NFT addon has no blockchain layer of its own. It imports three functions from Ecosystem at runtime:
| Function | Used for |
|---|---|
getProvider(chain) |
Every RPC call — deployments, transfers, receipts, balances |
getSmartContract("nft", name) |
Loading the ABI and bytecode for NFTMarketplace, NFTAuction, ERC721NFT and ERC1155NFT |
getAdjustedGasPrice(chain) |
Gas pricing on deployments |
They are loaded through guarded require calls, so a missing Ecosystem does
not crash the backend — it degrades silently until a deployment is attempted,
at which point the marketplace service throws "Ecosystem extension is required
for NFT marketplace deployment".
Deployments also read ecosystemMasterWallet directly, decrypt the stored
private key, and sign with it. The master wallet is the deployer and, unless
you override it, the marketplace fee recipient.
The compiled contract artifacts live in
backend/ecosystem/smart-contracts/nft/ — NFTMarketplace.json,
NFTAuction.json, ERC721NFT.json and ERC1155NFT.json. They ship with the
addon; you do not compile anything.
Ecosystem uses ScyllaDB for its order books and market data. The NFT addon never touches it — it uses only Ecosystem's provider, master wallet and smart-contract loader, all of which are MySQL and RPC. If you are installing Ecosystem purely to run NFT, you do not need a Scylla cluster.
Install the addon
-
Open the Extension Manager. Go to Admin → System → Extension Manager (
/admin/system/extension) — the page heading is Add-ons & Integrations. On the Extensions tab (or by searching for NFT) find the NFT Marketplace card — product ID60962133— and click it. Until its licence is activated the card's chip reads Activate and its switch is disabled, with the tooltip Activate license first.- The NFT Marketplace card — click it to open the product page
- Its switch stays disabled until the licence is activated
-
Activate the licence. On the product page press Activate License. Paste the purchase code from your MashDiv dashboard, optionally a Notification Email for update notifications, and press Activate License. The screen confirms License Activated! and returns you to the product page a couple of seconds later. Activation is verified against the licence server, so the box needs outbound HTTPS — if it has none, the License File tab on the same screen takes the licence certificate downloaded from your MashDiv dashboard, placed as
license.txtin the/licfolder at the project root.- Paste the purchase code here
- Activate License — then wait for the redirect back to the product page
- License File — the offline route for a box with no outbound HTTPS
-
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 updatorThat is the finalise chain — stop, dependencies, schema, seed data, frontend build, start. If the panel still says Up to date after the check, there is nothing to download — the release already on the server is current — and you go straight to the next step.
- Check for Updates, then Install v… when it is offered
- Releases — the notes for the version you are about to install
- The Enabled switch — step 4, not yet
-
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 gives you Admin → NFT, the user-facing
/nftroutes and the threenftcron jobs — after one more restart, which is the next step. -
Restart the backend. Route registration and menu loading happen at boot, and the switch was still off when
pnpm updatorran its restart. Until you restart once more,/nftand/admin/nftare 404. -
Confirm the schema. The NFT tables ship in
initial.sql, so a core install already has them. Two later tables are created by the boot sync instead:nft_metadata_backupandgas_history. If you run withDB_SYNC=nonethose two will be missing and the backup feature will fail.SHOW TABLES LIKE 'nft\_%';initial.sqlcarries 19 of them.nft_metadata_backupbrings that to 20 once the sync has run, andgas_historyis the twenty-first table the addon owns. -
Grant permissions. No seeder gives any role NFT access. Until you tick boxes on the Roles screen,
/admin/nftanswers with a no-permission page even for an account on the Admin role. See Permissions for the full key list.
Deploy your first marketplace contract
Nothing works until this exists. /api/nft/chains is built from the
nft_marketplace table, the collection-create endpoint refuses any chain with
no ACTIVE row, and every purchase path looks for a marketplace address before
it falls back to a direct transfer.
Go to Admin → NFT → Trading → Marketplace (/admin/nft/marketplace) and
use the deploy panel.
The contract is deployed with a 4,000,000 gas limit against live gas prices. Budget for it, and deploy to a test chain first if you have one configured. There is no dry run.
The deploy call takes five inputs:
| Field | Default | Notes |
|---|---|---|
chain |
ETH |
Must have an active Ecosystem master wallet |
feeRecipient |
the master wallet address | Where on-chain fees accumulate and where withdrawals default to |
feePercentage |
2.5 |
Rejected outside 0–10. Written into the contract in basis points |
listingFee |
0 |
A flat fee in native token, charged by the contract on listing |
maxRoyaltyPercentage |
10 |
The contract's own ceiling on creator royalties |
A second deployment on the same chain returns 409 unless you pass
force: true. Forcing marks the previous row DEPRECATED and inserts the new
one as ACTIVE.
feePercentage here is baked into the deployed contract. The Marketplace
Fee slider on the settings screen writes nftMarketplaceFeePercentage, which
is what the custodial offer path charges. Deploying at 2.5% and then setting
the slider to 5% gives you a marketplace that charges 2.5% on fixed-price sales
and 5% on offers. Set them to the same number, and change them together.
Network is always recorded as mainnet
The deploy route writes network: "mainnet" on the nft_marketplace row
regardless of what the chain's RPC actually points at. That string is then the
join key: /api/nft/chains returns it, the collection form sends it back, and
collection creation matches on chain and network. It is internally
consistent, so a testnet RPC works fine — but do not read "mainnet" in that
column as evidence of anything.
Configure the marketplace
- Five tabs - work through every one of them
- Off makes POST /api/nft/listing return 403 for FIXED_PRICE
Once a contract exists, work through the four settings tabs at
Admin → NFT → System → Settings (/admin/nft/settings). Every key, its
default and its real behaviour are listed in
Settings; the ones that block a launch are:
Several of these keys have no seeded row. The onboarding checklist treats a missing key as "not configured", and more importantly the code path that reads a boolean setting falls back to its default only when the key is absent — so until you have written them, what your settings screen shows and what the backend enforces can differ. Open each tab and save.
Create categories
- The checklist counts these rows
Collection creation requires a valid categoryId, and the category must
already exist. With zero categories nobody can create anything.
Go to Admin → NFT → Content → Categories (/admin/nft/category) and add at
least two. The onboarding checklist looks for two or more.
Check the cron jobs
Three jobs run in the nft category. Confirm they appear and are running on
the admin cron screen:
| Job | Every | What breaks without it |
|---|---|---|
expireOffers |
5 minutes | Expired offers stay ACTIVE and buyers' escrow stays held indefinitely |
settleAuctions |
10 minutes | Ended auctions never pay out and never transfer the NFT |
processNFTBackups |
15 minutes | Scheduled blockchain-state backups never run |
settleAuctions also runs the stale-offer sweep that unwinds accepted offers
whose on-chain transfer never happened. If the cron process is down, buyers'
funds sit locked with no NFT and no notification.
Verify the install
Work the onboarding checklist at /admin/nft/onboarding. It is not linked from
the navigation — reach it from the button on the Marketplace screen or type the
URL. It reads real state and reports four phases:
Infrastructure
At least one ACTIVE row in nft_marketplace. This satisfies both the "deploy
primary marketplace" and "verify blockchain health" tasks — they are driven by
the same check, so passing one passes both.
Configuration
nftEnableFixedPriceSales, nftEnableAuctions and nftEnableOffers must all
be present (not merely defaulted), nftRequireMetadataValidation must be
present, and nftRequireKycForCreators must be present.
Content
Two or more categories, at least one collection with status = ACTIVE, and at
least one ACTIVE collection that actually has tokens in it.
Users and creators
At least one nft_creator row with isVerified = true. Creator profiles are
created automatically the first time a user makes a collection; verification is
a manual flip on the Creators screen.
Then prove the whole loop with a real account before you announce anything:
-
Create a collection as a normal user at
/nft/collection/create. It is written PENDING. -
Approve it at
/admin/nft/collection— the status toggle sets ACTIVE. -
Deploy the collection contract from the creator's own screen. This spends gas from the master wallet again, one deployment per collection.
-
Mint one token at
/nft/create. The creator's browser wallet signs; the backend verifies the receipt before it writes the row. -
List it and buy it from a second account. Check that a
nft_salerow appears and the token's owner changed.
If step 5 fails with "Connect a wallet address in your profile", read When money or an NFT is stuck. It is the single most common blocker on a fresh install, and it is fixable only from the customer's own profile — not from the admin panel.