> For the complete documentation index, see [llms.txt](https://micapass.gitbook.io/micapass/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://micapass.gitbook.io/micapass/sc-integration/advanced-integration/steps-for-advanced-integration.md).

# Steps for Advanced Integration

## Step 1

Add the Micapass smart contracts to your codebase

* IMicapassBaseVerifier.sol

```solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.18;

interface IMicapassBaseVerifier {
    /*
     *  @dev get inforamtion if the user is verified for claim
     *  @param userAddress user wallet address
     *  @param requiredClaimTopic claim topics user is being checked for
     *  @return true or false
     */
    function isUserVerified(
        address userAddress,
        uint256[] memory requiredClaimTopics
    ) external view returns (bool);

    /*
     *  @dev get inforamtion if the user is verified for claim
     *  @param userAddress user wallet address
     *  @param claimTopicId claim topic user is being checked for
     *  @return true or false
     */
    function isUserVerifiedForClaim(
        address userAddress,
        uint256 claimTopicId
    ) external view returns (bool);
}
```

## Step 2

Import `IMicapassBaseVerifier.sol` interface to your smart contract

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

## Step 3

Define variable within your smart contract responsible for Micapass smart contract instance

```solidity
    IMicapassBaseVerifier internal _micapass;
    
```

## Step 4

Pass actual address of Micapass smart contract to your smart contract during initialization.&#x20;

{% hint style="info" %}
Use this [page](broken://pages/h9DmccquAOVLVXX3r3xm) to check available networks and actual addresses
{% endhint %}

```solidity
function initialize(address micapassAddress) external initializer {
        _micapass = IMicapassBaseVerifier(micapassAddress);
        ...
```

or through the setter method. Use the Micapass address of the chain you are going to deploy your smart contracts:

```solidity
function setMicapass(
    address micapassAddress
) external onlyRole(MANAGER_ROLE) {
    _micapass = IMicapassBaseVerifier(micapassAddress);
}
```

{% hint style="danger" %}
don't forget to protect calling this method for only authorized addresses (admin, manager, etc)
{% endhint %}

## Step5

Define your functions that are going to be protected by Micapass

For example it can be&#x20;

```solidity
function deposit()
```

and

```solidity
function withdraw() 
```

## Step 6

{% hint style="info" %}
This is only one example of configuring required claim topics ids for scpecific actions within your smart contract, you can follow the flow which better fits your needs, for example - make requirements for each action configurable or hardcode them, pass trough initialization or have specific setters etc
{% endhint %}

Declare claim topics ids which you are going to use&#x20;

```solidity
    uint256 private constant CLAIM_TOPIC_KYC = 1000001;
    uint256 private constant CLAIM_TOPIC_WALLET_SCREENING = 1000002;
```

{% hint style="info" %}
Please refer to [this](broken://pages/tTLwEGgQd3dJEIoQLtzd) page to check the actual proof types (claim topics) and their ids
{% endhint %}

and the variables responsible for storing set of claim topics required for specific methods

```solidity
    uint256[] public requiredDepositClaimTopics;
    uint256[] public requiredHugeDepositClaimTopics; // custom set for the cases with huge amount of deposits
    uint256[] public requiredWithdrawalClaimTopics;
```

here is an example of the case where ***deposit*** method should be protected with two proof types - KYC and Wallet sanctions screening, but ***withdraw*** method is protected only by Wallet sanctions screening:

```solidity
    function initialize(address micapassAddress) external initializer {
        _micapass = IMicapassBaseVerifier(micapassAddress);
        requiredDepositClaimTopics.push(CLAIM_TOPIC_WALLET_SCREENING);
        requiredHugeDepositClaimTopics.push(CLAIM_TOPIC_KYC);
        requiredHugeDepositClaimTopics.push(CLAIM_TOPIC_WALLET_SCREENING);

        requiredWithdrawalClaimTopics.push(CLAIM_TOPIC_WALLET_SCREENING);

        ...
    }
```

## Step 7

Define which user should be checked for Micapass proofs (sender, receiver, etc)

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

## Step 8

In each of the defined functions add the check or required statement for a user(s) verification check&#x20;

* use `isUserVerified` to check if user wallet address has set of claims ***(multi claims check)***

```solidity
    /*
     *  @dev get inforamtion if the user is verified for claim
     *  @param userAddress user wallet address
     *  @param requiredClaimTopic claim topics user is being checked for
     *  @return true or false
     */
    function isUserVerified(
        address userAddress,
        uint256[] memory requiredClaimTopics
    ) external view returns (bool);
```

* use `isUserVerifiedForClaim` to check if user wallet address has specific claim ***(one claim check)***

```solidity
     /*
     *  @dev get inforamtion if the user is verified for claim
     *  @param userAddress user wallet address
     *  @param requiredClaimTopic claim topics user is being checked for
     *  @return true or false
     */
    function isUserVerifiedForClaim(
        address userAddress,
        uint256 claimTopicId
    ) external view returns (bool);
```

#### Examples&#x20;

**example of protection deposit method**

<pre class="language-solidity"><code class="lang-solidity"><strong>    function deposit() external payable {
</strong>        require(
            _micapass.isUserVerified(msg.sender, requiredDepositClaimTopics),
            "Lacking required claims"
        );
        _userBalance[msg.sender] += msg.value;
    }
</code></pre>

**xample of protection deposit method with custom logic - if user deposits > 1 ether - check for extended set of proofs:**&#x20;

```solidity
function deposit() external payable {
        if (msg.value > 1 ether) {
            require(
                _micapass.isUserVerified(
                    msg.sender,
                    requiredHugeDepositClaimTopics
                ),
                "Lacking required claims"
            );
        } else {
            require(
                _micapass.isUserVerified(
                    msg.sender,
                    requiredDepositClaimTopics
                ),
                "Lacking required claims"
            );
        }
        _userBalance[msg.sender] += msg.value;
    }
```

**example of protection withdraw method**

```solidity
    function withdraw() external {
        require(
            _micapass.isUserVerified(msg.sender, requiredWithdrawalClaimTopics),
            "Lacking required claims"
        );
        require(_userBalance[msg.sender] > 0, "No funds deposited");
        uint256 userBalance = _userBalance[msg.sender];
        _userBalance[msg.sender] = 0;
        payable(msg.sender).transfer(userBalance);
    }

```

**or withdraw if the funds should be withdrawn to different address, so we can check receiver in this case**

```solidity
    function withdrawTo(
        address receiver
    ) external mAddressNotZero(receiver) {
        require(
            _micapass.isUserVerified(receiver, requiredWithdrawalClaimTopics),
            "Lacking required claims"
        );
        require(_userBalance[msg.sender] > 0, "No funds deposited");
        uint256 userBalance = _userBalance[msg.sender];
        _userBalance[msg.sender] = 0;
        payable(receiver).transfer(userBalance);
    }
```
