Skip to content

Web3 Passport For Developer ​

Passport Space ​

As a MatchID developer, you can:

1️⃣ Create Passport Spaces

Access our developer panel to set up your project passport space. This dedicated space will be automatically integrated as a subpage within all MatchID user passports, enabling exposure to our global user base.

2️⃣ Issue SBT Credentials

Within your created passport space:

  • Design and deploy SBTs (Soulbound Tokens) through our developer dashboard.
  • All issued SBTs will be permanently displayed in the associated passport subpage.

3️⃣ User Visibility

  • SBT holders automatically see your SBT credentials in their MatchID passport interface.
  • Real-time display of both SBTs and their originating passport space.

How to create a passport space? ​

1️⃣ Web Developer Panel Log in to the Developer Dashboard, And navigate to Web3 Passport and submit the following information:

  • Space logo
  • Name & Description

Then connect your EVM wallet and send a createOrgSpace on-chain transaction, A Passport Space smart contract will be deployed on the Matchain.

Access Control Rules Of Passport Space:

  • Transaction createOrgSpace sender will be the default owner of the space.
  • Supports multiple team members (non-owner roles)
  • Only the owner of space can add/remove team members.

SBT ​

Once a Passport Space is created, You can issue SBTs belonging to your passport space.

1️⃣ SBT Issuance Rights:

  • Both the Passport Space Owner and team members are granted full authority to issue SBTs.
  • The Passport Space's contract address is the owner of all issued SBTs.
  • By default, the Passport Space's smart contract holds the permission to mint SBTs.

2️⃣ Custom SBT Mint Permissions:

The owner and team members can authorize any address (including smart contract) to mint SBTs via the Developer Dashboard. For example, As a developer:

  • You can have your own mint logic or call SBT.mint(address to) in your smart contract, And authorize the mint permission to your smart contract.
  • You can authorize the mint permission to your EOA wallet address, And then you can send the SBT.mint(address to) transactions by the wallet.

How to issue SBTs? ​

1️⃣ Web Developer Panel

Log in to the Developer Dashboard, And navigate to Web3 Passport, And connect your EVM wallet.

If you have ever created a passport space or joined a passport space as the team member, You will see your space details.

If you don't created a passport space or joined a passport space as the team member, You can create a new passport space by clicking the Set up space button.

Then you can click the Issue SBT button, And submit the following information:

  • SBT Name

  • SBT Symbol

  • SBT Image or Metadata URL

    • If you use Metadata URL directly, please make sure the URL is accessible by the public and the content of Metadata should include the following information:
    json
    {
      "name": "SBT Name",
      "description": "SBT Description",
      "image": "SBT Image URL",
      "external_url": "SBT External URL"
    }

Then click the Issue button to send a publishSBT on-chain transaction, A SBT smart contract will be deployed on the Matchain.

Smart contracts ​

1️⃣ SBT Contract

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/extensions/AccessControlEnumerable.sol";

contract SBT is AccessControlEnumerable, ERC721Enumerable {
    /// @notice minter role
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    /// @notice base URI of SBT
    string public baseURI;

    constructor(
        string memory name_,
        string memory symbol_,
        string memory baseURI_,
        address owner_
    ) ERC721(name_, symbol_) {
        baseURI = baseURI_;
        _grantRole(DEFAULT_ADMIN_ROLE, owner_);
        _grantRole(MINTER_ROLE, owner_);
    }

    /**
     * override `_update` function to make SBT NFT Non-Transferable
     * @dev See {ERC721-_update}.
     */
    function _update(
        address to,
        uint256 tokenId,
        address auth
    ) internal virtual override(ERC721Enumerable) returns (address) {
        address previousOwner = super._update(to, tokenId, auth);
        require(previousOwner == address(0), "Non-Transferable");
        return previousOwner;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(
        bytes4 interfaceId
    ) public view virtual override(AccessControlEnumerable, ERC721Enumerable) returns (bool) {
        return
            super.supportsInterface(interfaceId) ||
            AccessControl.supportsInterface(interfaceId) ||
            ERC721Enumerable.supportsInterface(interfaceId);
    }

    /**
     * @notice update the baseURI of SBT
     */
    function setBaseURI(string memory baseURI_) external onlyRole(DEFAULT_ADMIN_ROLE) {
        baseURI = baseURI_;
    }

    /**
     * @notice mint SBT
     */
    function mint(address to) external onlyRole(MINTER_ROLE) {
        require(balanceOf(to) == 0, "Mint multiple SBT");
        _mint(to, totalSupply());
    }
}