Skip to content

Latest commit

 

History

History
363 lines (271 loc) · 21.8 KB

3.Initialization.md

File metadata and controls

363 lines (271 loc) · 21.8 KB

3. Initializing the Wallet and Cloud Agent

High Level Overview of steps

  1. Create a sponsor service/endpoint on your app's backend. A minimal sample can be found here.
  2. Ask Evernym to onboard you as a Sponsor. Check below for more details.
  3. Complete mobile SDK project setup guide first.
  4. Implement initialization logic for your application:
    1. Call your sponsor backend API (service set up in Step 1) to get provision token (once for the app).
    2. Call Evernym mobile SDK provision API with provided token to obtain a Cloud Agent (once for the app).
    3. Call Evernym mobile SDK to initialize library (every app run).

All the above steps are explained in detail in this document.

Introduction

Using the Evernym mobile SDK currently requires that the SDK be connected to and rely on a cloud agent that is hosted and provisioned at Evernym. In the future, this Evernym cloud agent will be replaceable with your own or the one from a different vendor, but still usable with the Evernym Mobile SDK. This agent is used for its store-and-forward services, persistence and availability and ability to push notify to a device or forward via http to the appropriate sponsor. By default, Evernym’s hosted cloud services are locked down. In order for your mobile SDK instance to prove that it has permission to provision a new hosted cloud agent (one unique cloud agent per installation of your mobile app), you must provide a provisioning token.

To register as a sponsor, you will need to contact Evernym at [email protected]

Definitions

  • Sponsor
    You are the sponsor. You as the Sponsor are the application owner using the mobile sdk to Sponsor individual app installs e.g. Example Credit Union is the Sponsor using the Evernym mobile SDK inside their own mobile app. Also Sponsor should have backend server that will perform token issuing. A sponsor provides a provision token so that their customers can provide authorization with Evernym's cloud agent.

    Example Credit Union is the Sponsor using the Evernym mobile SDK inside their own mobile app.

  • Sponsee
    Your customer's individual App installation on mobile device.

    Example The app on Ryan’s phone is a Sponsee. He is an Example Credit Union member installing Example CU’s mobile app (Sponsor)

  • Evernym Cloud Service
    Evernym hosted cloud service which facilitates provisioning and management of cloud agents.

  • VCX Config: The list of options can be set in the config JSON passed to vcx_get_provision_token and vcx_provision_agent_with_token functions can be found in the document.

  • Provision Token
    This token is provided by you as a Sponsor to enable provisioning of one of your customers (Sponsee) on an Evernym hosted cloud agent.

     {
       "sponseeId":     String,
       "sponsorId":     String,
       "nonce":         String,
       "timestamp":     String,
       "sig":           String,
       "sponsorVerKey": String,
     } 

    Provision Token Fields

    • sponseeId: An identifier you as a Sponsor use to identify/reference your customer the Sponsee. This can be a customer id used to identify the customer (Sponsee) in your (Sponsor) back end database. In other words, this is an ID of an app user.
    • sponsorId: An ID given to you from Evernym's Support Team after the Sponsor onboarding process is complete.
    • nonce: Randomly generated string. Used as one-time security token during registration.
      Example. random.number.toString()
    • timestamp: An RFC 3339 and ISO 8601 date and time string such as 1996-12-19T16:39:57-08:00.
    • sig: You will provide a signature to your customer (the Sponsee) so that they can provision with Evernym's Cloud Agent. You (The Sponsor) will:
      1. create a string by concatenating in this order nonce + timeStamp + sponseeId + sponsorId
      2. sign the resulting string with the keys registered during the onboarding process. The keys that match the configured sponsorVerKey.
      3. Base64 encode the result of the signature Example Base64Encode(Sign(nonce + timeStamp + sponseeId + sponsorId))
    • sponsorVerKey: This is the key you as the Sponsor provided to Evernym's support team during onboarding. You (Sponsor) can register multiple keys during onboarding so this identifies which key to use during authorization. This key is not used unless a corresponding one is found in the configuration.

Sponsor server

In order to receive messages from other sides each application must have an associated Cloud Agent. The process of getting of a Cloud Agent consist of two steps:

  1. Application call Sponsor Server to receive a provisioning token.
  2. Application call SDK function to provision Cloud Agent with received token.

A simple Sponsor Server performing generation and signing of tokens which can be used for provisioning of a Cloud Agents can be found here.

Sponsor Server may also include additional logic like Push Notifications which is not demonstrated in the sample.

Sponsor (i.e. You) Onboarding with Evernym's Cloud Service

  • In order for you to register as a Sponsor, contact [email protected].

  • Onboarding/Registration requires you (the Sponsor) to provide these attributes to Evernym's support team. Please include them in your email to [email protected]:

    1. Name of you organization
    2. Verification Keys: List (1 or many) of your Sponsor VerKeys (verification key or public key) associated with the signing of the token. This is used to verify and authenticate a customer's (Sponsee) provision token during the provisioning on Evernym's Cloud Service.
      • The signing keys (including the verkey shared with Evernym's Cloud Service) can be generated using this simple tool: https://github.com/sovrin-foundation/launch/raw/master/sovrin-keygen.zip
      • The Private keys need to be stored in a safe place under your (Sponsor's) control. You should not send private key in email.
      • The public verkey should be shared with Evernym for signature validation.
    3. Endpoint: Your (Sponsor's) URL that Evernym Cloud Service should forward customer (Sponsee) messages to. This is how you can add push notifications to your mobile app. Evernym does not host a push notification service for the mobile SDK, you must create and manage your own. Evernym cloud agents will forward messages to this endpoint for you to push notify to your app.

Mobile Application Provisioning Overview

  1. Get Provision Token

    • You as the Sponsor will need to sign a provision token for your customer (Sponsee). Your app will have to communicate with you (Sponsor) to receive a token.
    • This token will contain a signature generated by you (Sponsor) to ensure the customer's app (Sponsee) has authorization to do so.
    • The sig field in Token Fields describes how to sign a token.
    • It also contains a timestamp. If the token isn’t delivered to Evernym's Cloud Service in a predefined time frame, the token will be invalid. Your customer's app (Sponsee) will need to request another token from you (Sponsor).
    • If for whatever reason provisioning fails, your customer's app (Sponsee) should request a new token from you (Sponsor) and attempt provisioning again.
  2. Provisioning

    • Once your app has a provision token, you need to call SDK function with passing the received token to obtain its associated Cloud Agent.

    • This API expects two parameters of string type. These strings are JSON stringified objects which have following format

      vcx_config: { - VCX library config 
          // Target Agency
          agency_endpoint: string, // url of agency to connect
          agency_did: string, // did of agency
          agency_verkey: string, // verkey of agency
          // Creating Wallet 
          wallet_name: string, // name of wallet
          wallet_key: string, // key to be used for wallet encryption
          // Pool Ledger
          path: string, // path to file containing pool genesis transactions
          // User Meta
          logo: string, // url leading to image
          name: string, // name to use
          // Communication Protocol
          protocol_type: '4.0', // aries communication protocol
          // it can be extended with other configuration options (see Configuration.md document)
          ...
      }
      token: { - Token received from Sponsor
         sponseeId:     String,
         sponsorId:     String,
         nonce:         String,
         timestamp:     String,
         sig:           String,
         sponsorVerKey: String,
      }
    • The value returned from this api (it can be ) will be the input for SDK initialization function. Note, that provisioning step need to be done only once by each application. On the following runs, the application should use configuration JSON received after provisioning and do library initialization directly. At this point, the app will be provisioned on Evernym's Cloud Service with a cloud agent and will have a local wallet initialized but NOT open. As the next step, you need to initialize VCX library with the received configuration JSON ( initialization will open the wallet and set settings).

    • As mentioned above, at this step the Mobile SDK Wallet will be initialized. The only action required for the wallet initialization is providing a key that will initialize/encrypt/decrypt the wallet. wallet_key inside vcx_config in the above code sample is the key the client's app needs to provide. The generation of this key depends on the client's app. Here is an example implementation of the key generation for Android and iOS.

      Note, that the provisioning step needs to be done only on the first application run. On the following runs, the application should use configuration JSON received after provisioning and do library initialization directly.

  3. Receiving Your customer's Future Messages

    Cloud Agent is needed to receive messages from other parties. Once an application provisioned a Cloud Agent, there are two ways of message receiving from it:

    • Polling - Customer application once in a while calls Cloud Agent to get all received messages.

      This strategy is used in the sample applications.

    • Push Notifications - Cloud Agent forwards messages to Sponsor which then notifies application. Go to the document to get more information regarding setting push notifications.

NOTE: In the following tutorials we demonstrate the usage of protocol_type: '4.0'. You need to put it into provisioning config.

Detailed about Application Provision and Initialization Steps

Overview:

  1. Prepare Application environment data:
    • Agency information is going to be used for Cloud Agent provisioning.
    • Pool Genesis transactions is going to be used for Pool Ledger Network connection.
    • Application meta information (name, logo).
    • Default protocol type is 3.0, but we recommend to use "protocol_type":"4.0".
  2. On first application init:
    • Create a directory where wallet will be located.
    • Generate wallet key. This key will be used to derive a key used for the encryption of SDK data stored in the wallet.
    • (Optionally) Configure and init logger.
    • Call Sponsor server backend API to get provision token.
    • Call VCX function to provision a Cloud Agent with received token.
      • iOS - agentProvisionWithToken
      • Android - UtilsApi.vcxAgentProvisionWithToken
    • Store received JSON config for the next usages.
    • Call VCX function to initialize library with JSON config.
      • iOS - initWithConfig
      • Android - VcxApi.vcxInitWithConfig
  3. On second and other application runs:
    • Read provisioned JSON config received after first application init.
    • Call VCX function to initialize library with prepared JSON config.
      • iOS - initWithConfig
      • Android - VcxApi.vcxInitWithConfig

Referenced implementation of Initialization steps in the sample applications

iOS

Refer to AppDelegate.m.

Android

  1. Pool genesis transaction using for Ledger connection can be found here.
    This configuration targets Production network.
    In case your app works with another network, corresponding genesis transaction files for different environment could be found here. Genesis transaction should be saved on a filesystem and be accessible to libVcx. For sample, writeGenesisFile().

  2. Selected Agency and other application configuration settings can be found here.

  3. On first init (if you don't have populated JSON config) following steps should be performed:

    1. Configure application file system permissions. See configureStoragePermissions function.

    2. Configure application logger. SeeconfigureLogger function.

    3. Generate wallet key. See createWalletKey() function.

    4. Prepare configuration JSON (see config sample).

    5. Call Sponsor server backend API to get provision token. See retrieveToken()

    6. Call UtilsApi.vcxAgentProvisionWithTokenAsync function with prepared config to provision a Cloud Agent.

    7. Resulting JSON must be stored for latter usage. This JSON will be used to initialize libVcx.

    8. Call VcxApi.vcxInitWithConfig function with JSON received after provisioning to initialize library.

  4. On second and other application initializations skip provisioning and do library initialization with previously stored config.

    1. Fetch config (generated on the step 3 during the first application launch) from the storage.

    2. Call VcxApi.vcxInitWithConfig function with JSON received after provisioning to initialize library.

NOTE: If the initialization of the wallet does not work after you followed these steps, please contact Evernym. If you had to do extra steps to get it working, please also let us know what you had to do so that we can update this document.

Errors you might see while calling provision functions

  • GNR-115: This statusCode is returned when your sponsor details are not saved on agency which you are trying to use. To resolve this problem, send an email as described in section Sponsor (i.e You) onboarding above in this file.
  • GNR-117: This statusCode tells that the provisioningToken is already used. So, app should call your Sponsor token endpoint, and get a new provisioning token. Then call agentProvisionToken again with new token.
  • Provision Agent Error: Error Creating a wallet
    Caused by: Could not create wallet ...: "Error: IO error Caused by: Operation not permitted (os error 1)"
    
    The error relates to application permissions. MSDK tries to create .indy_sdk folder in android external storage but gets IO error. The issue should be solved by adding Os.setenv("EXTERNAL_STORAGE", Utils.getRootDir(config.context), true); into some place before provisioning step.

Selecting the Ledger and Cloud Service

Pool Ledger

The Indy-based Pool Ledgers Networks represent a publicly available distributed storages using for storing entities used for verifiable credential exchange.

There are different Ledgers you may use (see Pool Genesis Transactions value):

  • demo: for testing purposes during development and testing.
  • prod: production environment, for app releases in AppStores.

Use the Pool Genesis Transactions value in the particular environment to prepare a file with Pool Genesis Transactions. The path to this file will be used as genesis_path parameter of SDK provisioning config.

You also can use different available Indy Pool Ledgers. In the same way, you just need to store their Genesis Transactions into a file and use the path to the file in the library config.

Evernym Cloud Service

As we already mentioned before Evernym Cloud Service is used for provisioning of Cloud Agents.

There are different Evernym Cloud Services you may use (see Agency* values):

  • demo: for testing purposes during development and testing.
  • prod: production environment, for app releases in AppStores.

Use Agency Url, Agency DID, and Agency Verification Key values in the particular environment to prepare agency_did, agency_endpoint, and agency_verkey fields in the SDK initialization config.

SDK provisioning config sample (single Pool Ledger)

{
  // These fields are used for agency configuration
  "agency_endpoint": "http://agency.pps.evernym.com", // URL of agency to use
  "agency_did": "3mbwr7i85JNSL3LoNQecaW", // DID of agency
  "agency_verkey": "2WXxo6y1FJvXWgZnoYUP5BJej2mceFrqBDNPE3p6HDPf", // Verification key of the agency

  //These fields are used for wallet configuration
  "wallet_name": "wallet-name-wwwww-wallet",  // Name of the wallet
  "wallet_key": "viM/BUU7I+Ypn+AdXAIQUAGX59pteVzau7Z7Jv3Ll6nzmYsSHrFqRdT71tjoMhTPRM2uSnqt8tDTSOLMP1KVf0fl1uP/dPsWu7cjucMsqfK8ohb92amhAWnNn+8s8UWC5owLN3EXZuilqYtjtRZtRUm/hhK5ycQ/OuxMgNPpfUQ=", // Key of the wallet

  // Communication Protocol
  "protocol_type": "4.0", // Type of the protocol

  // Pool Ledger
  "genesis_path": "/data/user/0/me.connect.sdk.java.sample/files/connectMeVcx/pool_transactions_genesis", // path to file containing pool genesis transactions

  // User Meta
  "logo": "https://robothash.com/logo.png", // url leading to image
  "name": "real institution name" // name to use
}

Multi Pool Ledger Connection

In most cases it is enough to have a connection only to one specific Pool Ledger Network. But in some cases it can be useful to work with multiple Pool Ledger Netoworks at the same time. For example, there is several organisations running their own Indy Pool Ledger Networks, and you want to make your application able to work with each of them at the same time.

In order to achieve this goal you need to specify multiple Pool Ledgers (using pool_networks field) in the library configuration JSON. When the library is need to get some public information from the ledger (like schema or credential definition) it will query all connection ledger for this data.

SDK provisioning config sample (multiple Pool Ledgers)

{
  // These fields are used for agency configuration
  "agency_endpoint": "http://agency.pps.evernym.com", // URL of agency to use
  "agency_did": "3mbwr7i85JNSL3LoNQecaW", // DID of agency
  "agency_verkey": "2WXxo6y1FJvXWgZnoYUP5BJej2mceFrqBDNPE3p6HDPf", // Verification key of the agency

  //These fields are used for wallet configuration
  "wallet_name": "wallet-name-wwwww-wallet",  // Name of the wallet
  "wallet_key": "viM/BUU7I+Ypn+AdXAIQUAGX59pteVzau7Z7Jv3Ll6nzmYsSHrFqRdT71tjoMhTPRM2uSnqt8tDTSOLMP1KVf0fl1uP/dPsWu7cjucMsqfK8ohb92amhAWnNn+8s8UWC5owLN3EXZuilqYtjtRZtRUm/hhK5ycQ/OuxMgNPpfUQ=", // Key of the wallet

  // Communication Protocol
  "protocol_type": "4.0", // Type of the protocol

  // Pool Ledger
  "indy_pool_networks": [
    {
      'genesis_path': '/data/user/0/me.connect.sdk.java.sample/files/connectMeVcx/pool_transactions_genesis',
      'namespace_list': ['demo']
    },
    {
      'genesis_path': '/data/user/0/me.connect.sdk.java.sample/files/connectMeVcx/pool_transactions_genesis_dev',
      'namespace_list': ['dev']
    },
    {
      'genesis_path': '/data/user/0/me.connect.sdk.java.sample/files/connectMeVcx/pool_transactions_genesis_live',
      'namespace_list': ['live']
    }
  ],
  
  // User Meta
  "logo": "https://robothash.com/logo.png", // url leading to image
  "name": "real institution name" // name to use
}

Logging

Android

Android SDK uses slf4j logging library.
Sample of configuration to store SDK logs in specified file could be found here.
For additional information about logging configuration see slf4j documentation.

iOS

iOS sdk provides VcxLogger setLogger function accepting a callback which will be called to log records inside SDK.

[VcxLogger setLogger: ^(NSObject *context, NSNumber *level, NSString *target, NSString *message, NSString *modulePath, NSString *file, NSNumber *line) {
    NSLog(@"[Inside VcxLogger.setLogger callback] %@    %@:%@ | %@", [levelMappings valueForKey: [NSString stringWithFormat: @"%@", level]], file, line, message);
}];

Next Step

Congratulations! Now your application initialized and obtained their Cloud Agent. You are ready to read how to receive message from the Cloud Agent.