@notabene/javascript-sdk 1.32.0 → 2.0.0-next.10

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.
package/README.md CHANGED
@@ -8,27 +8,32 @@
8
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
9
  [![Latest Release](https://gitlab.com/notabene/open-source/javascript-sdk/-/badges/release.svg)](https://gitlab.com/notabene/open-source/javascript-sdk/-/releases)
10
10
 
11
- This library is the JavaScript SDK for loading the widget on a frontend.
11
+ This library is the JavaScript SDK for loading the Notabene UX components in the front-end.
12
12
 
13
- [Documentation](https://devx.notabene.id/docs/widget-v2) •
13
+ [Documentation](https://devx.notabene.id/docs/embedded=ux)
14
14
  [Installation](#installation)
15
15
 
16
16
  </div>
17
17
 
18
- - [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)
31
- - [License](#license)
18
+ - [JavaScript SDK](#javascript-sdk)
19
+ - [Installation](#installation)
20
+ - [Usage](#usage)
21
+ - [Authentication](#authentication)
22
+ - [Assisted Withdrawal](#assisted-withdrawal)
23
+ - [Embedded Component](#embedded-component)
24
+ - [Dynamic updates](#dynamic-updates)
25
+ - [Linked Component](#linked-component)
26
+ - [Transaction parameters](#transaction-parameters)
27
+ - [Asset specification](#asset-specification)
28
+ - [Transaction amount specification](#transaction-amount-specification)
29
+ - [Destination address](#destination-address)
30
+ - [Error handling](#error-handling)
31
+ - [Customization](#customization)
32
+ - [Functionality](#functionality)
33
+ - [Pass the variables in the configuration](#pass-the-variables-in-the-configuration)
34
+ - [Fields Properties](#fields-properties)
35
+ - [Transaction Custom Asset Price](#transaction-custom-asset-price)
36
+ - [License](#license)
32
37
 
33
38
  ## Installation
34
39
 
@@ -57,83 +62,122 @@ Use the [customer token endpoint](https://devx.notabene.id/docs/customertoken) w
57
62
  Create a new Notabene instance:
58
63
 
59
64
  ```js
65
+
60
66
  const notabene = new Notabene({
61
- vaspDID: 'did:ethr:0x94c38fd29ef36f5cb2f7bc771f9d5bd9f7d05f27',
62
- widget: 'https://beta-widget.notabene.id',
63
- container: '#container',
67
+ nodeUrl: 'https://api.notabene.id',
64
68
  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
- },
69
+ locale: 'de' // default locale
73
70
  });
74
71
  ```
75
72
 
76
- Then render the widget:
73
+ Use the same `nodeUrl` that you use to interact with the Notabene API.
77
74
 
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');
75
+ ## Assisted Withdrawal
76
+
77
+ The Withdrawal Assist component helps you collect additional required information from your user during a standard crypto withdrawal process.
78
+
79
+ ### Embedded Component
81
80
 
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');
81
+ This will let you embed the component into your existing withdrawal flow.
82
+
83
+ Create an html element to contain the component:
84
+
85
+ ```html
86
+ <div id="nb-withdrawal/>
84
87
  ```
85
88
 
86
- To update the widget as users enter transaction details:
89
+ Instantiate the withdrawal element and mount it using the id from above
87
90
 
88
91
  ```js
89
- notabene.setTransaction({
90
- transactionAsset: 'ETH',
91
- beneficiaryAccountNumber: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
92
- transactionAmount: '2000000000',
93
- });
92
+ const withdrawal = notabene.createWithdrawalAssist(tx, options);
93
+ withdrawal.mount("nb-withdrawal");
94
94
  ```
95
95
 
96
- Once the widget determines the transaction is valid, it will call the `onValidStateChange` callback, to access the transaction details:
96
+ The simplest way to get the result is to use:
97
97
 
98
98
  ```js
99
- const currentTransactionInfo = notabene.tx;
99
+ try {
100
+ const {valid, ivms101} = await withdrawal.completion()
101
+ if (valid) {
102
+ // Submit result to your backend
103
+ }
104
+ } catch (e) {
105
+ console.error(e)
106
+ }
100
107
  ```
101
108
 
102
- ### Supported asset formats
103
-
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"
116
- }
117
- ```
109
+ #### Dynamic updates
118
110
 
119
- ---
111
+ To update the component as users enter transaction details:
120
112
 
121
- ### Re-rendering
113
+ ```js
114
+ withdrawal.update({
115
+ asset: 'ETH',
116
+ destination: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
117
+ amountDecimal: 1.12
118
+ });
119
+ ```
122
120
 
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).
121
+ To be notified once the validation is completed so you can submit the withdrawal to your back end:
124
122
 
125
- The container of the widget must be in the DOM before calling `destroyWidget` or `renderWidget`.
123
+ ```js
124
+ withdrawal.on('valid', {ivms101} => ...)
125
+ ```
126
126
 
127
- If you need to close and re-render the widget, call the `destroyWidget` method like so:
127
+ To be notified of any errors use:
128
128
 
129
129
  ```js
130
- // Will remove the widget
131
- notabene.destroyWidget();
132
- // Will re-render the widget
133
- notabene.renderWidget();
130
+ withdrawal.on('error',error => ...)
131
+ ```
132
+
133
+ ### Linked Component
134
+
135
+ 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.
136
+
137
+ ```js
138
+ const withdrawal = notabene.createWithdrawalAssist(tx, options, {
139
+ callback: /// a serverside backend url
140
+ redirectUri: // URI of website or mobile app to redirect user to after completion
141
+ });
142
+
143
+ // NodeJS redirect. Link also works in an email.
144
+ res.redirect(withdrawal.url);
134
145
  ```
135
146
 
136
- Calling the `renderWidget` methods without destroying it first will not work.
147
+ Bear in mind that this is a full screen view for your users.
148
+
149
+ The two parameters that should be configured are:
150
+
151
+ - `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.
152
+ - `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.
153
+
154
+ **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.
155
+
156
+ ## Transaction parameters
157
+
158
+ ### Asset specification
159
+
160
+ The `asset` field the following types of assets specified:
161
+
162
+ - `notabene_asset` code passed as a`string`. See [Notabene Assets Service](https://devx.notabene.id/docs/coins-decimals#assets-service-api).
163
+ - [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.
164
+ - [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.
165
+
166
+ ### Transaction amount specification
167
+
168
+ Use one of the following
169
+
170
+ - `amountDecimal` A number specifying the amount in decimal format. Eg. `amountDecimal=1.1` would mean 1.1 of for example BTC or ETH.
171
+ - `amountSubunits` A string specifying the amount in the native blockchain subunits eg Satoshi for Bitcoin or wei for Ethereum
172
+
173
+ ### Destination address
174
+
175
+ Specify the beneficiary address as `destination` using one of the following formats:
176
+
177
+ - [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
178
+ - [EIP-3770](https://eips.ethereum.org/EIPS/eip-3770) EVM URI
179
+ - [BIP-21](https://en.bitcoin.it/wiki/BIP_0021) Bitcoin URI
180
+ - Native blockchain address
137
181
 
138
182
  ---
139
183
 
@@ -175,18 +219,6 @@ Type | Code | Title | Detail
175
219
 
176
220
  ## Customization
177
221
 
178
- ### Functionality
179
-
180
- `transactionTypeAllowed`: `ALL` | `VASP_2_VASP_ONLY` | `SELF_TRANSACTION_ONLY`
181
-
182
- For limiting the type of transaction destinations you can pass.
183
-
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.
187
-
188
- ---
189
-
190
222
  `nonCustodialDeclarationType`: `SIGNATURE` | `DECLARATION`
191
223
 
192
224
  For deciding which ownership proof type you want to use.
@@ -194,82 +226,11 @@ For deciding which ownership proof type you want to use.
194
226
  `SIGNATURE`: The ownership proof will be signed by the originator using a wallet. (DEFAULT)
195
227
  `DECLARATION`: The ownership proof will be declared by the originator using a checkbox.
196
228
 
197
- ### Pass the variables in the configuration
198
-
199
- ```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',
207
- });
208
- ```
209
-
210
229
  ---
211
230
 
212
- ### Theme
231
+ `counterpartyManualEntry`: `TRUE` | `FALSE`
213
232
 
214
- Pass a `theme` object when creating an instance
215
-
216
- Here you can pass configuration which will customize the styles of the widget to meet your brand needs, all values are optional.
217
-
218
- ```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
- }
252
- ```
253
-
254
- To get a list of supported fonts, visit [https://fonts.google.com/](https://fonts.google.com/)
255
-
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).
257
-
258
- ---
259
-
260
- ### Dictionary
261
-
262
- Pass a `dictionary` object mapping in text in the widget to your own language, for example:
263
-
264
- To replace `Loading...` with `Cargando...`
265
-
266
- ```js
267
- {
268
- 'Loading...': 'Cargando...',
269
- }
270
- ```
271
-
272
- ###### The property name must be the same as the text in the widget, for it to be replaced
233
+ For deciding if you would like to allow your customer to provide a manual counterparty vasp name in the counterparty field.
273
234
 
274
235
  ---
275
236
 
@@ -279,10 +240,9 @@ Possible fields customization support:
279
240
 
280
241
  | field name | `forceDisplay` | `optional` | description |
281
242
  | ------------------------ | -------------- | ---------- | ------------------------------------------------------- |
282
- | `counterparty` | -- | ☑️ | Counterparty VASP or Wallet (destination or originator) |
283
243
  | `dateAndPlaceOfBirth` | ☑️ | -- | Recipient (or Sender) Date and Place of Birth |
284
244
  | `geographicAddress` | ☑️ | ☑️ | Recipient (or Sender) Address |
285
- | `name` | ☑️ | -- | Recipient (or Sender) Name |
245
+ | `name` | ☑️ | -- | Recipient (or Sender) Last Name / Company Name |
286
246
  | `nationalIdentification` | ☑️ | --️ | Recipient (or Sender) National Identification |
287
247
  | `country` | ☑️ | ☑️ | Recipient (or Sender) Country of Residence (for natural person) / Country of Registration (for legal person) |
288
248
 
@@ -303,84 +263,7 @@ Possible fields customization support:
303
263
  }
304
264
  ```
305
265
 
306
- ---
307
-
308
- **_Beneficiary Details_ [DEPRECATED]**
309
-
310
- You can require specific beneficiary fields that are not required by your jurisdiction.
311
-
312
- Possible fields:
313
-
314
- - `beneficiaryName` - Recipient Name
315
- - `beneficiaryGeographicAddress` - Recipient Address
316
- - `beneficiaryNationalIdentification` - Recipient National Identification
317
- - `beneficiaryDateAndPlaceOfBirth` - Recipient Date and Place of Birth
318
-
319
- ```js
320
- beneficiaryDetails: [
321
- 'benficiaryName',
322
- 'beneficiaryGeographicAddress',
323
- 'beneficiaryNationalIdentification',
324
- 'beneficiaryDateAndPlaceOfBirth',
325
- ];
326
- ```
327
-
328
- ---
329
-
330
- ### Fallbacks
331
-
332
- Fallbacks are custom options provided when desired outcome is not achieved
333
-
334
- Possible options and actions:
335
-
336
- - `WALLET_NOT_SUPPORTED` - Performs one of the following options when wallet is not supported
337
- - `DECLARATION` - Falls back to the self declaration flow
338
- - `REJECT` - Rejects the transaction and throws an error
339
- - The error that will be thrown here will have the following structure
340
- ```js
341
- {
342
- "type": "WALLET_NOT_SUPPORTED",
343
- "title": "Wallet Not Supported",
344
- "status": 501,
345
- "detail": "We don't support the wallet for the provided asset"
346
- }
347
- ```
348
-
349
- ```js
350
- fallbacks: [{flow: "WALLET_NOT_SUPPORTED", action: "DECLARATION"}]
351
- ```
352
- ---
353
-
354
- Finally you pass the configuration to a Notabene instance:
355
-
356
- ```js
357
- const notabene = new Notabene({
358
- widget: 'https://beta-widget.notabene.id',
359
- container: '#container',
360
- authToken: '{CUSTOMER_TOKEN}'
361
- theme: {THEME},
362
- dictionary: {DICTIONARY},
363
- fallbacks: [{flow: "WALLET_NOT_SUPPORTED", action: "DECLARATION"}]
364
- });
365
- ```
366
- ---
367
-
368
- ### Opt-In Features
369
-
370
- ```js
371
- const notabene = new Notabene({
372
- widget: 'https://beta-widget.notabene.id',
373
- container: '#container',
374
- authToken: '{CUSTOMER_TOKEN}'
375
- theme: {THEME},
376
- dictionary: {DICTIONARY},
377
- optInFeatures: ['REUSE_ADDRESS_OWNERSHIP_PROOF']
378
- });
379
- ```
380
-
381
- **Available Opt-In Features**
382
266
 
383
- - `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.
384
267
 
385
268
  ### Transaction Custom Asset Price
386
269
 
@@ -0,0 +1 @@
1
+ "use strict";var d=Object.defineProperty;var c=(r,e,t)=>e in r?d(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var n=(r,e,t)=>c(r,typeof e!="symbol"?e+"":e,t);var a=(r=>(r.COMPLETE="complete",r.RESIZE="resize",r.RESULT="result",r.READY="ready",r.INVALID="invalid",r.MODAL="openModal",r.ERROR="error",r.CLOSE="closeModal",r.CANCEL="cancel",r))(a||{}),l=(r=>(r.UPDATE="update",r.REQUEST_RESPONSE="requestResponse",r))(l||{});class m{constructor(){n(this,"listeners",new Map);n(this,"port");this.handleMessage=this.handleMessage.bind(this)}setPort(e){this.port=e,this.port.onmessage=this.handleMessage,this.port.start()}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t)}off(e,t){const s=this.listeners.get(e);s&&(s.delete(t),s.size===0&&this.listeners.delete(e))}handleMessage(e){console.log("received message",e.data);const t=e.data;if(typeof t=="object"&&t!==null&&"type"in t){const s=t.type,o=this.listeners.get(s);o&&o.forEach(i=>i(t))}}send(e){this.port&&this.port.postMessage(e)}}class u{constructor(e,t){n(this,"_url");n(this,"_value");n(this,"_errors",[]);n(this,"iframe");n(this,"eventManager");n(this,"ready",!1);n(this,"modal");this._url=e,this._value=t,this.eventManager=new m,this.on(a.INVALID,s=>{s.type===a.INVALID&&(this._errors=s.errors,this._value=s.value)}),this.on(a.RESIZE,s=>{s.type===a.RESIZE&&this.iframe&&(this.iframe.style.height=`${s.height}px`)})}get url(){return this._url}get value(){return this._value}get errors(){return this._errors}open(){document.location.href=this.url}mount(e){const t=document.querySelector(e);if(!t)throw new Error(`parentID ${e} not found`);this.embed(t)}embed(e){var t,s;this.iframe=document.createElement("iframe"),this.iframe.src=this.url,this.iframe.style.width="100%",this.iframe.style.height="100px",this.iframe.style.border="none",this.iframe.style.overflow="hidden",this.iframe.setAttribute("allowtransparency","true"),this.iframe.style.backgroundColor="transparent",e.appendChild(this.iframe),window.addEventListener("message",o=>{var i,h;o.source===((i=this.iframe)==null?void 0:i.contentWindow)&&(console.log("received message from iframe",o.data),(h=this.eventManager)==null||h.setPort(o.ports[0]),this.ready=!0)}),(s=(t=this.iframe)==null?void 0:t.contentWindow)==null||s.focus()}send(e){this.eventManager.send(e)}on(e,t){this.eventManager.on(e,t)}off(e,t){this.eventManager.off(e,t)}update(e){this._value=e,this.send({type:l.UPDATE,value:e})}completion(){return new Promise((e,t)=>{this.closeModal(),this.on(a.COMPLETE,s=>{e(s.response)}),this.on("error",s=>{t(new Error(s.message))})})}openModal(){this.modal&&this.closeModal(),this.modal=document.createElement("dialog"),document.body.appendChild(this.modal),this.embed(this.modal),this.on(a.CANCEL,()=>{this.closeModal()}),this.on(a.CLOSE,()=>{this.closeModal()}),this.on(a.COMPLETE,()=>{this.closeModal()}),this.modal.showModal(),this.modal.addEventListener("click",()=>{this.closeModal()})}closeModal(){var e;this.modal&&(console.log("closeModal"),(e=this.modal)==null||e.close(),this.modal.remove(),this.modal=void 0)}}function f(r){return Object.entries(r).map(([e,t])=>{if(!(e&&t))return;const s=encodeURIComponent(e),o=encodeURIComponent(typeof t=="object"?JSON.stringify(t):t);return`${s}=${o}`}).filter(e=>!!e).join("&")}class p{constructor(e){n(this,"nodeUrl");n(this,"authToken");n(this,"uxUrl");n(this,"theme");n(this,"locale");this.uxUrl=e.uxUrl||"https://connect.notabene.id",this.nodeUrl=e.nodeUrl,this.authToken=e.authToken,this.theme=e.theme,this.locale=e.locale}componentUrl(e,t,s,o){const i=new URL(this.uxUrl);i.pathname=e;const h=f({authToken:this.authToken,value:t,configuration:s});return i.hash=h,this.nodeUrl&&i.searchParams.set("nodeUrl",this.nodeUrl),this.theme&&i.searchParams.set("theme",JSON.stringify(this.theme)),this.locale&&i.searchParams.set("locale",this.locale),o&&(o.callback&&i.searchParams.set("callback_url",o.callback),o.redirectUri&&i.searchParams.set("redirect_uri",o.redirectUri)),i.toString()}createComponent(e,t,s,o){return new u(this.componentUrl(e,t,s,o),t)}createWithdrawalAssist(e,t,s){return this.createComponent("withdrawal-assist",e,t,s)}createDepositAssist(e,t,s){return this.createComponent("deposit-assist",e,t,s)}createConnect(e,t,s){return this.createComponent("connect",e,t,s)}createDepositRequest(e,t,s){return this.createComponent("deposit-request",e,t,s)}decodeFragmentToObject(e){return e.slice(1).split("&").reduce((s,o)=>{const[i,h]=o.split("=");return s[decodeURIComponent(i)]=decodeURIComponent(h),s},{})}}module.exports=p;