1. Getting started - Fetch the API

    1. Fetch the SDK image on Docker

      If you want to use the SDK as an API, you can fetch the latest Docker Image using the following commands to authenticate to our Docker Registry :

      docker login -u <yourUsername> -p <yourDeployToken> registry.gitlab.com
      

      The credentials <yourUsername> and <yourDeployToken> are provided by Archipels (on demand).

      If a Docker image already exists, you need to configure the imagePullPolicy on Always. This changes needs to be done on your Docker client.

    2. Set up an the environment to authenticate to our registry

      In a .env file or with environment variables, you must set the following variables in order to make requests to the Trust Registry.

      Now you can run the SDK API in a container (using a .env file):

      docker run --env-file .env -p 3000:3000 registry.gitlab.com/archipels-managed/trust-registry-sdk/api:<version>
      

      The version is provided when given the TRUST_REGISTRY_API_KEY.

      Once the container has started, the Open API interactive documentation is accessible on http://localhost:3000/docs.

    3. Create your key pair (public/private)

      This operation is done without any communication with Trust Registry API.

      The algorithm can be EDDSA or ECDSA.

      GET /keys
      Host : "<yourLocalApiInstanceUrl>"
      

      This operation will return this type of json:

      {
        "pub_key": "VNxEdrOol/bnpB3irOCjP7gwanynqJDvUPp6PvI9zOw=",
        "pv_key": "UaBBJVneNEe2q967GHAroXS2tNkoYgr7ZHFjoTlEvMs172Dtq9XaHP4gN9PehiKNotZPPQYfWv9NkzgoTnbWsw==",
        "algo": "EDDSA"
      }
      

      Your private key (pv_key) authenticates you, you must keep it safe and not disclose it to anyone.

      Add it to the .env file you just created.

    4. Complete your environment

      In an .env file or directly in your run environment, you need to add the following variables in order to create or register your identity :

      # .env
      TRUST_REGISTRY_URL="<https://api.archipels.io/trust-registry/v1/>",
      TRUST_REGISTRY_API_KEY="e867be7d-55g2-45f9-80f1-ae776f868754",
      PUBLIC_KEY="VNxEdrOol/bnpB3irOCjP7gwanynqJDvUPp6PvI9zOw=",
      PRIVATE_KEY="UaBBJVneNEe2q967GHAroXS2tNkoYgr7ZHFjoTlEvMs172Dtq9XaHP4gN9PehiKNotZPPQYfWv9NkzgoTnbWsw==",
      ALGORITHM="EDDSA"
      
    5. Register you identity in the Trust Registry

      WARNING : When deploying the Certify solution in production, you cannot create your own identity, Archipels will provide your ISSUER_ID on demand. So you may skip this step.

      There are the instructions for the sandbox deployment.

      To create your identity, you need three environment variables : the TRUST_REGISTRY_URL , the  TRUST_REGISTRY_API_KEY and the SDK_API_URL: where the API SDK is deployed.

      To execute the command you need :

      • one mandatory argument : the "pub_key" :"<PUBLIC_KEY>"
      • two optionals arguments : the metadata including the name "name" of your identity (we recommend to associatemetadata) and its description"description"
      • your issuer_id if you want to choose one especially. If you don’t, it will create an issuer_id for you. You need to save it from the response, since it will be used to identify you.

      To register your identity in the Trust Registry use this code:

      POST /dids -H 'Content-Type: application/json' --data '{ "pub_key": "Ne9g7avV2hz+IDfT3oYijaLWTz0GH1r/TZM4KE521rM=", "metadata": { "name": "Certification Company SAS", "description": "Lorem..." }, "issuer_id": "<your_issuer_id>", "algorithm": "EDDSA" }'
      Host : "<yourLocalApiInstanceUrl>"
      

      If you get the error connect ECONNREFUSED, check if you have the TRUST_REGISTRY_URL set.

      The returned json will be like:

      {
        "pub_key": "VNxEdrOol/bnpB3irOCjP7gwanynqJDvUPp6PvI9zOw=",
        "metadata": {
          "name": "Certification Company SAS",
          "description": "Lorem..."
        },
        "issuer_id": "518f623212217689f0b0ab91157454847aa034f41219829abcd6ea3b898790a6",
        "did_version": null,
        "algorithm": "EDDSA"
      }
      
    6. Finalize your environment

      Now you have all the elements you need to complete your .env file. You must add the issuer_id you just created to your environment so that you have ISSUER_ID = "<issuer_id>"

      Here is an example of a complete .env file :

      # .env
      TRUST_REGISTRY_URL="<https://api.archipels.io/trust-registry/v1/>",
      TRUST_REGISTRY_API_KEY="e867be7d-55g2-45f9-80f1-ae776f868754",
      ISSUER_ID = "518f623212217689f0b0ab91157454847aa034f41219829abcd6ea3b898790a6"
      PUBLIC_KEY="VNxEdrOol/bnpB3irOCjP7gwanynqJDvUPp6PvI9zOw=",
      PRIVATE_KEY="UaBBJVneNEe2q967GHAroXS2tNkoYgr7ZHFjoTlEvMs172Dtq9XaHP4gN9PehiKNotZPPQYfWv9NkzgoTnbWsw==",
      ALGORITHM="EDDSA"
      

      Once completed, you are able to certify schemas and proofs on Archipels.

  2. Certify proofs

    1. Certify digitalDocument proofs

      1. Presentation of the digitalDocument schema

        The digitalDocument schema **is already anchored. Here is how it was built:

        {
            "id": "c42e2516",
            "name": "DigitalDocument",
            "description": "An electronic file or document",
            "version": "0.9.0",
            "namespace": "archipels.io",
            "hash_algorithm": "SHA256",
            "matching_conditions": {
                "or": [
                    "sha256"
                ]
            },
            "inputs": [
                "sha256",
                "dateCreated",
                "expires",
                "creator",
                "category",
                "description",
                null,
                null
            ],
            "input_definitions": {
                "sha256": {
                    "description": "The SHA-2 SHA256 hash of the content of the item.",
                    "standardization_function": "hexadecimal"
                },
                "dateCreated": {
                    "description": "The date on which the CreativeWork was created or the item was added to a DataFeed.",
                    "standardization_function": "formatDateTime"
                },
                "expires": {
                    "description": "Date the content expires and is no longer useful or available.",
                    "standardization_function": "formatDateTime"
                },
                "creator": {
                    "description": "The creator/author of this CreativeWork.",
                    "standardization_function": "replaceDiacritics.capitalize"
                },
                "category": {
                    "description": "A category for the item. Greater signs or slashes can be used to informally indicate a category hierarchy.",
                    "standardization_function": "digitalDocumentCategory"
                },
                "description": {
                    "description": "A description of the item.",
                    "standardization_function": ""
                }
            },
            "metadatum_definitions": {
                "sha256": {
                    "id": "i1",
                    "description": "The SHA-2 SHA256 hash of the content of the item.",
                    "mandatory": true,
                    "publication_flag": "searchable"
                },
                "dateCreated": {
                    "id": "i2",
                    "description": "The date on which the CreativeWork was created or the item was added to a DataFeed.",
                    "mandatory": true,
                    "publication_flag": "public"
                },
                "expires": {
                    "id": "i3",
                    "description": "Date the content expires and is no longer useful or available.",
                    "mandatory": true,
                    "publication_flag": "public"
                },
                "creator": {
                    "id": "i4",
                    "description": "The creator/author of this CreativeWork.",
                    "mandatory": true,
                    "publication_flag": "public"
                },
                "category": {
                    "id": "i5",
                    "description": "A category for the item. Greater signs or slashes can be used to informally indicate a category hierarchy.",
                    "mandatory": true,
                    "publication_flag": "public"
                },
                "description": {
                    "id": "i6",
                    "description": "A description of the item.",
                    "mandatory": true,
                    "publication_flag": "public"
                }
            }
        }
        

        See the next part 2. b. i. Create your proof schema to know more about *"*matching_conditions*"*, *"*standardization_function*",* *"*mandatory*"* and *"*publication_flag*"*.

      2. Create a digitalDocument proof

        Now you know how the schema is built, you can certify digital documents.

        First you must hash with SHA 256 your document using the following command to obtain the"document_hash" of your document.

        $ openssl dgst -sha256 /document_path
        

        There are the data you need to create a proof :

        "schema_id": "c42e2516",
        "sha256": "<"0x"+"document_hash">",
        "dateCreated" : "<creation_date>",
        "expires": "<expiration_date>",
        "creator": "<creator_name>",
        "category": "<document_category>",
        "description": "<description>",
        "secret" : "<12_characters_optional_secret>"
        

        WARNING : make sure to put “0x” before the "document_hash" of your document.

        The secret is used to generate a nullifier. You can create a proof without filling in a secret, but one will be returned after each creation. Please keep these secrets as they are the only data allowing someone to nullify a proof.

        WARNING : The secretmust be a random number generated separately and kept safe as this is required to revoke the proof we've just created. A good secret should have a high entropy level. For example : a good secret can be generated as an UUID, a hash or a password generated by a password manager.

        For the same proof, making requests one after the other without secret will trigger the creation of a proof twice and generate a new ID every calls.

        Now you know how to structure a digitalDocument proof, you will find in the next part 1. a. 2. b. ii. Certify your own proof, **the commands to certify a proof in the Trust Registry.

    2. Certify general proofs

      1. Create your proof schema

        If you're creating a new type of proof, you have to create the schema first.

        In the production environment, your proof schema will be created by the Archipels team after discussing of your use cases.

        In the sandbox environment you’ll need the following information to create a proof schema.

        The proof schema is the proof’s architecture. It is composed from :

        • "id" : the proof schema identifier

        • "name" : the name of the proof schema

        • "description" : the description of the proof schema

        • "version" : the version of the proof schema

        • "namespace" : “archipels.io”

        • "hash_algorithm" : “SHA256”

        • "inputs" : the inputs you need to create and characterize a proof. For example : “input_1”. Note that the number of inputs must be equal to a power of 2. If you don’t have enough inputs you need to complete it with null rows to complete it up to the higher power of 2.

        • "input_definitions" : for each input, you need to complete :

          "input_1" : { 
          "definition" : "<definition_of_the_input>",
          "standardization_function": "<the_function_used_to_standardize_the_input>"
          }
          
          • "standardization_function":
            • capitalize
            • digitalDocumentCategory
            • formatDate
            • formatDateTime
            • hexadecimal
            • removeSpaces
            • replaceDiacritics
        • "metadatum_definitions" :

          "input_1": {
            "id": "i1",
            "description": "<definition_of_the_input>",
            "mandatory": "<boolean>",
            "publication_flag": "<searchable_or_private_or_public>"
          }
          

          See the References for more details about the "id", the "mandatory" and the "publication_flag" inputs.

          • "id": identifier for the place of the Merkle tree where the input is. "i" identify the first stage, "n"is the second. When creating your schema, alway put "i", Archipels can change it after exploring your use case.
          • "mandatory": "true" or "false", it defines if the input is mandatory or not when creating a proof
          • "publication_flag":
            • "searchable": the input is a key for the proof verification, you can use it to identify the proof in the Archipels blockchain
            • "public": the input is disclosed when the proof verification is OK
            • "private": the input is not disclosed when the proof verification is OK
        • "matching_conditions" : a boolean combination of inputs needed to make a proof verification OK

        You can see an example of an existing proof schema in the part 1. a. 2. a. i. Presentation of the digitalDocument schema or in the example below with two inputs:

        {
            "id": "0aaaaa3b",
            "name": "Example",
            "description": "Example of proof schema",
            "version": "0.1.0",
            "namespace": "archipels.io",
            "hash_algorithm": "SHA256",
            "inputs": [
            "input_1",
            "input_2",
            "input_3",
            null
        	  ],
        	  "input_definitions": {
        	    "input_1": {
        	      "description": "Description of input_1",
        	      "standardization_function": "<standardization_function>"
        	    },
        	    "input_2": {
        	      "description": "Description of input_2",
        	      "standardization_function": "standardization_function"
        	    },
        	    "input_3": {
        	      "description": "Description of input_3",
        	      "standardization_function": "<standardization_function>"
        	    }
        	  },
        	  "metadatum_definitions": {
        	    "input_1": {
        	      "id": "i1",
        	      "description": "Description of input_1",
        	      "mandatory": true,
        	      "publication_flag": "searchable"
        	    },
        	    "input_2": {
        	      "id": "i2",
        	      "description": "Description input_2",
        	      "mandatory": true,
        	      "publication_flag": "searchable"
        	    },
        	    "input_3": {
        	      "id": "i3",
        	      "description": "Description of input_3",
        	      "mandatory": true,
        	      "publication_flag": "public"
        	    }
        	  },
            "matching_conditions": {
                "and": [
                    "input_1","input_2"
                ]
            }
        }
        

        Create a .json file (example.json for example) containing your proof schema.

        There is the code to create the schema in the Trust Registry :

        POST /schemas -H 'Content-Type: application/json' --data '@example.json’
        Host : "<yourLocalApiInstanceUrl>"
        

        If the schema already exists you’ll get :

        {
          "status": 409,
          "message": "ProofSchemaExisting"
        }
        

        If it doesn’t, the Trust Registry will send you a 201 response with the details of your schema. The response for the example before is :

        {
          "id": "0aaaaa3b",
          "name": "Example",
          "version": "0.1.0",
          "hash_algorithm": "SHA256",
          "tree_height": 2,
          "description": "Example of proof schema",
          "owner": null,
          "namespace": "archipels.io",
          "inputs": [
            "input_1",
            "input_2",
            "input_3",
            null
          ],
          "input_definitions": {
            "input_1": {
              "description": "Description of input_1",
              "standardization_function": "<standardization_function>"
            },
            "input_2": {
              "description": "Description of input_2",
              "standardization_function": "<standardization_function>"
            },
            "input_3": {
              "description": "Description of input_3",
              "standardization_function": "<standardization_function>"
            }
          },
          "metadatum_definitions": {
            "input_1": {
              "id": "i1",
              "description": "Description of input_1",
              "mandatory": true,
              "publication_flag": "searchable"
            },
            "input_2": {
              "id": "i2",
              "description": "Description input_2",
              "mandatory": true,
              "publication_flag": "searchable"
            },
            "input_3": {
              "id": "i3",
              "description": "Description of input_3",
              "mandatory": true,
              "publication_flag": "public"
            }
          },
          "matching_conditions": {
            "and": [
              "input_1",
              "input_2"
            ]
          }
        }
        

        Once you have created your proof schema, you can certify proofs using this schema on the Archipels Trust Registry.

      2. Certify your own proof

        The data you need to create a proof are the inputs for which mandatoryis true.

        There is the an example based on the "0aaaaa3b"proof schema created in the part before.

        "schema_id": "0aaaaa3b",
        "input_1": "<input_1>",
        "input_2": "<input_2>",
        "input_3": "<input_3>",
        "secret" : "<12_characters_optional_secret>"
        

        The secret given is used to generate a nullifier. You can create a proof without giving a secret, but one will be returned after each creation. Please keep these secrets as they are the only data allowing someone to nullify a proof.

        WARNING : The secretmust be a random number generated separately and kept safe as this is required to revoke the proof we've just created. A good secret should have a high entropy level. For example : a good secret can be generated as an UUID, a hash or a password generated by a password manager.

        For the same proof, making requests one after the other without secret will trigger the creation of a proof twice and generate a new ID every calls.

        If one of your inputs is a document hash, you can use the command below to compute the sha256 of your document :

        $ openssl dgst -sha256 /<pathToFile>/<nameFile>.<extensionFile>
        

        Then, the input would be