# 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

```solidity
// 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`

```solidity
// 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 from`MicapassBasicClient.sol` or `MicapassBasicClientInitializable.sol depending on your use case`

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

contract Client is MicapassBasicClientInitializable, Managerable {
...
```

## Step 2. Initialization

Pass actual address of [Micapass](https://micapass.gitbook.io/micapass/sc-integration/basic-integration/broken-reference) smart contract to your smart contract during initialization and pass it to \_\_MicapassBasicClient\_init method

{% hint style="info" %}
Use this [page](https://micapass.gitbook.io/micapass/sc-integration/basic-integration/broken-reference) to check available networks and actual addresses
{% endhint %}

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

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

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

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

{% hint style="warning" %}
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

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

{% endhint %}

## 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&#x20;

```solidity
function deposit()
```

and

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

**example of protection deposit method for msg.sender by checking two claims -** KYC and WALLET\_SCREENING

```solidity
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

```solidity
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

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