npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@notabene/javascript-sdk

v2.0.0

Published

JavaScript SDK for Notabene

Downloads

7,324

Readme

pipeline status npm version npm downloads Bundle Size Types License Dependencies

This library is the JavaScript SDK for loading the Notabene UX components in the front-end.

Additional Documentation

Table of Contents

Installation

There are two options for loading the Notabene SDK:

<script id="notabene" async src="https://unpkg.com/@notabene/javascript-sdk@next/dist/notabene.js"></script>

Or installing the library:

Using Yarn:

yarn add @notabene/javascript-sdk

Using NPM:

npm install @notabene/javascript-sdk

If you installed the library into your project, you can import it into your project:

import Notabene from '@notabene/javascript-sdk';

Quick Start

// 1. Create Notabene instance
const notabene = new Notabene({
  nodeUrl: 'https://api.notabene.id',
  authToken: 'YOUR_CUSTOMER_TOKEN'
});

// 2. Create and mount withdrawal component
const withdrawal = notabene.createWithdrawalAssist({
  asset: 'ETH',
  destination: '0x1234...',
  amountDecimal: 1.0
});
withdrawal.mount('#nb-withdrawal');

// 3. Handle completion
const { valid, value, txCreate } = await withdrawal.completion();
if (valid) {
  // Submit to your backend
}

Core Concepts

Authentication

Use the customer token endpoint with your access token to receive a token with a customer's scope.

⚠️ IMPORTANT ⚠️

When requesting the customer token you must pass a unique customerRef per customer for ownership proof reusability, otherwise you might encounter unwanted behavior.

Create a new Notabene instance:

const notabene = new Notabene({
  nodeUrl: 'https://api.notabene.id', // use `https://api.notabene.dev` for testing
  authToken: '{CUSTOMER_TOKEN}',
  locale: 'de', // default locale = `en`
});

Use the same nodeUrl that you use to interact with the Notabene API.

General Component Usage

Each component can be used in various ways depending on your use case.

Embedded Component

This will let you embed the component into your existing withdrawal flow.

Create an html element to contain the component:

<div id="nb-withdrawal/>

Instantiate the withdrawal element and mount it using the id from above

const withdrawal = notabene.createWithdrawalAssist(tx, options);
withdrawal.mount('#nb-withdrawal');

The simplest way to get the result is to use:

try {
  const { valid, value, txCreate, ivms101, proof } =
    await withdrawal.completion();
  if (valid) {
    // Submit result to your backend
  }
} catch (e) {
  console.error(e);
}

Dynamic updates

To update the component as users enter transaction details:

withdrawal.update({
  asset: 'ETH',
  destination: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
  amountDecimal: 1.12,
});

To be notified once the validation is completed so you can submit the withdrawal to your back end:

withdrawal.on('complete', { valid, value, txCreate, ivms101, proof } => ...)

To be notified of any validation errors use:

withdrawal.on('error',error => ...)

Calling on returns a function that will allow you to cleanly unsubscribe.

const unsubscribe = withdrawal.on('complete', { valid, value, txCreate, ivms101, proof } => ...)

// Clean up
unsubscribe()

Modal

All components support being opened in a modal using openModal(), which returns a promise.

const withdrawal = notabene.createWithdrawalAssist(tx, options);
try {
  const { valid, value, txCreate, ivms101, proof } =
    await withdrawal.openModal();
  if (valid) {
    // Submit result to your backend
  }
} catch (e) {
  console.error(e);
}

Linked Component

In some cases, in particular institutional or mobile apps you may prefer to link your customers to the component through an email or redirect the user to it in a mobile app.

const withdrawal = notabene.createWithdrawalAssist(tx, options, {
  callback: /// a serverside backend url
  redirectUri: // URI of website or mobile app to redirect user to after completion
});

// NodeJS redirect. Link also works in an email.
res.redirect(withdrawal.url);

Bear in mind that this is a full screen view for your users.

The two parameters that should be configured are:

  • callback - a URL for your serverside. On completion this will receive an HTTP POST with the result as a json body and the authToken as an Authorization: Bearer header.
  • redirectUri - the user will be redirected here on completion. The result parameters will be json encoded in the URL fragment. You can use a mobile app schema to intercept these in your mobile app.

Note for data privacy reasons the callback will be coming from your users web browser and not from our infrastructure, so no static IP is currently possible. Instead please check the authToken provided with the request.

Components

Assisted Withdrawal

The Withdrawal Assist component helps you collect additional required information from your user during a standard crypto withdrawal process.

const withdrawal = notabene.createWithdrawalAssist({
  asset: 'ETH',
  destination: '0x...',
  amountDecimal: 1.23,
  assetPrice: {
    currency: 'USD', // ISO currency code
    price: 1700.12, // Asset price
  }
});

Parameters

  • asset: The cryptocurrency or token being transferred. See Asset Specification
  • destination: The destination or blockchain address for the withdrawal. See Destination
  • amountDecimal: The amount to transfer in decimal format. See Transaction Amount
  • assetPrice: Optional price information in a fiat currency. See Asset Price

If any of the required parameters are missing the component will just show the Notabene badge.

Configuration Options

Include configuration Options as a second optional parameter:

const withdrawal = notabene.createWithdrawalAssist({
  asset: 'ETH',
  destination: '0x...',
  amountDecimal: 1.23,
  assetPrice: {
    currency: 'USD', // ISO currency code
    price: 1700.12, // Asset price
  }
}, {
  proofs: {
    microTransfer: {
      destination: '0x...',
      amountSubunits: '12344',
      timeout: 86440,
    }
  }
});

See Transaction Options

Connect Wallet

The Connect Wallet component helps you collect and verify the address of your users self-hosted wallet in one go.

const connect = notabene.createConnectWallet({
  asset: 'ETH'
});

const { proof, txCreate } = await connect.openModal()

Parameters

Configuration Options

Include configuration Options as a second optional parameter:

const connect = notabene.createConnectWallet({
    asset: 'ETH',
  }, {
  proofs: {
    microTransfer: {
      destination: '0x...',
      amountSubunits: '12344',
      timeout: 86440,
    }
  }
});

Deposit Request

The Deposit Request lets your customers request deposits that are fully Travel Rule compliant.

const withdrawal = notabene.createDepositRequest({
  asset: 'ETH',
  destination: '0x...',
  amountDecimal: 1.23,
  customer: {
    name: "John Smith"
  }
});

Parameters

  • asset: The cryptocurrency or token being transferred. See Asset Specification
  • destination: The destination or blockchain address for the withdrawal. See Destination
  • amountDecimal: Optional amount to deposit in decimal format. See Transaction Amount
  • customer: Optional Customer object containing their name

If any of the required parameters are missing the component will just show the Notabene badge.


Error handling

If any error occurs, the error event is passed containing a message.

withdrawal.on('error', {message} => ...)

Transaction parameters

Asset specification

The asset field the following types of assets specified:

  • notabene_asset code passed as astring. See Notabene Assets Service.
  • CAIP-19 is a chain agnostic format allows you to support the widest amount of assets and blockchains including NFTs.
  • DTI is the ISO Digital Token Identifier format. See DTI registry for supported tokens.

Transaction amount

Use one of the following

  • amountDecimal A number specifying the amount in decimal format. Eg. amountDecimal=1.1 would mean 1.1 of for example BTC or ETH.

Destination

Specify the beneficiary address as destination using one of the following formats:

  • CAIP-10 is a chain agnostic format allows you to specify the specific blockchain and address
  • EIP-3770 EVM URI
  • BIP-21 Bitcoin URI
  • Native blockchain address

Asset Price

The price of the asset is used to determine certain rules based on thresholds. We recommond you pass in your price like this:

assetPrice: {
  currency: 'USD', // ISO currency code
  price: 1700.12, // Asset price
};

Configuration

Transaction Options

Some components can be configured using an optional TransactionOptions object.

The following shows the full set of options in typescript:

import Notabene, {
  AgentType,
  PersonType,
  ProofTypes,
} from '@notabene/javascript-sdk';

const options: TransactionOptions = {
  proofs: {
    microTransfer: {
      destination: '0x...',
      amountSubunits: '12344',
      timeout: 86440,
    },
    fallbacks: [ProofTypes.Screenshot, ProofTypes.SelfDeclaration], // js ['screenshot','self_declaration']
    deminimis: {
      threshold: 1000,
      currency: 'EUR',
      proofTypes: [ProofTypes.SelfDeclaration]
    }
  },
  allowedAgentTypes: [AgentType.PRIVATE, AgentType.VASP], // js ['WALLET','VASP']
  allowedCounterpartyTypes: [
    PersonType.LEGAL, // JS: 'legal'
    PersonType.NATURAL, // JS: 'natural'
    PersonType.SELF, // JS: 'self'
  ],
  fields: {
    naturalPerson: {
      name: true, // Default true
      website: { optional: true },
      email: true,
      phone: true,
      geographicAddress: false,
      nationalIdentification: false,
      dateOfBirth: false,
      placeOfBirth: false,
      countryOfResidence: true,
    },
    legalPerson: {
      name: true, // Default true
      lei: true, // Default true
      website: { optional: true }, // Default true
      email: true,
      phone: true,
      geographicAddress: false,
      nationalIdentification: false,
      countryOfRegistration: true,
    },
    vasps: {
      addUnknown: true, // Allow users to add a missing VASP - Defaults to false
      onlyActive: true, // Only list active VASPs - Default false
    },
    hide: [ValidationSections.ASSET, ValidationSections.DESTINATION] // Don't show specific sections of component
  },
};
const withdrawal = notabene.createWithdrawalAssist(tx, options);

The options can additionally be updated dynamically with the update() function.

withdrawal.update({
  asset: 'ETH',
  destination: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
  amountDecimal: 1.12,
}, {
  proofs: {
    microTransfer: {
      destination: '0x...',
      amountSubunits: '12344',
      timeout: 86440,
    }
  }
});

Common use cases

Only allow first party transactions

const firstParty: TransactionOptions = {
  allowedCounterpartyTypes: [
    PersonType.SELF, // JS: 'self'
  ],
};

Only VASP to VASP transactions

const vasp2vasp: TransactionOptions = {
  allowedAgentTypes: [AgentType.VASP], // js ['VASP']
};

Only Self-hosted wallet transactions

const options: TransactionOptions = {
  allowedAgentTypes: [AgentType.PRIVATE], // js ['WALLET']
};

Configuring ownership proofs

By default components support message signing proofs.

Supporting Micro Transactions (aka Satoshi tests)

You can support Micro Transfers (aka Satoshi tests) by adding a deposit address for the test.

Your compliance team will have to determine how to handle and verify these transactions in the rules engine or individually.

const options: TransactionOptions = {
  proofs: {
    microTransfer: {
      destination: '0x...',
      amountSubunits: '1234',
      timeout: 86440, // Optional timeout in seconds, which is displayed to the user
    },
    fallbacks: [ProofTypes.Screenshot, ProofTypes.SelfDeclaration], // js ['screenshot','self_declaration']
  },
};

Notabene does not currently verify these tests automatically as you likely already have the infrastructure to do so.

You will receive a response back from the component containing a proof object. For MicroTransfers it will look like this:

type MicroTransferProof {
  type: ProofTypes.MicroTransfer;
  status: ProofStatus.PENDING;
  did: DID;
  address: CAIP10; // CAIP10 account to be verified
  txhash: string; // Transaction Hash to verify
  chain: CAIP2; // CAIP2 identifier of blockchain
  amountSubunits: string; // Amount in subunits eg (satoshi or wei) to be verified
}

Fallback Proof Options

You may accept a few options if none of the other are available. We do not recommend them, as they do not provide sufficient proof. However many VASPs do allow them for now:

const options: TransactionOptions = {
  proofs: {
    fallbacks: [ProofTypes.Screenshot, ProofTypes.SelfDeclaration], // js ['screenshot','self_declaration']
  },
};

The two options are:

  • screenshot Where a user is requested to upload a screenshot of their wallet
  • self-declaration Where a user self declares that they control the wallet address

Counterparty Field Properties

The fields requested from a customer about a counterparty can be configured with the fields object. You can configure required and optional fields individually for both natural and legal persons.

We recommend working closely with your compliance team for this. Bearing in mind that different jurisdictions have different rules.

Each field can be configured like this:

  • true required field
  • false don't show
  • { optional: true } show but don't require

Eg:

{
  naturalPerson: {
    website: { optional: true },
    email: true,
    phone: false,
  }
}

The above will always ask the user for the following for natural persons:

  • name since it is on by default (you can disable it explicitly by setting it to false)
  • website is show but is optional
  • email is required

Full Example

const options: TransactionOptions = {
  fields: {
    naturalPerson: {
      name: true, // Default true
      website: { optional: true },
      email: true,
      phone: true,
      geographicAddress: false,
      nationalIdentification: false,
      dateOfBirth: {
        transmit: true,
      },
      placeOfBirth: false,
      countryOfResidence: true,
    },
    legalPerson: {
      name: true, // Default true
      lei: true, // Default true
      website: { optional: true }, // Default true
      email: true,
      phone: true,
      geographicAddress: false,
      nationalIdentification: false,
      countryOfRegistration: true,
    },
  },
};

Field reference

| Field name | Natural | Legal | IVMS101 | description | | ------------------------ | ------- | ----- | ------- | --------------------------------------------- | | name | ✅ | ✅ | 🟩 | Full name | | email | 🟩 | 🟩 | -- | Email (for your internal purposes) | | website | -- | ✅ | -- | Business Website (for your internal purposes) | | phone | 🟩 | 🟩 | -- | Mobile Phone (for your internal purposes) | | geographicAddress | 🟩 | 🟩 | 🟩 | Residencial or business address | | nationalIdentification | 🟩 | 🟩 | 🟩 | National Identification number | | dateOfBirth | 🟩 | -- | 🟩 | Date of birth | | placeOfBirth | 🟩 | -- | 🟩 | Place of birth | | countryOfResidence | 🟩 | -- | 🟩 | Country of Residence | | lei | -- | ✅ | 🟩 | LEI (Legal Entity Identifier) | | countryOfRegistration | -- | 🟩 | 🟩 | Country of Registration |

Locales

See locales for the list of supported locales.

License

MIT © Notabene Inc.