@notabene/javascript-sdk 1.34.0 → 2.0.0-RC

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +500 -259
  3. package/dist/{es/index.js → js/notabene.js} +1 -1
  4. package/dist/notabene.cjs +1 -0
  5. package/dist/notabene.d.ts +1565 -0
  6. package/dist/notabene.js +343 -0
  7. package/dist/tsdoc-metadata.json +11 -0
  8. package/package.json +50 -64
  9. package/src/__tests__/notabene.test.ts +270 -0
  10. package/src/components/EmbeddedComponent.ts +237 -0
  11. package/src/components/__tests__/EmbeddedComponent.test.ts +530 -0
  12. package/src/ivms/types.ts +232 -152
  13. package/src/locales.ts +47 -0
  14. package/src/notabene.ts +292 -288
  15. package/src/types.ts +1068 -78
  16. package/src/utils/MessageEventManager.ts +115 -0
  17. package/src/utils/__tests__/MessageEventManager.test.ts +119 -0
  18. package/src/utils/__tests__/urls.test.ts +112 -0
  19. package/src/utils/arbitraries.ts +244 -0
  20. package/src/utils/caip.ts +16 -0
  21. package/src/utils/urls.ts +40 -0
  22. package/.editorconfig +0 -10
  23. package/.envrc.template +0 -1
  24. package/.eslintignore +0 -3
  25. package/.eslintrc.js +0 -13
  26. package/.gitlab-ci.yml +0 -74
  27. package/.husky/commit-msg +0 -4
  28. package/.husky/pre-commit +0 -4
  29. package/.husky/pre-push +0 -4
  30. package/.nvmrc +0 -1
  31. package/.prettierrc +0 -4
  32. package/.releaserc.json +0 -16
  33. package/.tool-versions +0 -3
  34. package/.vscode/extensions.json +0 -7
  35. package/.vscode/settings.json +0 -11
  36. package/CODEOWNERS +0 -1
  37. package/dist/lib/index.js +0 -376
  38. package/jest.config.js +0 -5
  39. package/public/index.html +0 -93
  40. package/src/lib/index.ts +0 -2
  41. package/src/module/index.ts +0 -10
  42. package/src/zoidComponentProps.ts +0 -81
  43. package/tsconfig.json +0 -18
  44. /package/{public/js/.gitkeep → src/arbitraries.ts} +0 -0
package/README.md CHANGED
@@ -2,32 +2,49 @@
2
2
 
3
3
  <img src="https://assets-global.website-files.com/5e68f0772de982756aa8c1a4/5eee5fb470215e6ecdc34b94_Full_transparent_black_1280x413.svg" height=50>
4
4
  <br>
5
+ # Notabene SafeConnect Components JavaScript SDK
5
6
 
6
- # JavaScript SDK
7
+ [![pipeline status](https://gitlab.com/notabene/open-source/javascript-sdk/badges/v2/pipeline.svg)](https://gitlab.com/notabene/open-source/javascript-sdk/-/commits/v2)
8
+ [![npm version](https://img.shields.io/npm/v/@notabene/javascript-sdk.svg)](https://www.npmjs.com/package/@notabene/javascript-sdk)
9
+ [![npm downloads](https://img.shields.io/npm/dm/@notabene/javascript-sdk.svg)](https://www.npmjs.com/package/@notabene/javascript-sdk)
10
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/@notabene/javascript-sdk)](https://bundlephobia.com/package/@notabene/javascript-sdk)
11
+ [![Types](https://img.shields.io/npm/types/@notabene/javascript-sdk)](https://www.npmjs.com/package/@notabene/javascript-sdk)
12
+ [![License](https://img.shields.io/npm/l/@notabene/javascript-sdk)](https://gitlab.com/notabene/open-source/javascript-sdk/-/blob/main/LICENSE.md)
13
+ [![Dependencies](https://img.shields.io/librariesio/release/npm/@notabene/javascript-sdk)](https://libraries.io/npm/@notabene%2Fjavascript-sdk)
7
14
 
8
- [![pipeline status](https://gitlab.com/notabene/open-source/javascript-sdk/badges/master/pipeline.svg)](https://gitlab.com/notabene/open-source/javascript-sdk/-/commits/master)
9
- [![Latest Release](https://gitlab.com/notabene/open-source/javascript-sdk/-/badges/release.svg)](https://gitlab.com/notabene/open-source/javascript-sdk/-/releases)
15
+ This library is the JavaScript SDK for loading the Notabene UX components in the front-end.
10
16
 
11
- This library is the JavaScript SDK for loading the widget on a frontend.
12
-
13
- [Documentation](https://devx.notabene.id/docs/widget-v2) •
14
- [Installation](#installation)
17
+ [Additional Documentation](https://devx.notabene.id/docs/embedded=ux)
15
18
 
16
19
  </div>
17
20
 
21
+ ## Table of Contents
22
+
18
23
  - [Installation](#installation)
19
- - [Usage](#usage)
20
- - [Supported asset formats](#supported-asset-formats)
21
- - [Re-rendering](#re-rendering)
22
- - [Error handling](#error-handling)
23
- - [Customization](#customization)
24
- - [Functionality](#functionality)
25
- - [Pass the variables in the configuration](#pass-the-variables-in-the-configuration)
26
- - [Theme](#theme)
27
- - [Dictionary](#dictionary)
28
- - [Fields Properties](#fields-properties)
29
- - [Fallbacks](#fallbacks)
30
- - [Transaction Custom Asset Price](#transaction-custom-asset-price)
24
+ - [Quick Start](#quick-start)
25
+ - [Core Concepts](#core-concepts)
26
+ - [Authentication](#authentication)
27
+ - [General Component Usage](#general-component-usage)
28
+ - [Embedded Component](#embedded-component)
29
+ - [Dynamic updates](#dynamic-updates)
30
+ - [Modal](#modal)
31
+ - [Linked Component](#linked-component)
32
+ - [Components](#components)
33
+ - [Assisted Withdrawal](#assisted-withdrawal)
34
+ - [Connect Wallet](#connect-wallet)
35
+ - [Deposit Request](#deposit-request)
36
+ - [Error handling](#error-handling)
37
+ - [Transaction parameters](#transaction-parameters)
38
+ - [Asset specification](#asset-specification)
39
+ - [Transaction amount](#transaction-amount)
40
+ - [Destination](#destination)
41
+ - [Asset Price](#asset-price)
42
+ - [Configuration](#configuration)
43
+ - [Transaction Options](#transaction-options)
44
+ - [Common use cases](#common-use-cases)
45
+ - [Configuring ownership proofs](#configuring-ownership-proofs)
46
+ - [Counterparty Field Properties](#counterparty-field-properties)
47
+ - [Locales](#locales)
31
48
  - [License](#license)
32
49
 
33
50
  ## Installation
@@ -35,16 +52,53 @@ This library is the JavaScript SDK for loading the widget on a frontend.
35
52
  There are two options for loading the Notabene SDK:
36
53
 
37
54
  ```bash
38
- <script id="notabene" async src="https://unpkg.com/@notabene/javascript-sdk@1.31.0/dist/es/index.js"></script>
55
+ <script id="notabene" async src="https://unpkg.com/@notabene/javascript-sdk@next/dist/notabene.js"></script>
39
56
  ```
40
57
 
41
58
  Or installing the library:
42
59
 
60
+ Using Yarn:
61
+
62
+ ```bash
63
+ yarn add @notabene/javascript-sdk@next
64
+ ```
65
+
66
+ Using NPM:
67
+
43
68
  ```bash
44
- yarn add @notabene/javascript-sdk
69
+ npm install @notabene/javascript-sdk@next
70
+ ```
71
+
72
+ If you installed the library into your project, you can import it into your project:
73
+
74
+ ```js
75
+ import Notabene from '@notabene/javascript-sdk';
45
76
  ```
46
77
 
47
- ## Usage
78
+ ## Quick Start
79
+
80
+ ```js
81
+ // 1. Create Notabene instance
82
+ const notabene = new Notabene({
83
+ nodeUrl: 'https://api.notabene.id',
84
+ authToken: 'YOUR_CUSTOMER_TOKEN'
85
+ });
86
+
87
+ // 2. Create and mount withdrawal component
88
+ const withdrawal = notabene.createWithdrawalAssist({
89
+ asset: 'ETH',
90
+ destination: '0x1234...',
91
+ amountDecimal: 1.0
92
+ });
93
+ withdrawal.mount('#nb-withdrawal');
94
+
95
+ // 3. Handle completion
96
+ const { valid, value, txCreate } = await withdrawal.completion();
97
+ if (valid) {
98
+ // Submit to your backend
99
+ }
100
+
101
+ ## Core Concepts
48
102
 
49
103
  ### Authentication
50
104
 
@@ -58,347 +112,534 @@ Create a new Notabene instance:
58
112
 
59
113
  ```js
60
114
  const notabene = new Notabene({
61
- vaspDID: 'did:ethr:0x94c38fd29ef36f5cb2f7bc771f9d5bd9f7d05f27',
62
- widget: 'https://beta-widget.notabene.id',
63
- container: '#container',
115
+ nodeUrl: 'https://api.notabene.id', // use `https://api.notabene.dev` for testing
64
116
  authToken: '{CUSTOMER_TOKEN}',
65
- onValidStateChange: (isValid) => {
66
- // Use this value to determine if the transaction is ready to be created.
67
- console.log('is transaction valid', isValid);
68
- },
69
- onError: (err) => {
70
- // If any errors are encountered, they will be passed to this function
71
- alert(err.message);
72
- },
117
+ locale: 'de', // default locale = `en`
73
118
  });
74
119
  ```
75
120
 
76
- Then render the widget:
121
+ Use the same `nodeUrl` that you use to interact with the Notabene API.
77
122
 
78
- ```js
79
- // Use this method when you need to collect missing information from the sender about the recipient (normal withdrawal)
80
- notabene.renderWidget('WITHDRAWAL');
123
+ ## General Component Usage
81
124
 
82
- // Use this method when you need to collect missing information from the recipient about the sender (for transactions created via notification)
83
- notabene.renderWidget('POST_DEPOSIT');
84
- ```
125
+ Each component can be used in various ways depending on your use case.
85
126
 
86
- To update the widget as users enter transaction details:
127
+ ### Embedded Component
87
128
 
88
- ```js
89
- notabene.setTransaction({
90
- transactionAsset: 'ETH',
91
- beneficiaryAccountNumber: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
92
- transactionAmount: '2000000000',
93
- });
129
+ This will let you embed the component into your existing withdrawal flow.
130
+
131
+ Create an html element to contain the component:
132
+
133
+ ```html
134
+ <div id="nb-withdrawal/>
94
135
  ```
95
136
 
96
- Once the widget determines the transaction is valid, it will call the `onValidStateChange` callback, to access the transaction details:
137
+ Instantiate the withdrawal element and mount it using the id from above
97
138
 
98
139
  ```js
99
- const currentTransactionInfo = notabene.tx;
140
+ const withdrawal = notabene.createWithdrawalAssist(tx, options);
141
+ withdrawal.mount('#nb-withdrawal');
100
142
  ```
101
143
 
102
- ### Supported asset formats
144
+ The simplest way to get the result is to use:
103
145
 
104
- - `USDC` the simple asset code passed as a `string`, in case different chain (polygon) -> `USDC-POLY`
105
- - `CAIP19` format
106
- ```js
107
- {
108
- caip19: 'eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'; // for USDC
109
- }
110
- ```
111
- - `coingeckoId` and `network` format
112
- ```js
113
- {
114
- coingeckoId: "usd-coin",
115
- network: "ethereum"
146
+ ```js
147
+ try {
148
+ const { valid, value, txCreate, ivms101, proof } =
149
+ await withdrawal.completion();
150
+ if (valid) {
151
+ // Submit result to your backend
116
152
  }
117
- ```
153
+ } catch (e) {
154
+ console.error(e);
155
+ }
156
+ ```
118
157
 
119
- ---
158
+ #### Dynamic updates
120
159
 
121
- ### Re-rendering
160
+ To update the component as users enter transaction details:
122
161
 
123
- **WARNING:** this shouldn't be used often, if you need to change the transaction's initial fields call `setTransaction` again. (This should be used only for tearing down the component).
162
+ ```js
163
+ withdrawal.update({
164
+ asset: 'ETH',
165
+ destination: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
166
+ amountDecimal: 1.12,
167
+ });
168
+ ```
169
+
170
+ To be notified once the validation is completed so you can submit the withdrawal to your back end:
124
171
 
125
- The container of the widget must be in the DOM before calling `destroyWidget` or `renderWidget`.
172
+ ```js
173
+ withdrawal.on('complete', { valid, value, txCreate, ivms101, proof } => ...)
174
+ ```
126
175
 
127
- If you need to close and re-render the widget, call the `destroyWidget` method like so:
176
+ To be notified of any validation errors use:
128
177
 
129
178
  ```js
130
- // Will remove the widget
131
- notabene.destroyWidget();
132
- // Will re-render the widget
133
- notabene.renderWidget();
179
+ withdrawal.on('error',error => ...)
134
180
  ```
135
181
 
136
- Calling the `renderWidget` methods without destroying it first will not work.
182
+ Calling `on` returns a function that will allow you to cleanly unsubscribe.
137
183
 
138
- ---
184
+ ```js
185
+ const unsubscribe = withdrawal.on('complete', { valid, value, txCreate, ivms101, proof } => ...)
139
186
 
140
- ### Error handling
187
+ // Clean up
188
+ unsubscribe()
141
189
 
142
- If any error occurs, the `onError` function from the Notabene instance will be triggered. The `error` passed as argument contains a `data` property that has the following type `ErrorData`.
190
+ ```
143
191
 
144
- > ⚠️ **Note**: These errors are mainly used for debugging internal issues while implementing the widget. They are not meant to be shown directly to the end user.
192
+ ### Modal
193
+
194
+ All components support being opened in a modal using `openModal()`, which returns a promise.
145
195
 
146
196
  ```js
147
- type ErrorData = {
148
- title: string;
149
- detail: string;
150
- code: number;
151
- type: string;
152
- };
197
+ const withdrawal = notabene.createWithdrawalAssist(tx, options);
198
+ try {
199
+ const { valid, value, txCreate, ivms101, proof } =
200
+ await withdrawal.openModal();
201
+ if (valid) {
202
+ // Submit result to your backend
203
+ }
204
+ } catch (e) {
205
+ console.error(e);
206
+ }
207
+ ```
153
208
 
154
- const notabene = new Notabene({
155
- ...,
156
- onError: (err) => {
157
- const errorData = err.data;
158
209
 
159
- // Do something
160
- },
210
+ ### Linked Component
211
+
212
+ 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.
213
+
214
+ ```js
215
+ const withdrawal = notabene.createWithdrawalAssist(tx, options, {
216
+ callback: /// a serverside backend url
217
+ redirectUri: // URI of website or mobile app to redirect user to after completion
161
218
  });
219
+
220
+ // NodeJS redirect. Link also works in an email.
221
+ res.redirect(withdrawal.url);
162
222
  ```
163
223
 
164
- **Notabene Internal Errors**
224
+ Bear in mind that this is a full screen view for your users.
165
225
 
166
- Type | Code | Title | Detail
167
- -- | -- | -- | --
168
- `BAD_REQUEST` | `400` | `Bad Request` | `NotabeneBadRequest: ...`
169
- `TRANSACTION_INVALID` | `400` | `Transaction Invalid` | `NotabeneTransactionInvalid: ...`
170
- `TOKEN_INVALID` | `401` | `Token Invalid` | `NotabeneTokenInvalid: ...`
171
- `ASSET_NOT_SUPPORTED` | `404` | `Asset Not Supported` | `NotabeneAssetNotSupported: ...`
172
- `SERVICE_UNAVAILABLE` | `500` | `Service Unavailable` | `NotabeneServiceUnavailable: ...`
173
- `WALLET_CONNECTED_FAILED` | `500` | `Wallet Connection Failed` | `NotabeneWalletConnectionFailed: ...`
174
- `WALLET_NOT_SUPPORTED` | `501` | `Wallet Not Supported` | `NotabeneWalletNotSupported: ...`
226
+ The two parameters that should be configured are:
175
227
 
176
- ## Customization
228
+ - `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.
229
+ - `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.
177
230
 
178
- ### Functionality
231
+ **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.
179
232
 
180
- `transactionTypeAllowed`: `ALL` | `VASP_2_VASP_ONLY` | `SELF_TRANSACTION_ONLY`
181
233
 
182
- For limiting the type of transaction destinations you can pass.
234
+ ## Components
183
235
 
184
- `ALL`: All transaction destinations are allowed. (DEFAULT)
185
- `VASP_2_VASP_ONLY`: Only transaction destinations that are VASPs are allowed.
186
- `SELF_TRANSACTION_ONLY`: Only transaction destinations that the originator owns are allowed.
236
+ ## Assisted Withdrawal
187
237
 
188
- ---
238
+ The Withdrawal Assist component helps you collect additional required information from your user during a standard crypto withdrawal process.
239
+
240
+ ```js
241
+ const withdrawal = notabene.createWithdrawalAssist({
242
+ asset: 'ETH',
243
+ destination: '0x...',
244
+ amountDecimal: 1.23,
245
+ assetPrice: {
246
+ currency: 'USD', // ISO currency code
247
+ price: 1700.12, // Asset price
248
+ }
249
+ });
250
+ ```
251
+
252
+ ### Parameters
189
253
 
190
- `nonCustodialDeclarationType`: `SIGNATURE` | `DECLARATION`
254
+ - `asset`: The cryptocurrency or token being transferred. See [Asset Specification](#asset-specification)
255
+ - `destination`: The destination or blockchain address for the withdrawal. See [Destination](#destination)
256
+ - `amountDecimal`: The amount to transfer in decimal format. See [Transaction Amount](#transaction-amount)
257
+ - `assetPrice`: Optional price information in a fiat currency. See [Asset Price](#asset-price)
191
258
 
192
- For deciding which ownership proof type you want to use.
259
+ If any of the required parameters are missing the component will just show the Notabene badge.
193
260
 
194
- `SIGNATURE`: The ownership proof will be signed by the originator using a wallet. (DEFAULT)
195
- `DECLARATION`: The ownership proof will be declared by the originator using a checkbox.
261
+ ### Configuration Options
196
262
 
197
- ### Pass the variables in the configuration
263
+ Include configuration Options as a second optional parameter:
198
264
 
199
265
  ```js
200
- const notabene = new Notabene({
201
- vaspDID: 'did:ethr:0x94c38fd29ef36f5cb2f7bc771f9d5bd9f7d05f27',
202
- widget: 'https://beta-widget.notabene.id',
203
- container: '#container',
204
- authToken: '{CUSTOMER_TOKEN}'
205
- allowedTransactionTypes: 'VASP_2_VASP_ONLY',
206
- nonCustodialDeclarationType: 'DECLARATION',
266
+ const withdrawal = notabene.createWithdrawalAssist({
267
+ asset: 'ETH',
268
+ destination: '0x...',
269
+ amountDecimal: 1.23,
270
+ assetPrice: {
271
+ currency: 'USD', // ISO currency code
272
+ price: 1700.12, // Asset price
273
+ }
274
+ }, {
275
+ proofs: {
276
+ microTransfer: {
277
+ destination: '0x...',
278
+ amountSubunits: '12344',
279
+ timeout: 86440,
280
+ }
281
+ }
207
282
  });
208
283
  ```
209
284
 
210
- ---
211
-
212
- ### Theme
285
+ See [Transaction Options](#transaction-options)
213
286
 
214
- Pass a `theme` object when creating an instance
287
+ ## Connect Wallet
215
288
 
216
- Here you can pass configuration which will customize the styles of the widget to meet your brand needs, all values are optional.
289
+ The Connect Wallet component helps you collect and verify the address of your users self-hosted wallet in one go.
217
290
 
218
291
  ```js
219
- {
220
- primaryColor: '#fff',
221
- secondaryColor: '#fff',
222
- primaryFontColor: '#fff',
223
- secondaryFontColor: '#fff',
224
- backgroundColor: '#fff',
225
- fontFamily: Arial,
226
- logo: {LOGO_URL},
227
- mode: 'dark', // default: 'light'
228
-
229
- // If you are using the Signature flow, here is the full list of custom theme that can be applied to the WalletConnect Modal.
230
- '--w3m-font-family',
231
- '--w3m-font-feature-settings',
232
- '--w3m-overlay-background-color',
233
- '--w3m-overlay-backdrop-filter',
234
- '--w3m-z-index',
235
- '--w3m-accent-color',
236
- '--w3m-accent-fill-color',
237
- '--w3m-background-color',
238
- '--w3m-background-image-url',
239
- '--w3m-logo-image-url',
240
- '--w3m-background-border-radius',
241
- '--w3m-container-border-radius',
242
- '--w3m-wallet-icon-border-radius',
243
- '--w3m-wallet-icon-large-border-radius',
244
- '--w3m-wallet-icon-small-border-radius',
245
- '--w3m-input-border-radius',
246
- '--w3m-notification-border-radius',
247
- '--w3m-button-border-radius',
248
- '--w3m-secondary-button-border-radius',
249
- '--w3m-icon-button-border-radius',
250
- '--w3m-button-hover-highlight-border-radius',
251
- }
292
+ const connect = notabene.createConnectWallet({
293
+ asset: 'ETH'
294
+ });
295
+
296
+ const { proof, txCreate } = await connect.openModal()
252
297
  ```
253
298
 
254
- To get a list of supported fonts, visit [https://fonts.google.com/](https://fonts.google.com/)
299
+ ### Parameters
255
300
 
256
- To get more details about the WalletConnect theme variables, visit [General style variables](https://docs.walletconnect.com/2.0/web/web3modal/react/wagmi/theming#general-style-variables).
301
+ - `asset`: The cryptocurrency or token being transferred. See [Asset Specification](#asset-specification)
257
302
 
258
- ---
303
+ ### Configuration Options
259
304
 
260
- ### Dictionary
305
+ Include configuration Options as a second optional parameter:
261
306
 
262
- Pass a `dictionary` object mapping in text in the widget to your own language, for example:
307
+ ```js
308
+ const connect = notabene.createConnectWallet({
309
+ asset: 'ETH',
310
+ }, {
311
+ proofs: {
312
+ microTransfer: {
313
+ destination: '0x...',
314
+ amountSubunits: '12344',
315
+ timeout: 86440,
316
+ }
317
+ }
318
+ });
319
+ ```
320
+
321
+ ## Deposit Request
263
322
 
264
- To replace `Loading...` with `Cargando...`
323
+ The Deposit Request lets your customers request deposits that are fully Travel Rule compliant.
265
324
 
266
325
  ```js
267
- {
268
- 'Loading...': 'Cargando...',
269
- }
326
+ const withdrawal = notabene.createDepositRequest({
327
+ asset: 'ETH',
328
+ destination: '0x...',
329
+ amountDecimal: 1.23,
330
+ customer: {
331
+ name: "John Smith"
332
+ }
333
+ });
270
334
  ```
271
335
 
272
- ###### The property name must be the same as the text in the widget, for it to be replaced
336
+ ### Parameters
337
+
338
+ - `asset`: The cryptocurrency or token being transferred. See [Asset Specification](#asset-specification)
339
+ - `destination`: The destination or blockchain address for the withdrawal. See [Destination](#destination)
340
+ - `amountDecimal`: Optional amount to deposit in decimal format. See [Transaction Amount](#transaction-amount)
341
+ - `customer`: Optional Customer object containing their name
342
+
343
+ If any of the required parameters are missing the component will just show the Notabene badge.
273
344
 
274
345
  ---
275
346
 
276
- ### Fields Properties
347
+ ## Error handling
348
+
349
+ If any error occurs, the `error` event is passed containing a message.
277
350
 
278
- Possible fields customization support:
351
+ ```ts
352
+ withdrawal.on('error', {message} => ...)
353
+ ```
279
354
 
280
- | field name | `forceDisplay` | `optional` | description |
281
- | ------------------------ | -------------- | ---------- | ------------------------------------------------------- |
282
- | `counterparty` | -- | ☑️ | Counterparty VASP or Wallet (destination or originator) |
283
- | `dateAndPlaceOfBirth` | ☑️ | -- | Recipient (or Sender) Date and Place of Birth |
284
- | `geographicAddress` | ☑️ | ☑️ | Recipient (or Sender) Address |
285
- | `firstName` | ☑️ | -- | Recipient (or Sender) First name |
286
- | `name` | ☑️ | -- | Recipient (or Sender) Last Name / Company Name |
287
- | `nationalIdentification` | ☑️ | --️ | Recipient (or Sender) National Identification |
288
- | `country` | ☑️ | ☑️ | Recipient (or Sender) Country of Residence (for natural person) / Country of Registration (for legal person) |
355
+ ## Transaction parameters
289
356
 
290
- **Field Options**
357
+ ### Asset specification
291
358
 
292
- - **forceDisplay** - Force a field that is not required by your jurisdiction to be displayed - defaults to **false**
293
- - **optional** - Bypass the jurisdiction rules validation for that specific field - defaults to **false**
359
+ The `asset` field the following types of assets specified:
294
360
 
295
- ```js
296
- {
297
- counterparty: {
298
- optional: true;
361
+ - `notabene_asset` code passed as a`string`. See [Notabene Assets Service](https://devx.notabene.id/docs/coins-decimals#assets-service-api).
362
+ - [CAIP-19](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-19.md_) is a chain agnostic format allows you to support the widest amount of assets and blockchains including NFTs.
363
+ - [DTI](https://www.iso.org/standard/80601.html) is the ISO Digital Token Identifier format. See [DTI registry](https://dtif.org/registry-search/) for supported tokens.
364
+
365
+ ### Transaction amount
366
+
367
+ Use one of the following
368
+
369
+ - `amountDecimal` A number specifying the amount in decimal format. Eg. `amountDecimal=1.1` would mean 1.1 of for example BTC or ETH.
370
+
371
+ ### Destination
372
+
373
+ Specify the beneficiary address as `destination` using one of the following formats:
374
+
375
+ - [CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md_) is a chain agnostic format allows you to specify the specific blockchain and address
376
+ - [EIP-3770](https://eips.ethereum.org/EIPS/eip-3770) EVM URI
377
+ - [BIP-21](https://en.bitcoin.it/wiki/BIP_0021) Bitcoin URI
378
+ - Native blockchain address
379
+
380
+ ### Asset Price
381
+
382
+ The price of the asset is used to determine certain rules based on thresholds. We recommond you pass in your price like this:
383
+
384
+ ```ts
385
+ assetPrice: {
386
+ currency: 'USD', // ISO currency code
387
+ price: 1700.12, // Asset price
388
+ };
389
+ ```
390
+
391
+
392
+ ## Configuration
393
+
394
+ ### Transaction Options
395
+
396
+ Some components can be configured using an optional [TransactionOptions](./docs/types/interfaces/TransactionOptions.md) object.
397
+
398
+ The following shows the full set of options in typescript:
399
+
400
+ ```ts
401
+ import Notabene, {
402
+ AgentType,
403
+ PersonType,
404
+ ProofTypes,
405
+ } from '@notabene/javascript-sdk';
406
+
407
+ const options: TransactionOptions = {
408
+ proofs: {
409
+ microTransfer: {
410
+ destination: '0x...',
411
+ amountSubunits: '12344',
412
+ timeout: 86440,
413
+ },
414
+ fallbacks: [ProofTypes.Screenshot, ProofTypes.SelfDeclaration], // js ['screenshot','self_declaration']
415
+ deminimis: {
416
+ threshold: 1000,
417
+ currency: 'EUR',
418
+ proofTypes: [ProofTypes.SelfDeclaration]
419
+ }
299
420
  },
300
- geographicAddress: {
301
- forceDisplay: true,
302
- optional: true;
421
+ allowedAgentTypes: [AgentType.PRIVATE, AgentType.VASP], // js ['WALLET','VASP']
422
+ allowedCounterpartyTypes: [
423
+ PersonType.LEGAL, // JS: 'legal'
424
+ PersonType.NATURAL, // JS: 'natural'
425
+ PersonType.SELF, // JS: 'self'
426
+ ],
427
+ fields: {
428
+ naturalPerson: {
429
+ name: true, // Default true
430
+ website: { optional: true },
431
+ email: true,
432
+ phone: true,
433
+ geographicAddress: false,
434
+ nationalIdentification: false,
435
+ dateOfBirth: false,
436
+ placeOfBirth: false,
437
+ countryOfResidence: true,
438
+ },
439
+ legalPerson: {
440
+ name: true, // Default true
441
+ lei: true, // Default true
442
+ website: { optional: true }, // Default true
443
+ email: true,
444
+ phone: true,
445
+ geographicAddress: false,
446
+ nationalIdentification: false,
447
+ countryOfRegistration: true,
448
+ },
449
+ vasps: {
450
+ addUnknown: true, // Allow users to add a missing VASP - Defaults to false
451
+ onlyActive: true, // Only list active VASPs - Default false
452
+ },
453
+ hide: [ValidationSections.ASSET, ValidationSections.DESTINATION] // Don't show specific sections of component
303
454
  },
304
- }
455
+ };
456
+ const withdrawal = notabene.createWithdrawalAssist(tx, options);
305
457
  ```
306
458
 
307
- ---
459
+ The options can additionally be updated dynamically with the `update()` function.
308
460
 
309
- **_Beneficiary Details_ [DEPRECATED]**
461
+ ```js
462
+ withdrawal.update({
463
+ asset: 'ETH',
464
+ destination: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
465
+ amountDecimal: 1.12,
466
+ }, {
467
+ proofs: {
468
+ microTransfer: {
469
+ destination: '0x...',
470
+ amountSubunits: '12344',
471
+ timeout: 86440,
472
+ }
473
+ }
474
+ });
475
+ ```
310
476
 
311
- You can require specific beneficiary fields that are not required by your jurisdiction.
477
+ ### Common use cases
312
478
 
313
- Possible fields:
479
+ #### Only allow first party transactions
314
480
 
315
- - `beneficiaryName` - Recipient Name
316
- - `beneficiaryGeographicAddress` - Recipient Address
317
- - `beneficiaryNationalIdentification` - Recipient National Identification
318
- - `beneficiaryDateAndPlaceOfBirth` - Recipient Date and Place of Birth
481
+ ```ts
482
+ const firstParty: TransactionOptions = {
483
+ allowedCounterpartyTypes: [
484
+ PersonType.SELF, // JS: 'self'
485
+ ],
486
+ };
487
+ ```
319
488
 
320
- ```js
321
- beneficiaryDetails: [
322
- 'benficiaryName',
323
- 'beneficiaryGeographicAddress',
324
- 'beneficiaryNationalIdentification',
325
- 'beneficiaryDateAndPlaceOfBirth',
326
- ];
489
+ #### Only VASP to VASP transactions
490
+
491
+ ```ts
492
+ const vasp2vasp: TransactionOptions = {
493
+ allowedAgentTypes: [AgentType.VASP], // js ['VASP']
494
+ };
327
495
  ```
328
496
 
329
- ---
497
+ #### Only Self-hosted wallet transactions
330
498
 
331
- ### Fallbacks
499
+ ```ts
500
+ const options: TransactionOptions = {
501
+ allowedAgentTypes: [AgentType.PRIVATE], // js ['WALLET']
502
+ };
503
+ ```
332
504
 
333
- Fallbacks are custom options provided when desired outcome is not achieved
505
+ ### Configuring ownership proofs
334
506
 
335
- Possible options and actions:
507
+ By default components support message signing proofs.
336
508
 
337
- - `WALLET_NOT_SUPPORTED` - Performs one of the following options when wallet is not supported
338
- - `DECLARATION` - Falls back to the self declaration flow
339
- - `REJECT` - Rejects the transaction and throws an error
340
- - The error that will be thrown here will have the following structure
341
- ```js
342
- {
343
- "type": "WALLET_NOT_SUPPORTED",
344
- "title": "Wallet Not Supported",
345
- "status": 501,
346
- "detail": "We don't support the wallet for the provided asset"
347
- }
348
- ```
509
+ #### Supporting Micro Transactions (aka Satoshi tests)
349
510
 
350
- ```js
351
- fallbacks: [{flow: "WALLET_NOT_SUPPORTED", action: "DECLARATION"}]
511
+ You can support Micro Transfers (aka Satoshi tests) by adding a deposit address for the test.
512
+
513
+ Your compliance team will have to determine how to handle and verify these transactions in the rules engine or individually.
514
+
515
+ ```ts
516
+ const options: TransactionOptions = {
517
+ proofs: {
518
+ microTransfer: {
519
+ destination: '0x...',
520
+ amountSubunits: '1234',
521
+ timeout: 86440, // Optional timeout in seconds, which is displayed to the user
522
+ },
523
+ fallbacks: [ProofTypes.Screenshot, ProofTypes.SelfDeclaration], // js ['screenshot','self_declaration']
524
+ },
525
+ };
352
526
  ```
353
- ---
354
527
 
355
- Finally you pass the configuration to a Notabene instance:
528
+ Notabene does not currently verify these tests automatically as you likely already have the infrastructure to do so.
356
529
 
357
- ```js
358
- const notabene = new Notabene({
359
- widget: 'https://beta-widget.notabene.id',
360
- container: '#container',
361
- authToken: '{CUSTOMER_TOKEN}'
362
- theme: {THEME},
363
- dictionary: {DICTIONARY},
364
- fallbacks: [{flow: "WALLET_NOT_SUPPORTED", action: "DECLARATION"}]
365
- });
530
+ You will receive a response back from the component containing a proof object. For MicroTransfers it will look like this:
531
+
532
+ ```ts
533
+ type MicroTransferProof {
534
+ type: ProofTypes.MicroTransfer;
535
+ status: ProofStatus.PENDING;
536
+ did: DID;
537
+ address: CAIP10; // CAIP10 account to be verified
538
+ txhash: string; // Transaction Hash to verify
539
+ chain: CAIP2; // CAIP2 identifier of blockchain
540
+ amountSubunits: string; // Amount in subunits eg (satoshi or wei) to be verified
541
+ }
366
542
  ```
367
- ---
368
543
 
369
- ### Opt-In Features
544
+ #### Fallback Proof Options
370
545
 
371
- ```js
372
- const notabene = new Notabene({
373
- widget: 'https://beta-widget.notabene.id',
374
- container: '#container',
375
- authToken: '{CUSTOMER_TOKEN}'
376
- theme: {THEME},
377
- dictionary: {DICTIONARY},
378
- optInFeatures: ['REUSE_ADDRESS_OWNERSHIP_PROOF']
379
- });
546
+ 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:
547
+
548
+ ```ts
549
+ const options: TransactionOptions = {
550
+ proofs: {
551
+ fallbacks: [ProofTypes.Screenshot, ProofTypes.SelfDeclaration], // js ['screenshot','self_declaration']
552
+ },
553
+ };
380
554
  ```
381
555
 
382
- **Available Opt-In Features**
556
+ The two options are:
383
557
 
384
- - `REUSE_ADDRESS_OWNERSHIP_PROOF`: For a given unique customer (identified by the `customerRef` from the customer token used) + unique wallet address, the widget would not ask for data collection if the customer previously verified the address ownership in a previous first party self-hosted transfer.
558
+ - `screenshot` Where a user is requested to upload a screenshot of their wallet
559
+ - `self-declaration` Where a user self declares that they control the wallet address
385
560
 
386
- ### Transaction Custom Asset Price
561
+ ### Counterparty Field Properties
387
562
 
388
- To use your own asset price as fallback in case an asset is not supported by Notabene, you can provide a `customAssetPrice` object that will be used instead to render the widget with the correct jurisdiction requirements.
563
+ 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.
389
564
 
390
- ```js
391
- notabene.setTransaction({
392
- transactionAsset: 'ASSET_UNSUPPORTED_FROM_NOTABENE',
393
- beneficiaryAccountNumber: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
394
- transactionAmount: '2000000000',
395
- customAssetPrice: {
396
- priceUSD: 1700.12, // Asset price in USD
397
- decimals: 10 // Decimals used for the given transactionAmount
398
- };
399
- });
565
+ We recommend working closely with your compliance team for this. Bearing in mind that different jurisdictions have different rules.
566
+
567
+ Each field can be configured like this:
568
+
569
+ - `true` required field
570
+ - `false` don't show
571
+ - `{ optional: true }` show but don't require
572
+
573
+ Eg:
574
+
575
+ ```ts
576
+ {
577
+ naturalPerson: {
578
+ website: { optional: true },
579
+ email: true,
580
+ phone: false,
581
+ }
582
+ }
583
+ ```
584
+
585
+ The above will always ask the user for the following for natural persons:
586
+
587
+ - `name` since it is on by default (you can disable it explicitly by setting it to `false`)
588
+ - `website` is show but is optional
589
+ - `email` is required
590
+
591
+ #### Full Example
592
+
593
+ ```ts
594
+ const options: TransactionOptions = {
595
+ fields: {
596
+ naturalPerson: {
597
+ name: true, // Default true
598
+ website: { optional: true },
599
+ email: true,
600
+ phone: true,
601
+ geographicAddress: false,
602
+ nationalIdentification: false,
603
+ dateOfBirth: {
604
+ transmit: true,
605
+ },
606
+ placeOfBirth: false,
607
+ countryOfResidence: true,
608
+ },
609
+ legalPerson: {
610
+ name: true, // Default true
611
+ lei: true, // Default true
612
+ website: { optional: true }, // Default true
613
+ email: true,
614
+ phone: true,
615
+ geographicAddress: false,
616
+ nationalIdentification: false,
617
+ countryOfRegistration: true,
618
+ },
619
+ },
620
+ };
400
621
  ```
401
622
 
623
+ #### Field reference
624
+
625
+ | Field name | Natural | Legal | IVMS101 | description |
626
+ | ------------------------ | ------- | ----- | ------- | --------------------------------------------- |
627
+ | `name` | ✅ | ✅ | 🟩 | Full name |
628
+ | `email` | 🟩 | 🟩 | -- | Email (for your internal purposes) |
629
+ | `website` | -- | ✅ | -- | Business Website (for your internal purposes) |
630
+ | `phone` | 🟩 | 🟩 | -- | Mobile Phone (for your internal purposes) |
631
+ | `geographicAddress` | 🟩 | 🟩 | 🟩 | Residencial or business address |
632
+ | `nationalIdentification` | 🟩 | 🟩 | 🟩 | National Identification number |
633
+ | `dateOfBirth` | 🟩 | -- | 🟩 | Date of birth |
634
+ | `placeOfBirth` | 🟩 | -- | 🟩 | Place of birth |
635
+ | `countryOfResidence` | 🟩 | -- | 🟩 | Country of Residence |
636
+ | `lei` | -- | ✅ | 🟩 | LEI (Legal Entity Identifier) |
637
+ | `countryOfRegistration` | -- | 🟩 | 🟩 | Country of Registration |
638
+
639
+ ## Locales
640
+
641
+ See [locales](src/locales.ts) for the list of supported locales.
642
+
402
643
  ## [License](LICENSE.md)
403
644
 
404
- BSD 3-Clause © Notabene Inc.
645
+ MIT © Notabene Inc.