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());
    }
}