data-book="docs" Marketplace (Native API example) | The Root Network
Skip to content

2.44 Marketplace (Native API example) ​
At a glance
What it isRegister a marketplace, list NFTs for sale or auction, buy and bid. Futureverse’s Native API example for The Root Network, with its README and source.
Where it sitsPart II — Building · Chapter 2.44
CoversExamples · Source files
Sourcegithub.com/futureversecom/trn-examples/tree/main/examples/substrate/use-marketplace

Register a marketplace, list NFTs for sale or auction, buy and bid. Reference: marketplace pallet.

Copied from Futureverse’s futureversecom/trn-examples, deleted with its GitHub organisation, at commit 44c9e16 of 2024-10-31. Apache-2.0: license. Before you run it, read Running the examples.

Offline destinations

Some places this page points to did not answer when last checked:

  • docs-beta.therootnetwork.com — does not resolve (checked 2026-10-18)
  • stackblitz.com/github/futureversecom — StackBlitz loads these projects from the deleted futureversecom organisation on GitHub (checked 2026-10-18)

Run in StackBlitz (repository deleted, checked 2026-10-18) · Pallet Documentation (offline, checked 2026-10-18)

IMPORTANT

Ensure the following ENV vars are available before running the examples

2.44.1 Examples ​

bash
# change your working directory to this example first
cd examples/substrate/use-marketplace

# export all required environments
export CALLER_PRIVATE_KEY=

# register a new marketplace
pnpm call:registerMarketplace

# list a bundle of NFTs as fixed price sell
pnpm call:sell

# buy a listing
pnpm call:buy

# list a bundle NFT as auction
pnpm call:auction

# submit a bid to an auction listing
pnpm call:bid

2.44.2 Source files ​

src/auction.ts2.44.2.1 ​

ts
import { filterExtrinsicEvents } from "@trne/utils/filterExtrinsicEvents";
import { formatEventData } from "@trne/utils/formatEventData";
import { XRP_ASSET_ID } from "@trne/utils/porcini-assets";
import { sendExtrinsic } from "@trne/utils/sendExtrinsic";
import { withChainApi } from "@trne/utils/withChainApi";
import assert from "node:assert";

interface OwnedTokens {
	0: number;
	1: number;
	2: number[];
}

/**
 * Use `marketplace.auctionNft` to list an NFT for auction sale on the marketplace (id = 1).
 *
 * Assumes caller has NFT of collection id 1124 and XRP to pay gas.
 */
withChainApi("porcini", async (api, caller, logger) => {
	const collectionId = 1124;
	const marketplaceId = 1;
	const paymentAsset = XRP_ASSET_ID;
	const reservePrice = 1_000_000; // 1 XRP
	const duration = 100; // the listing will expire in 100 blocks

	const ownedTokens = (await api.rpc.nft.ownedTokens(
		collectionId,
		caller.address,
		0,
		1
	)) as unknown as OwnedTokens;
	const serialNumbers = ownedTokens[2];
	assert(serialNumbers.length);

	logger.info(
		{
			parameters: {
				collectionId,
				serialNumbers,
				paymentAsset,
				reservePrice,
				duration,
				marketplaceId,
			},
		},
		`create a "marketplace.sellNft" extrinsic`
	);

	const extrinsic = api.tx.marketplace.auctionNft(
		collectionId,
		serialNumbers,
		paymentAsset,
		reservePrice,
		duration,
		marketplaceId
	);

	const { result, extrinsicId } = await sendExtrinsic(extrinsic, caller, { log: logger });
	const [openEvent] = filterExtrinsicEvents(result.events, ["Marketplace.AuctionOpen"]);

	logger.info(
		{
			result: {
				extrinsicId,
				blockNumber: result.blockNumber,
				openEvent: formatEventData(openEvent.event),
			},
		},
		"receive result"
	);
});

src/bid.ts2.44.2.2 ​

ts
import { filterExtrinsicEvents } from "@trne/utils/filterExtrinsicEvents";
import { formatEventData } from "@trne/utils/formatEventData";
import { sendExtrinsic } from "@trne/utils/sendExtrinsic";
import { withChainApi } from "@trne/utils/withChainApi";
import assert from "node:assert";

/**
 * Use `marketplace.bid` extrinsic to submit a bid on a listing.
 *
 * Assume caller has balance of required token to buy and XRP to pay for gas.
 */
withChainApi("porcini", async (api, caller, logger) => {
	const collectionId = 1124;
	// pick up the first available listing
	const collectionListing = (
		await api.query.marketplace.openCollectionListings.keys(collectionId)
	).shift();

	assert(collectionListing);
	const {
		args: [, listingId],
	} = collectionListing;

	const amount = 1_000_000; // 1 XRP

	logger.info(
		{
			parameters: {
				listingId: listingId.toString(),
				amount,
			},
		},
		`create a "nft.bid" extrinsic`
	);
	const extrinsic = api.tx.marketplace.bid(listingId, amount);

	logger.info(`dispatch extrinsic from caller="${caller.address}"`);
	const { result, extrinsicId } = await sendExtrinsic(extrinsic, caller, { log: logger });
	const [bidEvent] = filterExtrinsicEvents(result.events, ["Marketplace.Bid"]);

	logger.info(
		{
			result: {
				extrinsicId,
				blockNumber: result.blockNumber,
				bidEvent: formatEventData(bidEvent.event),
			},
		},
		"receive result"
	);
});

src/buy.ts2.44.2.3 ​

ts
import { filterExtrinsicEvents } from "@trne/utils/filterExtrinsicEvents";
import { formatEventData } from "@trne/utils/formatEventData";
import { sendExtrinsic } from "@trne/utils/sendExtrinsic";
import { withChainApi } from "@trne/utils/withChainApi";
import assert from "node:assert";

/**
 * Use `marketplace.buy` extrinsic to buy NFT from a listing.
 *
 * Assume caller has balance of required token to buy and XRP to pay for gas.
 */
withChainApi("porcini", async (api, caller, logger) => {
	const collectionId = 1124;
	// pick up the first available listing
	const collectionListing = (
		await api.query.marketplace.openCollectionListings.keys(collectionId)
	).shift();

	assert(collectionListing);
	const {
		args: [, listingId],
	} = collectionListing;

	logger.info(
		{
			parameters: {
				listingId: listingId.toString(),
			},
		},
		`create a "nft.buy" extrinsic`
	);
	const extrinsic = api.tx.marketplace.buy(listingId);

	logger.info(`dispatch extrinsic from caller="${caller.address}"`);
	const { result, extrinsicId } = await sendExtrinsic(extrinsic, caller, { log: logger });
	const [completeEvent] = filterExtrinsicEvents(result.events, [
		"Marketplace.FixedPriceSaleComplete",
	]);

	logger.info(
		{
			result: {
				extrinsicId,
				blockNumber: result.blockNumber,
				completeEvent: formatEventData(completeEvent.event),
			},
		},
		"receive result"
	);
});

src/registerMarketplace.ts2.44.2.4 ​

ts
import { filterExtrinsicEvents } from "@trne/utils/filterExtrinsicEvents";
import { formatEventData } from "@trne/utils/formatEventData";
import { sendExtrinsic } from "@trne/utils/sendExtrinsic";
import { withChainApi } from "@trne/utils/withChainApi";

/**
 * Use `marketplace.registerMarketplace` to register a new marketplace
 *
 * Assumes caller has XRP to pay gas.
 */
withChainApi("porcini", async (api, caller, logger) => {
	const marketplaceAccount = caller.address;
	const entitlement = 10_000; // One percent

	logger.info(
		{
			parameters: {
				marketplaceAccount,
				entitlement,
			},
		},
		`create a "marketplace.registerMarketplace" extrinsic`
	);
	const extrinsic = api.tx.marketplace.registerMarketplace(marketplaceAccount, entitlement);

	logger.info(`dispatch extrinsic from caller="${caller.address}"`);
	const { result, extrinsicId } = await sendExtrinsic(extrinsic, caller, { log: logger });
	const [registerEvent] = filterExtrinsicEvents(result.events, ["Marketplace.MarketplaceRegister"]);

	logger.info(
		{
			result: {
				extrinsicId,
				blockNumber: result.blockNumber,
				registerEvent: formatEventData(registerEvent.event),
			},
		},
		"receive result"
	);
});

src/sell.ts2.44.2.5 ​

ts
import { filterExtrinsicEvents } from "@trne/utils/filterExtrinsicEvents";
import { formatEventData } from "@trne/utils/formatEventData";
import { XRP_ASSET_ID } from "@trne/utils/porcini-assets";
import { sendExtrinsic } from "@trne/utils/sendExtrinsic";
import { withChainApi } from "@trne/utils/withChainApi";
import assert from "node:assert";

interface OwnedTokens {
	0: number;
	1: number;
	2: number[];
}

/**
 * Use `marketplace.sellNft` to list an NFT for fixed-price sale on the marketplace (id = 1).
 *
 * Assumes caller has NFT of collection id 1124 and XRP to pay gas.
 */
withChainApi("porcini", async (api, caller, logger) => {
	const collectionId = 1124;
	const marketplaceId = 1;
	const paymentAsset = XRP_ASSET_ID;
	const fixedPrice = 1_000_000; // 1 XRP
	const duration = 100; // the listing will expire in 100 blocks

	const ownedTokens = (await api.rpc.nft.ownedTokens(
		collectionId,
		caller.address,
		0,
		1
	)) as unknown as OwnedTokens;
	const serialNumbers = ownedTokens[2];
	assert(serialNumbers.length);

	logger.info(
		{
			parameters: {
				collectionId,
				serialNumbers,
				paymentAsset,
				fixedPrice,
				duration,
				marketplaceId,
			},
		},
		`create a "marketplace.sellNft" extrinsic`
	);
	const extrinsic = api.tx.marketplace.sellNft(
		collectionId,
		serialNumbers,
		null, // buyer
		paymentAsset,
		fixedPrice,
		duration,
		marketplaceId
	);

	logger.info(`dispatch extrinsic from caller="${caller.address}"`);
	const { result, extrinsicId } = await sendExtrinsic(extrinsic, caller, { log: logger });
	const [saleEvent] = filterExtrinsicEvents(result.events, ["Marketplace.FixedPriceSaleList"]);

	logger.info(
		{
			result: {
				extrinsicId,
				blockNumber: result.blockNumber,
				saleEvent: formatEventData(saleEvent.event),
			},
		},
		"receive result"
	);
});

package.json2.44.2.6 ​

json
{
  "scripts": {
    "call": "tsx --tsconfig ../../../tsconfig.json",
    "call:registerMarketplace": "pnpm call src/registerMarketplace.ts",
    "call:sell": "pnpm call src/sell.ts",
    "call:buy": "pnpm call src/buy.ts",
    "call:auction": "pnpm call src/auction.ts",
    "call:bid": "pnpm call src/bid.ts"
  }
}
Source: futureversecom/trn-examples, examples/substrate/use-marketplace (deleted) · commit 44c9e16, 2024-10-31 · Apache-2.0, license · part of Code examples

Associated docs

Where else you might go from here. Following one is optional — this chapter stands without them.

Back matter — read in order
See also — The whole of Back matter as one continuous page, reprinted from its chapters without change.
Code examples
See also — Futureverse’s code examples for The Root Network: scripts for the native API and the EVM, and two contract projects, each with its README and source.
Contents
See also — Every chapter in this book, each with the one line that tells you what you get by reading it.
Front matter — read in order
See also — The whole of Front matter as one continuous page, reprinted from its chapters without change.
Guides for the code examples
See also — How Futureverse’s TRN code examples get a test account: create one in MetaMask and fund it from the Porcini faucet.
Index · A
See also — 609 index terms that start with A, each linked to the pages that define or use it.
Index · F
See also — 319 index terms that start with F, each linked to the pages that define or use it.
Index · M
See also — 492 index terms that start with M, each linked to the pages that define or use it.

Curated independently and source-attributed. Not affiliated with Futureverse or TRN Labs. Sources

Curated independently and source-attributed. Not affiliated with Futureverse or TRN Labs.