# For SDI Issuers

### Terms

**SDI** - Swisstronik Digital Identity.

**Issuer** - An organization, business, or government entity that conducts user and business checks and issues verifications based on those checks.

**Verifier** - Generally, an organization that requires verification of certain conditions for the user to engage, transact, or provide services. Currently, for simplicity, we consider this a smart contract on the Swisstronik blockchain network that interacts with the x/compliance module.

**Operator** - An entity that can verify that the Issuer is legitimate and trustworthy.

**Main Operator** - The first and only operator authorized to create other operators. Cannot be deleted.

**Regular Operators** - All operators except the Main Operator.

**x/compliance module** - A part of SDI integrated into the Swisstronik Blockchain. It is a decentralized storage of verifications made by Issuers and provides this data to Verifiers for user verification.

**Verification** - An entry in the Swisstronik blockchain, created and verified by the Issuer, which is the result of a specific user verification.

**User** - An individual or a company that has a blockchain address and needs to use services or products.

### Interaction Steps

1. [**Deploy Smart Contract**](#deploy-a-smart-contract) **-** The issuer deploys a smart contract that will interact with the x/compliance module;
2. [**Create an Issuer**](#create-an-issuer) - The Issuer is registered in the x/compliance module. This operation is available to anyone;
3. [**Verify Your Issuer**](#verify-your-issuer) - The Operator verifies the registered Issuer by interacting with the x/compliance module, marking the address of the smart contract created by the Issuer as verified, ensuring that the address is associated with the company and that the company is legitimate;
4. [**Issue Verifications for Your Users**](#issue-verifications-for-your-users) - The authorized Issuer uploads verifications to the Swisstronik Blockchain via its designated smart contract.

You can create the necessary SDI entities using [CLI transaction commands](#cli-transaction-commands).&#x20;

Additionally, you can always get information regarding the SDI entities by running [CLI query commands](#cli-query-commands).

### Deploy a Smart Contract

The issuer must deploy a smart contract to interact with the x/compliance module.&#x20;

An example of such a smart contract is shown below:

```solidity
pragma solidity ^0.8.24;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

interface IComplianceBridge {
    enum VerificationType {
        VT_UNSPECIFIED, // VT_UNSPECIFIED defines an invalid/undefined verification type.
        VT_KYC, // Know Your Custom
        VT_KYB, // Know Your Business
        VT_KYW, // Know Your Wallet
        VT_HUMANITY, // Check humanity
        VT_AML, // Anti Money Laundering (check transactions)
        VT_ADDRESS,
        VT_CUSTOM,
        VT_CREDIT_SCORE
    }

    function addVerificationDetails(
        address userAddress,
        string memory originChain,
        uint32 verificationType,
        uint32 issuanceTimestamp,
        uint32 expirationTimestamp,
        bytes memory proofData,
        string memory schema,
        string memory issuerVerificationId,
        uint32 version
    ) external;
}


contract Adapter is Ownable, EIP712 {
    event UserVerified(address _userAddress);

    constructor() EIP712("World Coin Adapter", "1") Ownable(msg.sender) {}

    function addVerificationDetails(
        address userAddress,
        string memory originChain,
        IComplianceBridge.VerificationType verificationType,
        uint32 issuanceTimestamp,
        uint32 expirationTimestamp,
        bytes memory proofData,
        string memory schema,
        string memory issuerVerificationId,
        uint32 version
    ) internal {
        bytes memory payload = abi.encodeCall(
            IComplianceBridge.addVerificationDetails,
            (
                userAddress, // user address
                originChain, // chain_id if transferred via cross-chain
                uint32(verificationType), // verification type
                issuanceTimestamp, // issuance timestamp
                expirationTimestamp, // expiration timestamp
                proofData, // proof data
                schema, // schema
                issuerVerificationId, // issuer verification id
                version // version
            )
        );

        (bool success, bytes memory data) = address(1028).call(payload);
        require(
            success,
            string(abi.encodePacked("Verification failed: ", data))
        );
    }


    function recoverSigner(
        bytes calldata signature
    ) public view returns (address) {
        bytes32 structHash = keccak256(
            abi.encode(
                keccak256("Obj(string contents)"),
                keccak256("World Coin Verification")
            )
        );

        bytes32 digest = _hashTypedDataV4(structHash);

        return ECDSA.recover(digest, signature);
    }

    function markAsVerified(
        bytes calldata signature,
        bytes memory proofData,
        string memory nullifierHash
    ) public onlyOwner {
        address userAddress = recoverSigner(signature);
        string memory originChain = "chain_1291-1";
        string memory schema = "WorldcoinV1";
        string memory issuerVerificationId = nullifierHash;
        uint32 version = 1;

        addVerificationDetails(
            userAddress,
            originChain,
            IComplianceBridge.VerificationType.VT_HUMANITY,
            uint32(block.timestamp % 2 ** 32),
            0,
            proofData,
            schema,
            issuerVerificationId,
            version
        );

        emit UserVerified(userAddress);
    }
}

```

### Create an Issuer

There are a few CLI commands intended to manage issuers. You can [create](#creating-issuer), [modify](#modifying-issuers-data), or [delete ](#deleting-issuer)an issuer.

### Verify your issuer

After you have deployed a smart contract and created an issuer using the CLI, the issuer needs to be verified. To do this, please contact us through the validators, on Discord, or by emailing <contact@swisstronik.com>. Authorized operators will verify your issuer. You can check the status of your issuer by using the `get-issuer-details` CLI command.

### Issue **Verifications for Your Users**

After verification of the issuer by an authorized operator, the issuer can start uploading verifications using its designated smart contract.

### CLI Commands Access Table

Here is a list of CLI commands with access permissions for different entities:&#x20;

<table><thead><tr><th>Command</th><th>Main Operator</th><th width="164">Regular Operator</th><th>Issuer</th><th>All the rest </th></tr></thead><tbody><tr><td>Any query command</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr><tr><td>add-operator</td><td>Yes</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>remove-operator</td><td>Yes, except removing Main Operator</td><td>Yes, except removing itself and Main Operator</td><td>No</td><td>No</td></tr><tr><td>create-issuer</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr><tr><td>update-issuer-details</td><td>Yes</td><td>Yes</td><td>Issuer creator only</td><td>Issuer creator only</td></tr><tr><td>remove-issuer</td><td>Yes</td><td>Yes</td><td>Issuer creator only</td><td>Issuer creator only</td></tr><tr><td>set-issuer-status</td><td>Yes</td><td>Yes</td><td>No</td><td>No</td></tr></tbody></table>

### CLI transaction commands

#### Creating Issuer

To create an issuer, you need to use the `create-issuer` command:

```bash
swisstronikcli tx compliance create-issuer [issuer-address] [name] [description] [url] [logo-url] [legal-entity] [flags]
```

Where:

* `issuer-address`: Issuer address in the Swisstronik Network.
* `name`: Name of the issuer.
* `description`: Short description of the issuer.
* `url`: Issuer's website link.
* `logo-url`: Issuer's logo link.
* `legal-entity`: Legal entity of the issuer.
* `flags`: Additional flags. You need to specify at least `--from` and `--fees` flags for the command.

#### Modifying Issuer's data

To modify the data for the issuer, use the following command:

<pre class="language-bash"><code class="lang-bash"><strong>swisstronikcli tx compliance update-issuer-details [issuer-address] [name] [description] [url] [logo-url] [legal-entity] [flags]
</strong></code></pre>

Parameters:

* `issuer-address`: Issuer address in the Swisstronik Network.
* `name`: Name of the issuer.
* `description`: Short description of the issuer.
* `url`: Issuer's website link.
* `logo-url`: Issuer's logo link.
* `legal-entity`: Legal entity of the issuer.
* `flags`: Additional flags. You need to specify at least `--from` and `--fees` flags for the command.

#### Deleting Issuer

To remove an issuer, use the following command:

```bash
swisstronikcli tx compliance remove-issuer [issuer-address] [flags]
```

Where:

* `issuer-address`: Issuer address in the Swisstronik Network.
* `flags`: Additional flags. You need to specify at least `--from` and `--fees` flags for the command.

{% hint style="info" %}
Please note that only Operators are able to delete Issuers. See the [Access Table](#cli-commands-access-table) for reference.
{% endhint %}

#### Setting Issuer's verification status

To set issuer's verification status, use the following command:&#x20;

```bash
swisstronikcli tx compliance set-issuer-status [issuer-address] [verification-status] [flags]
```

Where:

* `issuer-address`: Issuer address in the Swisstronik Network.
* `verification-status`: Boolean indicator of whether the Issuer associated with the address was verified by the Operator. Possible values: true/false.
* `flags`: Additional flags. You need to specify at least `--from` and `--fees` flags for the command.

#### Creating Operator

To create an operator, you should use the following command:

```sh
swisstronikcli tx compliance add-operator [operator-address] [flags]
```

* `operator-address`: The operator's address in the Swisstronik Network in bech32 or hex format;
* `flags`: Additional flags. You need to specify at least the `--from` and `--fees` flags for the command.&#x20;

{% hint style="info" %}
Please note that to add the operator, the transaction must be signed with the operator's private key, see the [Access Table](#cli-commands-access-table) for reference.
{% endhint %}

#### Deleting Operator

To delete an operator, you should use the following command:

```sh
swisstronikcli tx compliance remove-operator [operator-address] [flags]
```

* `operator-address`: The operator's address in the Swisstronik Network.
* `flags`: Additional flags. You need to specify at least the `--from` and `--fees` flags for the command.&#x20;

{% hint style="info" %}
Please note that to delete the operator, just as with creating an operator, the transaction must be signed with the operator's private key. See the [Access Table](#cli-commands-access-table) for reference.
{% endhint %}

### CLI query commands

#### Getting Operator Details

To get information about an operator, use the following command:

```bash
swisstronikcli query compliance get-operator [operator-address] [flags]
```

Where:

* `operator-address`: The operator's address in the Swisstronik Network in Bech32 or hex format.
* `flags`: Additional flags.

You will receive output like this:

```
details:                       
 operator: swtr1yjffhqr3m20fxahmgmjghekw547uz22ygvfclk 
 operator_type: OT_INITIAL 
```

Possible values for the `operator_type`:

* **`OT_INITIAL`**: The main operator, cannot be deleted;
* **`OT_REGULAR`**: Regular operator;
* **`OT_UNSPECIFIED`**: The address is not associated with any operator.

#### Getting Issuer Details

To get information about an issuer, use the following command:

```bash
swisstronikcli query compliance get-issuer-details [issuer-address] [flags]
```

Where:

* `issuer-address`: The issuer's address in the Swisstronik Network in Bech32 or hex format.
* `flags`: Additional flags.

You will receive output like this:

```yaml
details:                       
 description: The most important issuer
 legalEntity: Authorized issuer GmbH
 logo: https://pbs.twimg.com/profile_images/1630871073917894659/LbAxXi_V_400x400.jpg
 name: SuperIssuer    
 url: www.swisstronik.com 
```

#### Getting All Issuers Details

To get information about all the issuers, use the following:

```bash
swisstronikcli query compliance get-issuers-details [flags]
```

* `flags`: Additional optional flags.

You will receive output like this:

```yaml
issuers:
- description: World ID is privacy preserving proof of personhood, which allow for
    Proof of Humanity verifications
  issuerAddress: swtr1243hzt2fy03jyr8ef4fa6tuhvktfmwkru39pqz
  legalEntity: Worldcoin Foundation, World Assets Ltd.
  logo: https://bafkreidg6wx6pkyhgenoerdnqsqgws32fe4phbgmmcjebtrbvbxfq35awu.ipfs.dweb.link
  name: Worldcoin Adapter
  url: https://worldcoin.org
- description: Quadrata Passport is a soulbound token, which allows for KYC, KYB,
    AML and Credit Score verifications
  issuerAddress: swtr1juwdxadg0xw20u3kvyzwz979f9ey83rcqvgn6m
  legalEntity: Quadrata, Inc.
  logo: https://bafkreigajtsnqh4qygsftcb3bnoxf5wyin75hauhn2a3ar2ztncm57b5zu.ipfs.dweb.link
  name: Quadrata Adapter
  url: https://quadrata.com
- description: The most important issuer
  issuerAddress: swtr1nq8eyzmym9u5kmf735s865nepkyd52dtmenpvg
  legalEntity: Authorized issuer GmbH
  logo: https://pbs.twimg.com/profile_images/1630871073917894659/LbAxXi_V_400x400.jpg
  name: SuperIssuer
  url: www.swisstronik.com
pagination:
  next_key: null
  total: "0"
 
```

#### Getting Verification Details

To get information about a Verification, use the following command:

```bash
swisstronikcli query compliance get-verification-details [verification-id] [flags]
```

Where:

* `verification-id`: The issuer's address in the Swisstronik Network in Bech32 or hex format.
* `flags`: Additional flags.

You will receive output like this:

```yaml
details:
  expiration_timestamp: 0
  issuance_timestamp: 1719266788
  issuer_address: swtr1juwdxadg0xw20u3kvyzwz979f9ey83rcqvgn6m
  issuer_verification_id: 0xc5d81223aed4183dce6bf48e369349becef83570011cd205a8445631fa365a4d
  origin_chain: chain_1291-1
  original_data: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRlIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjB4YzVkODEyMjNhZWQ0MTgzZGNlNmJmNDhlMzY5MzQ5YmVjZWY4MzU3MDAxMWNkMjA1YTg0NDU2MzFmYTM2NWE0ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
  schema: quadrataPassportV1
  verificationID: /aaNbgNPGQhYNCYKZQYisJ58jLtpDi0BlibJlG1iu+k=
  type: VT_AML
  version: 1
```

* **`expiration_timestamp`** - The validity period for the Verification in UNIX time format. 0 means the validity period is forever.
* **`issuance_timestamp`** - The time when the Verification was created, in UNIX time format.
* **`issuer_address`** - The address of the Issuer that issued the verification.
* **`issuer_verification_id`** - The internal ID of the Verification on the Issuer's side.
* **`origin_chain`** - The blockchain network on which the Verification was issued.
* **`original_data`** - The field that contains all the data related to the Verification.
* **`schema`** - The method describing how to parse the `original_data` field.
* **`verificationID`** - The Verification ID of the x/compliance module.

Possible values for the **`type`** :

* **`VT_UNSPECIFIED`** - Defines an invalid/undefined verification type.
* **`VT_KYC`** - Know Your Customer
* **`VT_KYB`** - Know Your Business
* **`VT_KYW`** - Know Your Wallet
* **`VT_HUMANITY`** - Check humanity
* **`VT_AML`** - Anti Money Laundering (check transactions)
* **`VT_ADDRESS`** - Verification of Address
* **`VT_CUSTOM`** - Custom Verification
* **`VT_CREDIT_SCORE`** - Verification of Credit Score

#### Getting Verifications Details

To get information about all Verifications, use the command:

```bash
swisstronikcli query compliance get-verifications-details [flags]
```

Where `[flags]` are optional.

The command returns the sequence of Verifications in the same format as for the [get-verification-details](#getting-verification-details) command. You can apply pagination by using the `--limit`, `--offset`, `--page`, and `--page-key` flags."

#### Getting Address details

To get information associated with the provided address use the command:

<pre><code><strong>swisstronikcli query compliance get-address-details [flags]
</strong></code></pre>

Where `[flags]` are optional.

#### Getting Addresses details

To get information about all the Addresses, use the command:

<pre><code><strong>swisstronikcli query compliance get-addresses-details [flags]
</strong></code></pre>

You will receive output like this:

```yaml
data:
  is_revoked: false
  is_verified: false
  verifications:
  - issuer_address: swtr1juwdxadg0xw20u3kvyzwz979f9ey83rcqvgn6m
    type: VT_AML
    verification_id: q0+6sUL3PgUbLVbdMyM0lsTBnRjeKBNDzhu57x6Hm94=
  - issuer_address: swtr1juwdxadg0xw20u3kvyzwz979f9ey83rcqvgn6m
    type: VT_KYC
    verification_id: LyIAYV06gOMD809Kny2wfJDnLK1djQIPl8STpSONkCI=

```

* **`is_revoked`** - Boolean indicating if the address was revoked.
* **`is_verified`** - Boolean indicator of whether the Issuer associated with the address was verified by the Operator.
* **`verifications`** - Array of Verifications associated with the address. Please see the "[Getting Verification Details](#getting-verification-details)" section for the description of the fields.
