Skip to main content

List your dapp on the Chromia Mainnet Vault

This guide provides step-by-step instructions for listing your decentralized application (dapp) on the Chromia Mainnet Vault. Following these steps will make your dapp discoverable to users and streamline the onboarding process.

Prerequisites

  • A deployed dapp on the Chromia Mainnet
  • Access to your dapp's codebase
  • Media files for your dapp (icons, screenshots, etc.)

Steps to the listing

To list your dapp, you need to implement the following query and supporting functions in your dapp's codebase:

  • Implement the required query and functions:

    • Integrate the find_dapp_details query into your dapp's codebase. This query retrieves and formats your dapp's details.

      query find_dapp_details(dapp_rowid: rowid, requested_content_types: list<dapps.dapp_content_type>? = null)
    • Implement the supporting functions:

      • map_dapp_details: Maps dapp details, including associated blockchains and media content.

        function map_dapp_details(dapp, requested_content_types: list<dapp_content_type>? = null) {
        val blockchains = find_and_map_dapp_blockchains(dapp);
        val dapp_media = if (not empty(requested_content_types)) find_and_map_dapp_media(
        dapp,
        requested_content_types
        ) else null;

        return (
        rowid = dapp.rowid,
        name = dapp.name,
        description = dapp.description,
        launch_url = dapp.launch_url,
        genre = dapp.genre,
        chain_list = blockchains,
        content = dapp_media
        ).to_gtv_pretty();
        }
      • find_and_map_dapp_blockchains: Retrieves and maps blockchains your dapp interacts with.

        function find_and_map_dapp_blockchains(dapp) =
        blockchain @* { dapp } (
        @omit @sort .rowid,
        name = .name,
        brid = .brid,
        role = .role
        );
      • find_and_map_dapp_media: Retrieves and maps media content associated with your dapp (e.g., screenshots, icons).

        function find_and_map_dapp_media(dapp, requested_content_types: list<dapp_content_type>) =
        dapp_media @* {
        dapp,
        .type in requested_content_types
        } (
        @omit @sort .rowid,
        name = .name,
        url = .url,
        type = .type
        );
  • Upload your media content:

    To display media content in your dapp listing, such as icons and screenshots, you need to upload these files to Filehub and integrate their URLs into the find_and_map_dapp_media function:

    • Here are the steps to upload to Filehub:

      1. Ensure you have a Vault account and transfer at least 1 CHR from your Chromia Economy Chain account to your Filehub account.
      2. Complete your Filehub registration through Vault.
      3. Connect your wallet and authorize Filehub to upload files.
    • To install the Filehub NPM Package:

      • The Filehub npm package is the recommended way to upload files to Filehub from the client side. It is available at Filehub NPM Package. Use the following command:

        npm install filehub
    • To instantiate the Filehub client:

      • Use the code below and provide your blockchain RID and directory node URL pool:

        const { Filehub, FsFile } = require("filehub");
        const filehub = new Filehub({
        blockchainRid: process.env.BLOCKCHAIN_RID,
        directoryNodeUrlPool: process.env.DIRECTORY_NODE_URL_POOL,
        });
    • To calculate file allocation Fees:

      • When uploading files, you can calculate the allocation fee for them. For each file size, you receive an object with price details, and the property total_file_price_in_asset_with_decimals will contain the total price in CHR for the files. Use the following code to calculate the allocation fee for files:

        const fees = await filehub.calculateFileAllocationFees(fileSizes);
        console.log("Total price in CHR:", fees.total_file_price_in_asset_with_decimals);
    • To store a file:

      • To store a file, you need to provide the user's Chromia session and the file to be stored. The Chromia session is created using the @chromia/ft4 package, and the file is created using the FsFile class from the Filehub package. You need to provide the file's buffer and content type.

        import { FsFile } from "filehub";

        // Create an FsFile object with the file data
        const fsFile = FsFile.fromData(buffer, { contentType: "image/jpeg" });

        // Store the file using the Filehub client and Chromia session
        await filehub.storeFile(chromiaSession, fsFile);
    • To monitor upload progress:

      • Filehub will emit multiple events so that you can keep track of the file's upload progress:

        filehub.on("onChunkStored", async (fileHash, chunkLocation, error) => {
        // Called whenever a chunk of the file is stored
        console.log(fileHash, chunkLocation, error);
        });

        filehub.on("onFileStored", async (hash, metadata, error) => {
        // Called when the full file is stored
        console.log(hash, metadata, error);
        });

        filehub.on("onProgress", async (currentProgress, status) => {
        // Called whenever the upload progress changes
        console.log(currentProgress, status);
        });
    • To get all files:

      • Use the following code to get a list of all the files in your Filehub account:

        const files = await filehub.getAllFiles(accountId);
        console.log("Files:", files);
    • To integrate Media URLs:

      • Use the URLs provided by Filehub in the find_and_map_dapp_media function to include the media in your dapp's metadata.
    • For automatic listing:

      • Once you've implemented the query and functions, your dapp will be automatically listed in the Chromia Mainnet Vault based on the information it provides.
    • For verification for a checkmark (optional):

      • Contact the Chromia team admin for final verification. The team will review your dapp to ensure it meets the quality standards.

Example usage

Here’s an example implementation of the find_dapp_details query:

query find_dapp_details(dapp_rowid: rowid, requested_content_types: list<dapp_content_type>? = null) {
val dapp = get_dapp_by_rowid(dapp_rowid);
return map_dapp_details(dapp, requested_content_types);
}

function get_dapp_by_rowid(dapp_rowid: rowid) =
dapp @ { .rowid = dapp_rowid } (
rowid = .rowid,
name = .name,
description = .description,
launch_url = .launch_url,
genre = .genre
);

The data in the example is stored in the following entities.

entity dapp {
key name;
mutable description: text = "";
mutable launch_url: text = "";
mutable genre: text = "";
}

entity dapp_media {
key dapp, name;
mutable url: text = "";
type: dapp_content_type;
}

entity blockchain {
key dapp, brid: byte_array;
index brid;
index mutable name: text;
mutable role: text;
}

Example of storing the data

To store the required data, use the setUpMocks.ts script with the Filehub media links. For more details, refer to the following GitLab repository: GitLab: dapp-aggregator setupMocks.ts.