npm package: @notabene/nodejs
Description: Client for Notabene's API
Author: Notabene
Latest version: 1.19.0

<div align="center">

<img src="https://assets-global.website-files.com/5e68f0772de982756aa8c1a4/5eee5fb470215e6ecdc34b94_Full_transparent_black_1280x413.svg" height=50>

<br>

# Notabene NodeJS SDK

[![pipeline status](https://gitlab.com/notabene/open-source/notabene-nodejs/badges/master/pipeline.svg)](https://gitlab.com/notabene/open-source/notabene-nodejs/-/commits/master)
[![Latest Release](https://gitlab.com/notabene/open-source/notabene-nodejs/-/badges/release.svg)](https://gitlab.com/notabene/open-source/notabene-nodejs/-/releases)

Notabene NodeJS SDK for sending and receiving transactions through the Notabene Travel Rule gateway.

[Documentation](https://devx.notabene.id) •
[Getting started](#getting-started) •
[Installation](#installation) •
[Configuration](#configuration)

</div>

## Getting Started

### Step 1: Install the library

```
npm install @notabene/nodejs
```

### Step 2: Initialize the client

```javascript
const { Notabene } = require('@notabene/nodejs');

const client = new Notabene({
  clientId: '{CLIENT_ID}', // Add your own client ID
  clientSecret: '{CLIENT_SECRET}', // Add your own client secret
});
```

## Configuration

### Client ID and Client Secret

The client ID and client secret required to authenticate against Notabene's APIs must be requested.

### Test environment

For sending transactions to Notabene's test environment, use your test Client ID and Client Secret and
set the `baseURL` and `audience` to `https://api.notabene.dev`.

```javascript
const { Notabene } = require('@notabene/nodejs');

const client = new Notabene({
  baseURL: 'https://api.notabene.dev',
  audience: 'https://api.notabene.dev',
  clientId: '{CLIENT_ID}', // Add your own client ID
  clientSecret: '{CLIENT_SECRET}', // Add your own client secret
});
```

## VASP methods

- `client.trustFramework.get(...)` get properties of a VASP
- `client.trustFramework.list(...)` get a list of VASPs
- `client.trustFramework.update(...)` update properties of your VASP

## Transaction methods

- `client.transaction.create(...)` create a new outgoing transaction (see details below)
- `client.transaction.get(...)` get transaction by id (see details below)
- `client.transaction.update(...)` update transaction (see details below)
- `client.transaction.list(did)` retrieve a list of transactions
- `client.transaction.approve(id)` approve a transaction by ID
- `client.transaction.cancel(id)` cancel a transaction by ID
- `client.transaction.confirm(id)` confirm a transaction by ID
- `client.transaction.reject(id)` reject a transaction by ID
- `client.transaction.notReady(id)` mark transaction as Not Ready by ID
- `client.transaction.accept(id)` accept a transaction by ID
- `client.transaction.decline(id)` decline a transaction by ID
- `client.transaction.notify(...)` create an empty incoming transaction
- `client.transaction.redirect(fromDID, toDID)` redirect transaction
- `client.transaction.verifyMessage(signature, message, address)` Verify a signature (for beneficiary ownership proof)

## Creating Transactions

Examples for `ivms` and `payload` variables can be found in the Appendix.

### Create a Basic Transaction

```javascript
const ivms = ...; // (see Appendix)
const payload = ...; // (see Appendix)

const txCreated = await client.transaction.create(payload);
```

### Create an "End-2-End Encrypted" Transaction

E2E encryption method will encryt PII that such that only you and the beneficiary VASP

```javascript
const ivms = ...; // (see Appendix)
const payload = ...; // (see Appendix)
const jsonDIDKey = ...; // create or import a jsonDIDKey (see below)

const txCreated = await client.transaction.create(
  payload,
  jsonDIDKey
);
```

### Hybrid Encryption

The hybrid encryption method will also encrypt the PII data to Notabene, using a unique managed Escrow Key for your VASP. This allows us to run **sanction screening** on the PII data.

```javascript
const txCreated = await client.transaction.create(
  payload,
  jsonDIDKey,
  true // hybrid
);
```

### JsonDIDKey

For `END_2_END` and `HYBRID` encryption your VASP needs a dedicated DIDKey, which is a public-private keypair. You can create a new keypair using the [`@notabene/cli`](https://www.npmjs.com/package/@notabene/cli) and then publish it to the Notabene directory under the `pii_didkey` field. This allows other VASPs retrieve your public key and encrypt PII data to you.

```javascript
// get your encryption key
const ikey = ... // or create a new key using the CLI, or: await client.toolset.createKey();

// extract the did:key (public key)
const pii_didkey = JSON.parse(ikey).did;

// upload did:key to your VASP on the Notabene directory
const fields = [
  {
    fieldName: 'pii_didkey',
    values: [
      {
        value: pii_didkey,
      },
    ],
  },
];
await client.trustFramework.update(vaspDID, fields);
```

Typically you will do this only once, and re-use the same keypair for a long time. If you believe your private key was compromised, you can rotate your keypair (ie. create a new one + publish it again). Data encrypted using a specific public key can only be decrypted with its private key, so don't throw away your old key(s) if you still have data of interest encrypted with those key(s).

## Retrieving transactions

To retrieve a transaction simply call:

```javascript
const txInfo = await client.transaction.get(id);
```

If the transaction was encrypted with the `HOSTED` (default) or `HYBRID` strategy, the PII Service will be able to decrypt it for you, the `ivms101` property will contain the decrypted data. However, for `END_2_END` encrypted data you can pass your `jsonDIDKey` argument to decrypt it locally:

```javascript
const txInfo = await client.transaction.get(id, jsonDIDKey);
```

## Updating transactions

To update a transaction simply call the following with the fields you wish to update:

```javascript
const updatedTx = await client.transaction.update({
  id: txCreated.id,
  beneficiaryVASPdid: '...',
});
```

Note, you need specify an encryption method just like in `transaction.create` (and your `jsonDIDKey`):

```javascript
const updatedTxEnd2End = await client.transaction.update(
  { id: txCreated.id, beneficiaryVASPdid: '...' },
  jsonDIDKey // for END_2_END | HYBRID
  // false | true
);
```

## Appendix

### txCreate example

```javascript
// transaction.create payload:
const payload = {
  transactionAsset: 'ETH',
  transactionAmount: '1111111000000000000',
  originatorVASPdid: 'did:ethr:0xb086499b7f028ab7d3c96c4c2b71d7f24c5a0772',
  beneficiaryVASPdid: 'did:ethr:0xa80b54afa45dc22a4ebc0e1a9b638998a7899c33',
  transactionBlockchainInfo: {
    origin: '0x123',
    destination: '0x321',
  },
  originator: ivms.originator,
  beneficiary: ivms.beneficiary,
};
```

### IVMS101 example

```javascript
const ivms = {
  originator: {
    originatorPersons: [
      {
        naturalPerson: {
          name: [
            {
              nameIdentifier: [
                {
                  primaryIdentifier: 'Frodo',
                  secondaryIdentifier: 'Baggins',
                  nameIdentifierType: 'LEGL',
                },
              ],
            },
          ],
          nationalIdentification: {
            nationalIdentifier: 'AABBCCDDEEFF0011223344',
            nationalIdentifierType: 'CCPT',
            countryOfIssue: 'NZ',
          },
          dateAndPlaceOfBirth: {
            dateOfBirth: '1900-01-01',
            placeOfBirth: 'Planet Earth',
          },
          geographicAddress: [
            {
              addressLine: ['Cool Road /-.st'],
              country: 'BE',
              addressType: 'HOME',
            },
          ],
        },
      },
    ],
    accountNumber: ['01234567890'],
  },

  beneficiary: {
    beneficiaryPersons: [
      {
        naturalPerson: {
          name: [
            {
              nameIdentifier: [
                {
                  primaryIdentifier: 'Bilbo',
                  secondaryIdentifier: 'Bolson',
                  nameIdentifierType: 'LEGL',
                },
              ],
            },
          ],
        },
      },
    ],
    accountNumber: ['01234567890'],
  },
};
```

## [License](LICENSE.md)

BSD 3-Clause © Notabene Inc.