@notabene/javascript-sdk 1.35.2 → 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 (46) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +498 -268
  3. package/dist/notabene.cjs +1 -0
  4. package/dist/notabene.d.ts +1565 -0
  5. package/dist/notabene.js +343 -0
  6. package/dist/tsdoc-metadata.json +11 -0
  7. package/package.json +50 -63
  8. package/src/__tests__/notabene.test.ts +270 -0
  9. package/src/components/EmbeddedComponent.ts +237 -0
  10. package/src/components/__tests__/EmbeddedComponent.test.ts +530 -0
  11. package/src/ivms/types.ts +232 -152
  12. package/src/locales.ts +47 -0
  13. package/src/notabene.ts +292 -293
  14. package/src/types.ts +1068 -78
  15. package/src/utils/MessageEventManager.ts +115 -0
  16. package/src/utils/__tests__/MessageEventManager.test.ts +119 -0
  17. package/src/utils/__tests__/urls.test.ts +112 -0
  18. package/src/utils/arbitraries.ts +244 -0
  19. package/src/utils/caip.ts +16 -0
  20. package/src/utils/urls.ts +40 -0
  21. package/.editorconfig +0 -10
  22. package/.envrc.template +0 -1
  23. package/.eslintignore +0 -3
  24. package/.eslintrc.js +0 -13
  25. package/.gitlab-ci.yml +0 -74
  26. package/.husky/commit-msg +0 -4
  27. package/.husky/pre-commit +0 -4
  28. package/.husky/pre-push +0 -4
  29. package/.nvmrc +0 -1
  30. package/.prettierrc +0 -4
  31. package/.releaserc.json +0 -16
  32. package/.tool-versions +0 -3
  33. package/.vscode/extensions.json +0 -7
  34. package/.vscode/settings.json +0 -11
  35. package/.yarn/releases/yarn-3.2.2.cjs +0 -783
  36. package/.yarnrc.yml +0 -5
  37. package/CODEOWNERS +0 -1
  38. package/dist/lib/index.js +0 -379
  39. package/jest.config.js +0 -5
  40. package/public/index.html +0 -93
  41. package/src/lib/index.ts +0 -2
  42. package/src/module/index.ts +0 -10
  43. package/src/zoidComponentProps.ts +0 -81
  44. package/tsconfig.json +0 -18
  45. /package/dist/{es/index.js → js/notabene.js} +0 -0
  46. /package/{public/js/.gitkeep → src/arbitraries.ts} +0 -0
package/README.md CHANGED
@@ -2,37 +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
- See v2 branch for the latest version of the SDK.
15
+ This library is the JavaScript SDK for loading the Notabene UX components in the front-end.
9
16
 
10
- [![npm version](https://badge.fury.io/js/%40notabene%2Fjavascript-sdk.svg)](https://badge.fury.io/js/%40notabene%2Fjavascript-sdk)
11
- [![Coverage Status](https://coveralls.io/repos/github/notabene-id/javascript-sdk/badge.svg?branch=master)](https://coveralls.io/github/notabene-id/javascript-sdk?branch=master)
12
-
13
- [![pipeline status](https://gitlab.com/notabene/open-source/javascript-sdk/badges/master/pipeline.svg)](https://gitlab.com/notabene/open-source/javascript-sdk/-/commits/master)
14
- [![Latest Release](https://gitlab.com/notabene/open-source/javascript-sdk/-/badges/release.svg)](https://gitlab.com/notabene/open-source/javascript-sdk/-/releases)
15
-
16
- This library is the JavaScript SDK for loading the widget on a frontend.
17
-
18
- [Documentation](https://devx.notabene.id/docs/widget-v2) •
19
- [Installation](#installation)
17
+ [Additional Documentation](https://devx.notabene.id/docs/embedded=ux)
20
18
 
21
19
  </div>
22
20
 
21
+ ## Table of Contents
22
+
23
23
  - [Installation](#installation)
24
- - [Usage](#usage)
25
- - [Supported asset formats](#supported-asset-formats)
26
- - [Re-rendering](#re-rendering)
27
- - [Error handling](#error-handling)
28
- - [Customization](#customization)
29
- - [Functionality](#functionality)
30
- - [Pass the variables in the configuration](#pass-the-variables-in-the-configuration)
31
- - [Theme](#theme)
32
- - [Dictionary](#dictionary)
33
- - [Fields Properties](#fields-properties)
34
- - [Fallbacks](#fallbacks)
35
- - [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)
36
48
  - [License](#license)
37
49
 
38
50
  ## Installation
@@ -40,16 +52,53 @@ This library is the JavaScript SDK for loading the widget on a frontend.
40
52
  There are two options for loading the Notabene SDK:
41
53
 
42
54
  ```bash
43
- <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>
44
56
  ```
45
57
 
46
58
  Or installing the library:
47
59
 
60
+ Using Yarn:
61
+
48
62
  ```bash
49
- yarn add @notabene/javascript-sdk
63
+ yarn add @notabene/javascript-sdk@next
64
+ ```
65
+
66
+ Using NPM:
67
+
68
+ ```bash
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';
50
76
  ```
51
77
 
52
- ## 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
53
102
 
54
103
  ### Authentication
55
104
 
@@ -63,353 +112,534 @@ Create a new Notabene instance:
63
112
 
64
113
  ```js
65
114
  const notabene = new Notabene({
66
- vaspDID: 'did:ethr:0x94c38fd29ef36f5cb2f7bc771f9d5bd9f7d05f27',
67
- widget: 'https://beta-widget.notabene.id',
68
- container: '#container',
115
+ nodeUrl: 'https://api.notabene.id', // use `https://api.notabene.dev` for testing
69
116
  authToken: '{CUSTOMER_TOKEN}',
70
- onValidStateChange: (isValid) => {
71
- // Use this value to determine if the transaction is ready to be created.
72
- console.log('is transaction valid', isValid);
73
- },
74
- onError: (err) => {
75
- // If any errors are encountered, they will be passed to this function
76
- alert(err.message);
77
- },
117
+ locale: 'de', // default locale = `en`
78
118
  });
79
119
  ```
80
120
 
81
- Then render the widget:
121
+ Use the same `nodeUrl` that you use to interact with the Notabene API.
82
122
 
83
- ```js
84
- // Use this method when you need to collect missing information from the sender about the recipient (normal withdrawal)
85
- notabene.renderWidget('WITHDRAWAL');
123
+ ## General Component Usage
86
124
 
87
- // Use this method when you need to collect missing information from the recipient about the sender (for transactions created via notification)
88
- notabene.renderWidget('POST_DEPOSIT');
89
- ```
125
+ Each component can be used in various ways depending on your use case.
90
126
 
91
- To update the widget as users enter transaction details:
127
+ ### Embedded Component
92
128
 
93
- ```js
94
- notabene.setTransaction({
95
- transactionAsset: 'ETH',
96
- beneficiaryAccountNumber: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
97
- transactionAmount: '2000000000',
98
- });
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/>
99
135
  ```
100
136
 
101
- 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
102
138
 
103
139
  ```js
104
- const currentTransactionInfo = notabene.tx;
140
+ const withdrawal = notabene.createWithdrawalAssist(tx, options);
141
+ withdrawal.mount('#nb-withdrawal');
105
142
  ```
106
143
 
107
- ### Supported asset formats
144
+ The simplest way to get the result is to use:
108
145
 
109
- - `USDC` the simple asset code passed as a `string`, in case different chain (polygon) -> `USDC-POLY`
110
- - `CAIP19` format
111
- ```js
112
- {
113
- caip19: 'eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'; // for USDC
114
- }
115
- ```
116
- - `coingeckoId` and `network` format
117
- ```js
118
- {
119
- coingeckoId: "usd-coin",
120
- 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
121
152
  }
122
- ```
153
+ } catch (e) {
154
+ console.error(e);
155
+ }
156
+ ```
123
157
 
124
- ---
158
+ #### Dynamic updates
125
159
 
126
- ### Re-rendering
160
+ To update the component as users enter transaction details:
161
+
162
+ ```js
163
+ withdrawal.update({
164
+ asset: 'ETH',
165
+ destination: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
166
+ amountDecimal: 1.12,
167
+ });
168
+ ```
127
169
 
128
- **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).
170
+ To be notified once the validation is completed so you can submit the withdrawal to your back end:
129
171
 
130
- 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
+ ```
131
175
 
132
- 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:
133
177
 
134
178
  ```js
135
- // Will remove the widget
136
- notabene.destroyWidget();
137
- // Will re-render the widget
138
- notabene.renderWidget();
179
+ withdrawal.on('error',error => ...)
139
180
  ```
140
181
 
141
- Calling the `renderWidget` methods without destroying it first will not work.
182
+ Calling `on` returns a function that will allow you to cleanly unsubscribe.
142
183
 
143
- ---
184
+ ```js
185
+ const unsubscribe = withdrawal.on('complete', { valid, value, txCreate, ivms101, proof } => ...)
186
+
187
+ // Clean up
188
+ unsubscribe()
144
189
 
145
- ### Error handling
190
+ ```
146
191
 
147
- 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`.
192
+ ### Modal
148
193
 
149
- > ⚠️ **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.
194
+ All components support being opened in a modal using `openModal()`, which returns a promise.
150
195
 
151
196
  ```js
152
- type ErrorData = {
153
- title: string;
154
- detail: string;
155
- code: number;
156
- type: string;
157
- };
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
+ ```
158
208
 
159
- const notabene = new Notabene({
160
- ...,
161
- onError: (err) => {
162
- const errorData = err.data;
163
209
 
164
- // Do something
165
- },
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
166
218
  });
167
- ```
168
219
 
169
- **Notabene Internal Errors**
220
+ // NodeJS redirect. Link also works in an email.
221
+ res.redirect(withdrawal.url);
222
+ ```
170
223
 
171
- Type | Code | Title | Detail
172
- -- | -- | -- | --
173
- `BAD_REQUEST` | `400` | `Bad Request` | `NotabeneBadRequest: ...`
174
- `TRANSACTION_INVALID` | `400` | `Transaction Invalid` | `NotabeneTransactionInvalid: ...`
175
- `TOKEN_INVALID` | `401` | `Token Invalid` | `NotabeneTokenInvalid: ...`
176
- `ASSET_NOT_SUPPORTED` | `404` | `Asset Not Supported` | `NotabeneAssetNotSupported: ...`
177
- `SERVICE_UNAVAILABLE` | `500` | `Service Unavailable` | `NotabeneServiceUnavailable: ...`
178
- `WALLET_CONNECTED_FAILED` | `500` | `Wallet Connection Failed` | `NotabeneWalletConnectionFailed: ...`
179
- `WALLET_NOT_SUPPORTED` | `501` | `Wallet Not Supported` | `NotabeneWalletNotSupported: ...`
224
+ Bear in mind that this is a full screen view for your users.
180
225
 
181
- ## Customization
226
+ The two parameters that should be configured are:
182
227
 
183
- ### Functionality
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.
184
230
 
185
- `transactionTypeAllowed`: `ALL` | `VASP_2_VASP_ONLY` | `SELF_TRANSACTION_ONLY`
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.
186
232
 
187
- For limiting the type of transaction destinations you can pass.
188
233
 
189
- `ALL`: All transaction destinations are allowed. (DEFAULT)
190
- `VASP_2_VASP_ONLY`: Only transaction destinations that are VASPs are allowed.
191
- `SELF_TRANSACTION_ONLY`: Only transaction destinations that the originator owns are allowed.
234
+ ## Components
192
235
 
193
- ---
236
+ ## Assisted Withdrawal
194
237
 
195
- `nonCustodialDeclarationType`: `SIGNATURE` | `DECLARATION`
238
+ The Withdrawal Assist component helps you collect additional required information from your user during a standard crypto withdrawal process.
196
239
 
197
- For deciding which ownership proof type you want to use.
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
+ ```
198
251
 
199
- `SIGNATURE`: The ownership proof will be signed by the originator using a wallet. (DEFAULT)
200
- `DECLARATION`: The ownership proof will be declared by the originator using a checkbox.
252
+ ### Parameters
201
253
 
202
- ---
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)
203
258
 
204
- `counterpartyManualEntry`: `TRUE` | `FALSE`
259
+ If any of the required parameters are missing the component will just show the Notabene badge.
205
260
 
206
- For deciding if you would like to allow your customer to provide a manual counterparty vasp name in the counterparty field.
261
+ ### Configuration Options
207
262
 
208
- ### Pass the variables in the configuration
263
+ Include configuration Options as a second optional parameter:
209
264
 
210
265
  ```js
211
- const notabene = new Notabene({
212
- vaspDID: 'did:ethr:0x94c38fd29ef36f5cb2f7bc771f9d5bd9f7d05f27',
213
- widget: 'https://beta-widget.notabene.id',
214
- container: '#container',
215
- authToken: '{CUSTOMER_TOKEN}'
216
- allowedTransactionTypes: 'VASP_2_VASP_ONLY',
217
- 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
+ }
218
282
  });
219
283
  ```
220
284
 
221
- ---
222
-
223
- ### Theme
285
+ See [Transaction Options](#transaction-options)
224
286
 
225
- Pass a `theme` object when creating an instance
287
+ ## Connect Wallet
226
288
 
227
- 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.
228
290
 
229
291
  ```js
230
- {
231
- primaryColor: '#fff',
232
- secondaryColor: '#fff',
233
- primaryFontColor: '#fff',
234
- secondaryFontColor: '#fff',
235
- backgroundColor: '#fff',
236
- fontFamily: Arial,
237
- logo: {LOGO_URL},
238
- mode: 'dark', // default: 'light'
239
-
240
- // If you are using the Signature flow, here is the full list of custom theme that can be applied to the WalletConnect Modal.
241
- '--w3m-font-family',
242
- '--w3m-font-feature-settings',
243
- '--w3m-overlay-background-color',
244
- '--w3m-overlay-backdrop-filter',
245
- '--w3m-z-index',
246
- '--w3m-accent-color',
247
- '--w3m-accent-fill-color',
248
- '--w3m-background-color',
249
- '--w3m-background-image-url',
250
- '--w3m-logo-image-url',
251
- '--w3m-background-border-radius',
252
- '--w3m-container-border-radius',
253
- '--w3m-wallet-icon-border-radius',
254
- '--w3m-wallet-icon-large-border-radius',
255
- '--w3m-wallet-icon-small-border-radius',
256
- '--w3m-input-border-radius',
257
- '--w3m-notification-border-radius',
258
- '--w3m-button-border-radius',
259
- '--w3m-secondary-button-border-radius',
260
- '--w3m-icon-button-border-radius',
261
- '--w3m-button-hover-highlight-border-radius',
262
- }
292
+ const connect = notabene.createConnectWallet({
293
+ asset: 'ETH'
294
+ });
295
+
296
+ const { proof, txCreate } = await connect.openModal()
263
297
  ```
264
298
 
265
- To get a list of supported fonts, visit [https://fonts.google.com/](https://fonts.google.com/)
299
+ ### Parameters
266
300
 
267
- 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)
268
302
 
269
- ---
303
+ ### Configuration Options
270
304
 
271
- ### Dictionary
305
+ Include configuration Options as a second optional parameter:
272
306
 
273
- 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
+ ```
274
320
 
275
- To replace `Loading...` with `Cargando...`
321
+ ## Deposit Request
322
+
323
+ The Deposit Request lets your customers request deposits that are fully Travel Rule compliant.
276
324
 
277
325
  ```js
278
- {
279
- 'Loading...': 'Cargando...',
280
- }
326
+ const withdrawal = notabene.createDepositRequest({
327
+ asset: 'ETH',
328
+ destination: '0x...',
329
+ amountDecimal: 1.23,
330
+ customer: {
331
+ name: "John Smith"
332
+ }
333
+ });
281
334
  ```
282
335
 
283
- ###### 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.
284
344
 
285
345
  ---
286
346
 
287
- ### Fields Properties
347
+ ## Error handling
288
348
 
289
- Possible fields customization support:
349
+ If any error occurs, the `error` event is passed containing a message.
290
350
 
291
- | field name | `forceDisplay` | `optional` | description |
292
- | ------------------------ | -------------- | ---------- | ------------------------------------------------------- |
293
- | `counterparty` | -- | ☑️ | Counterparty VASP or Wallet (destination or originator) |
294
- | `dateAndPlaceOfBirth` | ☑️ | -- | Recipient (or Sender) Date and Place of Birth |
295
- | `geographicAddress` | ☑️ | ☑️ | Recipient (or Sender) Address |
296
- | `firstName` | ☑️ | -- | Recipient (or Sender) First name |
297
- | `name` | ☑️ | -- | Recipient (or Sender) Last Name / Company Name |
298
- | `nationalIdentification` | ☑️ | --️ | Recipient (or Sender) National Identification |
299
- | `country` | ☑️ | ☑️ | Recipient (or Sender) Country of Residence (for natural person) / Country of Registration (for legal person) |
351
+ ```ts
352
+ withdrawal.on('error', {message} => ...)
353
+ ```
300
354
 
301
- **Field Options**
355
+ ## Transaction parameters
302
356
 
303
- - **forceDisplay** - Force a field that is not required by your jurisdiction to be displayed - defaults to **false**
304
- - **optional** - Bypass the jurisdiction rules validation for that specific field - defaults to **false**
357
+ ### Asset specification
305
358
 
306
- ```js
307
- {
308
- counterparty: {
309
- optional: true;
359
+ The `asset` field the following types of assets specified:
360
+
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
+ }
310
420
  },
311
- geographicAddress: {
312
- forceDisplay: true,
313
- 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
314
454
  },
315
- }
455
+ };
456
+ const withdrawal = notabene.createWithdrawalAssist(tx, options);
316
457
  ```
317
458
 
318
- ---
459
+ The options can additionally be updated dynamically with the `update()` function.
319
460
 
320
- **_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
+ ```
321
476
 
322
- You can require specific beneficiary fields that are not required by your jurisdiction.
477
+ ### Common use cases
323
478
 
324
- Possible fields:
479
+ #### Only allow first party transactions
325
480
 
326
- - `beneficiaryName` - Recipient Name
327
- - `beneficiaryGeographicAddress` - Recipient Address
328
- - `beneficiaryNationalIdentification` - Recipient National Identification
329
- - `beneficiaryDateAndPlaceOfBirth` - Recipient Date and Place of Birth
481
+ ```ts
482
+ const firstParty: TransactionOptions = {
483
+ allowedCounterpartyTypes: [
484
+ PersonType.SELF, // JS: 'self'
485
+ ],
486
+ };
487
+ ```
330
488
 
331
- ```js
332
- beneficiaryDetails: [
333
- 'benficiaryName',
334
- 'beneficiaryGeographicAddress',
335
- 'beneficiaryNationalIdentification',
336
- 'beneficiaryDateAndPlaceOfBirth',
337
- ];
489
+ #### Only VASP to VASP transactions
490
+
491
+ ```ts
492
+ const vasp2vasp: TransactionOptions = {
493
+ allowedAgentTypes: [AgentType.VASP], // js ['VASP']
494
+ };
338
495
  ```
339
496
 
340
- ---
497
+ #### Only Self-hosted wallet transactions
341
498
 
342
- ### Fallbacks
499
+ ```ts
500
+ const options: TransactionOptions = {
501
+ allowedAgentTypes: [AgentType.PRIVATE], // js ['WALLET']
502
+ };
503
+ ```
343
504
 
344
- Fallbacks are custom options provided when desired outcome is not achieved
505
+ ### Configuring ownership proofs
345
506
 
346
- Possible options and actions:
507
+ By default components support message signing proofs.
347
508
 
348
- - `WALLET_NOT_SUPPORTED` - Performs one of the following options when wallet is not supported
349
- - `DECLARATION` - Falls back to the self declaration flow
350
- - `REJECT` - Rejects the transaction and throws an error
351
- - The error that will be thrown here will have the following structure
352
- ```js
353
- {
354
- "type": "WALLET_NOT_SUPPORTED",
355
- "title": "Wallet Not Supported",
356
- "status": 501,
357
- "detail": "We don't support the wallet for the provided asset"
358
- }
359
- ```
509
+ #### Supporting Micro Transactions (aka Satoshi tests)
360
510
 
361
- ```js
362
- 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
+ };
363
526
  ```
364
- ---
365
527
 
366
- 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.
367
529
 
368
- ```js
369
- const notabene = new Notabene({
370
- widget: 'https://beta-widget.notabene.id',
371
- container: '#container',
372
- authToken: '{CUSTOMER_TOKEN}'
373
- theme: {THEME},
374
- dictionary: {DICTIONARY},
375
- fallbacks: [{flow: "WALLET_NOT_SUPPORTED", action: "DECLARATION"}]
376
- });
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
+ }
377
542
  ```
378
- ---
379
543
 
380
- ### Opt-In Features
544
+ #### Fallback Proof Options
381
545
 
382
- ```js
383
- const notabene = new Notabene({
384
- widget: 'https://beta-widget.notabene.id',
385
- container: '#container',
386
- authToken: '{CUSTOMER_TOKEN}'
387
- theme: {THEME},
388
- dictionary: {DICTIONARY},
389
- optInFeatures: ['REUSE_ADDRESS_OWNERSHIP_PROOF']
390
- });
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
+ };
391
554
  ```
392
555
 
393
- **Available Opt-In Features**
556
+ The two options are:
394
557
 
395
- - `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
396
560
 
397
- ### Transaction Custom Asset Price
561
+ ### Counterparty Field Properties
398
562
 
399
- 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.
400
564
 
401
- ```js
402
- notabene.setTransaction({
403
- transactionAsset: 'ASSET_UNSUPPORTED_FROM_NOTABENE',
404
- beneficiaryAccountNumber: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
405
- transactionAmount: '2000000000',
406
- customAssetPrice: {
407
- priceUSD: 1700.12, // Asset price in USD
408
- decimals: 10 // Decimals used for the given transactionAmount
409
- };
410
- });
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
+ };
411
621
  ```
412
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
+
413
643
  ## [License](LICENSE.md)
414
644
 
415
- BSD 3-Clause © Notabene Inc.
645
+ MIT © Notabene Inc.