Skip to content
securitize-ioPublic

Latest commit

 

History

20 Commits

Folders and files

Repository files navigation

Securitize-iD Integration Tutorial

Summary

altText

This document provides all the required steps to integrate a partner's site with Securitize-iD and the capability of registering attested wallets into a blockchain smart contract.

Securize provides the services to KYC users, as well as the ability to establish if that user complies with a certain set of requirements (attestation requirements) the partner requires from that user. These attestation requirements can simply be that the user is KYCed, but the partner might require that the user resides in a certain jurisdiction (e.g., the United States of America), but doesn’t in specific jurisdictions (e.g, not being a resident in Texas). The attestation rules are quite flexible, and can combine a whole set of user personal identification features to satisfy the partner’s requirements.

To be able to interact with Securitize-iD services:

  1. The user needs to sign-in (or up) in Securitize and have a Securitize ID
  2. The partner will need to require the user permission to access his profile
  3. The partner will need to authenticate in the system
  4. The partner will need to interact with the user to obtain his public crypto wallet address

Prerequisites

In order to be able to access Securitize APIs, a set of information and variables have to be shared between Securitize and the Parner, which are summarized in the following table:

Variable Value Comment
baseUrl

(SecuritizeID)

Take into account, that depending on the environment (Production and Sandbox), issuerID and secret will be different, and the redirecturl will have to be configured in SecID for both environments
API_BASE_URL

(API Gateway)

issuerID String, like this: "b462d564-7562-4528-a207-86fcdfc1c6d5" Provided by Securitize
secret String, like this: "95cacd3d-fbcf-487c-b8f0-60f986ea8968” Provided by Securitize
contractAddress

(Deployed Smart Contract Address)

String like this: “0xB8D7d897BdCe6f6454b54E808461B337058cDB0B” Provided by Securitize
redirecturl "https://{partnerSite}" Provided by Partner

Take into account to change these paramenters in the index.html file:

        const baseUrl = "https://id.sandbox.securitize.io/";
        const API_BASE_URL = "https://connect-gw.sandbox.securitize.io/api/";
        const issuerID = "Provided by Securitize";
        const secret = "Provided by Securitize";
        const redirecturl = "Where the front end Application is hosted"
        const contractAddress = "Provided by Securitize"; // Contract Address 

Securitize ID Flow

In order to access Securitize ID APIs a simple OAuth process takes place, as shown in the figure below:

alt_text

  1. The user accesses the partner's site, and clicks on “Login with Securitize” button
  2. The user gets redirected to Securitize-iD’s site, and the redirection URL contains the following information: issuerId, scope of access (info, details, …) and the URL the user will be re-directed once he has finished signing in (or up).

Login & Sign Up with Securitize-iD

Whitelisting the redirect URL

The partner will need to whitelist the URL the user will be redirected to in Securitize. In order to do so, the following script in python can be used.

# Import the required libraries
import requests
from requests_oauthlib import OAuth1
from requests_oauthlib import OAuth2Session
import json
serviceUrl = 'https://sec-id-api.sandbox.securitize.io/v1/'
Issuer ="{Issuer Name}"
issuerID="{issuerID}"
Secret ="{secret}"

body = {'appIcon':{url of the icon},
       'appName':'{Issuer Name}',
       'redirectUrls':['{redirectUrl}']}

response = requests.patch(
   serviceUrl + issuerID ,
   headers={'Authorization': Secret},
   data= body
)

if (response.status_code == 200):
 print("Correctly updated")
else:
 print('Error: ', response.content)

Or using the following CURL:

curl -X PATCH "https://sec-id-api.sandbox.securitize.io/v1/{issuerID}" -H "accept: application/json" -H "Authorization: {secret}" -H "Content-Type: application/json" -d "{body}"

Where:

Parameter Description
{issuerID} Is the issuer ID provided by Securitize
{secret} Is the {secret} provided by Securitize
body
{ 
"appIcon": "Icon url", 
"appName": "The Name of your App or [yourdomain]", 
"redirectUrls": [ 
"https://[yourdomain]/*" ]
}
    

Show the Logo

The partner can integrate the Securitize iD button within his own UI. The Partner’s landing page should show a button which links to Securitize iD.

altText

For instance, the partner could use the following code to include in his landing page, which basically creates a button and, once clicked, re-directs the user to Securitize-iD authorization site:

   function showSecuritizeIDLogInLogo(baseUrl, issuerID, redirecturl) {
       var scope = "info";
       var securitizeID = document.getElementById("SecuritizeID");
       var link = document.createElement("a");
       var logo = document.createElement("img");

       var href = baseUrl + "#/authorize" + "?issuerId=" + issuerID + "&scope=" + scope + 
                             "&redirecturl=" + redirecturl;
       logo.src = "./images/securitizeID.png";
       link.href = href;
       link.id = "SecuritizeLogo";
       link.appendChild(logo);
       securitizeID.appendChild(link);
   }

Capture the Token

alt_text

Once the user has singed–in (or up) in Securitize-ID, he will be redirected back the the partners site. The URL of the redirection will look like this:

{Redirecturl}?code={code}&authorized=true

Hence, the partner will have to capture the information in the parameters of the URL. This can be simply done with the following JavaScript function:

   function captureTOKEN() {
       const queryString = window.location.search;
       const urlParams = new URLSearchParams(queryString);
       const code = urlParams.get("code");
       const authorized = urlParams.get("authorized");
       const country = urlParams.get("country");
       console.log(code, country, authorized);
       if (code != null) { // User has signed-up and has a SecuritizeID
           return code;
       }
   }

User has no Securitize-iD

In case the user has not registered in Securitize-iD before, he will have to sign-up and follow the 5 KYC steps in order to be KYCed by Securitize.

In any case, this is not affecting the way the partner is interacting with the user. By the end of the process, the user will be redirected to the partner’s site exactly in the same way as he had already a verified Securitize-iD. However, in this case, the partner will have to check that the user has been KYCed by Securitize to access the rest of the APIs.

Request JSON Access Token

alt_text

The partner will need to request Securitize API GW a JSON Access token to be able to interact with the rest of the APIs through a simple request:

curl --location --request POST '{API_BASE_URL}/api/auth/v1/authorize' \
--header 'Authorization: Bearer {secret}' \
--header 'Content-Type: application/json' \
--header 'clientid: {issuerID}' \
--data-raw '{
   "code": "{code}"
}'

Where:

Parameter Description
{API_BASE_URL}
{issuerID} Is the {issuerID} provided by Securitize
{secret} Is the {secret} provided by Securitize
{code} The {code} returned in the redirect URL

The following JavaScript function will request, and return, the access Token to be later used to access Securitize APIs:

   function requestAccessToken(Url, code, secret, clientId) {
       var xhr = new XMLHttpRequest();
       var responseString = null;
       xhr.addEventListener("readystatechange", function () {
           if (this.readyState === 4) {
               if (this.status === 200) {
                   response = JSON.parse(this.responseText);
                   console.log("Authorized with access Token: ", response.accessToken);
                   responseString = 
                                  JSON.parse('{"response":"OK", "accessToken":"' +
                                              response.accessToken + '"}');
               }
               else {
                   responseString = JSON.parse('{"response":"NoAccessToken"}');
               }
               console.log(this.responseText);
           } else {
               console.log("Big Problem", this);
               responseString = JSON.parse('{"response":"CORS_PROBLEM"}');
           }
       });

       xhr.open("POST", Url, false);
       xhr.setRequestHeader("Content-Type", "application/json");
       xhr.setRequestHeader("Authorization", "Bearer " + secret);
       xhr.setRequestHeader("clientid", issuerID);
       try {
           xhr.send(JSON.stringify({ "code": code }));
           return responseString;
       } catch (err) {
           console.log(err);
           return responseString;
       }
   }

Connect Wallet

alt_text

After the user has signed in into Securitize-iD, the partner will have to provide all the functionality to enable the user’s Crypto-Wallet connection. There are multiple ways of doing this, as well as packages and libraries to deal with the details. In this tutorial, and the code provided, we have used Web3Modal, which provides all the basic functionality to connect to a wallet and retrieve the user’s wallet public address.

Registering a Wallet into the BlockChain

alt_text

In order to register the user’s wallet into the BlockChain registry, Securitze has developed the infrastructure to simplify the process as much as possible.Therefore, by hitting the following endpoint

curl 'https://connect-gw.sandbox.securitize.io/api/bc/v1/partners/{issuerID}/attestation' \
  -H 'access-token: {accessToken}' \
  -H 'Content-Type: application/json' 

Where:

Parameter Description
{issuerID} Is the {issuerID} provided by Securitize
{accessToken} Is the {accessToken} returned by the request JSON Access Token API

The result might contain the following values

Parameter Description
{"status":"passed"} If the user has passed all the Attestation Rules
{"status":"rejected"} If the user does not pass all the Attestation Rules. In order to protect the user privacy, no further information will be provided of why the user did not pass the attestation rules.

And with this endpoint:

curl 'https://connect-gw.sandbox.securitize.io/api/bc/v1/partners/{issuerID}/wallets/{wallet}/whitelist' \
  -H 'access-token: {accessToken}' \
  -H 'Content-Type: application/json' 

Where:

Parameter Description
{wallet} Is the {wallet} address of the user, which will be registered and whitelisted in the Registry smart contract

The Partner will receive a prepared meta-transaction which can be signed by the user, using his, e.g., metamask wallet, to sign the transaction and store his wallet in the BlockChain Registry contract, like this:

{
    "preparedTransaction": "0xf9014a80843b9aca00835b8d8094b8d7d897bdce6f6454b54e808461b337058cdb0b80b901246e5832f2000000000000000000000000000000000000000000000000000000000000001b67d0a755ff7a6ccfab413c71ee5fac8a3d11c3a699dc2381b0bb0f9c077ccd471d1c3cc8fcd31936f63b67f66285b42f5c3233f7cafb75efe12309bf94d6bf5f00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000005b8d8000000000000000000000000000000000000000000000000000000000000000440a2a9a01000000000000000000000000bf244e70c66b0a70d071cd0374e6b14397f0f55c0000000000000000000000000000000000000000000000000000000000a22b9200000000000000000000000000000000000000000000000000000000808080"
}

A simple JavaScript snippet to call the API and use Web3 to trigger Metamask on the user’s browser to sign the transaction could look like this:

var transaction = await requestTransaction(Url, accessToken);    
console.log("The transaction: ", transaction["preparedTransaction"]);

   const tx = new ethereumjs.Tx(transaction["preparedTransaction"]);

   const params = {
            gas: '0x' + tx.gas.toString("hex"),
            gasPrice: '0x' + tx.gasPrice.toString("hex"),
            gasLimit: '0x' + tx.gasLimit.toString("hex"),
            to: tx.to.toString("hex"),
            value:  tx.value.toString("hex"),
            data: '0x' + tx.data.toString("hex"),
            from: selectedAccount
   }

   await window.ethereum.request({
       method: 'eth_sendTransaction',
       params: [params],
   }).then((result) => {
       console.log('Transaction Hash:', result)
   });

Interacting with the Smart Contract

The deployed Registry Smart Contract has a set of methods the partner can interact with:

    function addOwner(address _newOwner) public onlyOwners {}

    function removeOwner(address _owner) public onlyOwners {}

    function addWalletFromOwner(address _wallet) public onlyOwners {}

    function addWallet(address _wallet, uint256 _blockLimit) public onlyOwners {}

    function removeWalletFromOwner(address _wallet) public onlyOwners {}

    function removeWallet(address _wallet) public {}

    function isWhitelisted(address _wallet) public view returns (bool) {}

    function getTotalWallets() public view returns (uint256) {}

    function getChainId() public view returns (uint256) {}

In order to interact with the methods using Web3 in the browser, these simple calls can be used:

Retrieve number of total registered Wallets

 const totalWallets = await theContract.methods.getTotalWallets().call();

Checking if a Wallet has been Whitelisted

const isWhitelisted = await theContract.methods.isWhitelisted(selectedAccount).call();

Removing a Wallet from the Whitelist

await theContract.methods.removeWallet(selectedAccount).send({ from: selectedAccount }, function (err, res) {
               if (err) {
                   showInfo("An error occured" + err, "error");
                   return
               }
               console.log("Hash of the transaction: " + res);
});

Releases

Packages

Contributors

Languages