Steps for Basic Integration

Step 1. Import and inheritance

Step 1.1

Add the MicapassBasicClient.sol or MicapassBasicClientInitializable.sol smart contracts to your codebase

  • MicapassBasicClient.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import {IMicapassBaseVerifier} from "../interfaces/IMicapassBaseVerifier.sol";

contract MicapassBasicClient {
    IMicapassBaseVerifier internal _micapass;

    // Declare claim topics for function access control
    uint256 internal constant CLAIM_TOPIC_KYC = 1000001;
    uint256 internal constant CLAIM_TOPIC_WALLET_SCREENING = 1000002;
    uint256 internal constant CLAIM_TOPIC_WALLET_RISK_SCREENING = 1000003;

    /**
     * @dev  Requires the set of claims for specific wallet address
     * @param   walletAddress - user wallet address
     * @param   requiredClaimTopic - claim topic id that needs to be checked
     */
    modifier micapassProtected(
        address walletAddress,
        uint256 requiredClaimTopic
    ) {
        require(
            _micapass.isUserVerifiedForClaim(walletAddress, requiredClaimTopic),
            "Lacking required claims"
        );
        _;
    }

    constructor(address micapassAddress) {
        _setMicapass(micapassAddress);
    }

    function getMicapass() external view returns (address) {
        return address(_micapass);
    }

    function _setMicapass(address micapassAddress) internal {
        require(
            IMicapassBaseVerifier(micapassAddress).supportsInterface(
                type(IMicapassBaseVerifier).interfaceId
            ),
            "Creator interface is incorrect"
        );
        _micapass = IMicapassBaseVerifier(micapassAddress);
    }
}
  • MicapassBasicClientInitializable.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {IMicapassBaseVerifier} from "../interfaces/IMicapassBaseVerifier.sol";

contract MicapassBasicClientInitializable is Initializable {
    IMicapassBaseVerifier internal _micapass;

    // Declare claim topics for function access control
    uint256 internal constant CLAIM_TOPIC_KYC = 1000001;
    uint256 internal constant CLAIM_TOPIC_WALLET_SCREENING = 1000002;
    uint256 internal constant CLAIM_TOPIC_WALLET_RISK_SCREENING = 1000003;

    /**
     * @dev  Requires the set of claims for specific wallet address
     * @param   walletAddress - user wallet address
     * @param   requiredClaimTopic - claim topic id that needs to be checked
     */
    modifier micapassProtected(
        address walletAddress,
        uint256 requiredClaimTopic
    ) {
        require(
            _micapass.isUserVerifiedForClaim(walletAddress, requiredClaimTopic),
            "Lacking required claims"
        );
        _;
    }

    function getMicapass() external view returns (address) {
        return address(_micapass);
    }

    // solhint-disable-next-line func-name-mixedcase
    function __MicapassBasicClient_init(
        address micapassAddress
    ) internal onlyInitializing {
        _setMicapass(micapassAddress);
    }

    function _setMicapass(address micapassAddress) internal {
        require(
            IMicapassBaseVerifier(micapassAddress).supportsInterface(
                type(IMicapassBaseVerifier).interfaceId
            ),
            "Creator interface is incorrect"
        );
        _micapass = IMicapassBaseVerifier(micapassAddress);
    }
}

Step 1.2

Import and inherit fromMicapassBasicClient.sol or MicapassBasicClientInitializable.sol depending on your use case

import {MicapassBasicClientInitializable} from "./MicapassBasicClientInitializable.sol";

contract Client is MicapassBasicClientInitializable, Managerable {
...

Step 2. Initialization

Pass actual address of Micapass smart contract to your smart contract during initialization and pass it to __MicapassBasicClient_init method

Use this page to check available networks and actual addresses

    function initialize(address micapassAddress) external initializer {
        __MicapassBasicClient_init(micapassAddress);
        ...

implement setMicapass method if you want it to be configurable after initialization:

    function setMicapass(
        address micapassAddress
    ) external onlyRole(MANAGER_ROLE) {
        _setMicapass(micapassAddress);
    }

don't forget to protect calling this method for only authorized addresses (admin, manager, etc)

Pay attention that you will not be able to pass address which doesn't support IMicapassBaseVerifier interface, as the internal _setMicapass method is protected with this check

        require(
            IMicapassBaseVerifier(micapassAddress).supportsInterface(
                type(IMicapassBaseVerifier).interfaceId
            ),
            "Creator interface is incorrect"
        );

Step 3. Prepare methods and requirements

Step 3.1

Define your functions that are going to be protected by Micapass

For example it can be

function deposit()

and

function withdraw() 

Step 3.2

Define requirements

  • which address should be checked (sender, receiver, etc)

    • For example for deposit method the msg.sender should be protected by Micapass, but for withdraw - the receiver, or both, msg.sender + receiver

  • which proofs this address should be checked for ( KYC, WALLET_SCREENING), for example:

    • deposit - KYC, WALLET_SCREENING

    • withdraw - only WALLET_SCREENING

Step 4. Protection implementation

Add micapassProtected modifier to each method which should be protected with micapass passing address and claim topic that need to be checked

Examples

example of protection deposit method for msg.sender by checking two claims - KYC and WALLET_SCREENING

function deposit()
        external
        payable
        micapassProtected(msg.sender, CLAIM_TOPIC_KYC)
        micapassProtected(msg.sender, CLAIM_TOPIC_WALLET_SCREENING)
    {
    // logic of deposit
    ...

example of protection withdraw method for msg.sender by checking claim WALLET_SCREENING

function withdraw()
        external
        micapassProtected(msg.sender, CLAIM_TOPIC_WALLET_SCREENING)
    {

or withdraw if the funds should be withdrawn to different address, so we can check receiver for claim WALLET_SCREENING

function withdrawTo(
        address receiver
    )
        external
        mAddressNotZero(receiver)
        micapassProtected(receiver, CLAIM_TOPIC_WALLET_SCREENING)
    {

Last updated