# 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](https://micapass.gitbook.io/micapass/sc-integration/advanced-integration/broken-reference) 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](https://micapass.gitbook.io/micapass/sc-integration/advanced-integration/broken-reference) 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);
    }
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://micapass.gitbook.io/micapass/sc-integration/advanced-integration/steps-for-advanced-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
