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

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
@@ -5,8 +5,7 @@
5
5
 
6
6
  # JavaScript SDK
7
7
 
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)
8
+ [![pipeline status](https://gitlab.com/notabene/open-source/javascript-sdk/badges/v2/pipeline.svg)](https://gitlab.com/notabene/open-source/javascript-sdk/-/commits/v2)
10
9
 
11
10
  This library is the JavaScript SDK for loading the Notabene UX components in the front-end.
12
11
 
@@ -27,12 +26,16 @@ This library is the JavaScript SDK for loading the Notabene UX components in the
27
26
  - [Asset specification](#asset-specification)
28
27
  - [Transaction amount specification](#transaction-amount-specification)
29
28
  - [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)
29
+ - [Destination address](#destination-address-1)
30
+ - [Connect Wallet](#connect-wallet)
31
+ - [Asset specification](#asset-specification-1)
32
+ - [Modal](#modal)
33
+ - [Linked Component](#linked-component-1)
34
+ - [Error handling](#error-handling)
35
+ - [Transaction Options](#transaction-options)
36
+ - [Common use cases](#common-use-cases)
37
+ - [Configuring ownership proofs](#configuring-ownership-proofs)
38
+ - [Counterparty Field Properties](#counterparty-field-properties)
36
39
  - [License](#license)
37
40
 
38
41
  ## Installation
@@ -40,7 +43,7 @@ This library is the JavaScript SDK for loading the Notabene UX components in the
40
43
  There are two options for loading the Notabene SDK:
41
44
 
42
45
  ```bash
43
- <script id="notabene" async src="https://unpkg.com/@notabene/javascript-sdk@1.31.0/dist/es/index.js"></script>
46
+ <script id="notabene" async src="https://unpkg.com/@notabene/javascript-sdk@next/dist/notabene.js"></script>
44
47
  ```
45
48
 
46
49
  Or installing the library:
@@ -121,7 +124,7 @@ withdrawal.update({
121
124
  To be notified once the validation is completed so you can submit the withdrawal to your back end:
122
125
 
123
126
  ```js
124
- withdrawal.on('valid', {ivms101} => ...)
127
+ withdrawal.on('complete', {valid, txCreate } => ...)
125
128
  ```
126
129
 
127
130
  To be notified of any errors use:
@@ -168,7 +171,6 @@ The `asset` field the following types of assets specified:
168
171
  Use one of the following
169
172
 
170
173
  - `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
174
 
173
175
  ### Destination address
174
176
 
@@ -179,108 +181,282 @@ Specify the beneficiary address as `destination` using one of the following form
179
181
  - [BIP-21](https://en.bitcoin.it/wiki/BIP_0021) Bitcoin URI
180
182
  - Native blockchain address
181
183
 
182
- ---
184
+ ### Destination address
183
185
 
184
- ### Error handling
186
+ The price of the asset is used to determine certain rules based on thresholds. We recommond you pass in your price like this:
185
187
 
186
- 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`.
188
+ ```ts
189
+ assetPrice: {
190
+ currency: 'USD', // ISO currency code
191
+ price: 1700.12, // Asset price
192
+ };
193
+ ```
187
194
 
188
- > ⚠️ **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.
195
+ ## Connect Wallet
189
196
 
190
- ```js
191
- type ErrorData = {
192
- title: string;
193
- detail: string;
194
- code: number;
195
- type: string;
196
- };
197
+ The Connect Wallet component helps you collect and verify the address of your users self-hosted wallet in one go.
197
198
 
198
- const notabene = new Notabene({
199
- ...,
200
- onError: (err) => {
201
- const errorData = err.data;
199
+ ### Asset specification
202
200
 
203
- // Do something
204
- },
205
- });
206
- ```
201
+ The `asset` field the following types of assets specified:
207
202
 
208
- **Notabene Internal Errors**
203
+ - `notabene_asset` code passed as a`string`. See [Notabene Assets Service](https://devx.notabene.id/docs/coins-decimals#assets-service-api).
204
+ - [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.
205
+ - [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.
209
206
 
210
- Type | Code | Title | Detail
211
- -- | -- | -- | --
212
- `BAD_REQUEST` | `400` | `Bad Request` | `NotabeneBadRequest: ...`
213
- `TRANSACTION_INVALID` | `400` | `Transaction Invalid` | `NotabeneTransactionInvalid: ...`
214
- `TOKEN_INVALID` | `401` | `Token Invalid` | `NotabeneTokenInvalid: ...`
215
- `ASSET_NOT_SUPPORTED` | `404` | `Asset Not Supported` | `NotabeneAssetNotSupported: ...`
216
- `SERVICE_UNAVAILABLE` | `500` | `Service Unavailable` | `NotabeneServiceUnavailable: ...`
217
- `WALLET_CONNECTED_FAILED` | `500` | `Wallet Connection Failed` | `NotabeneWalletConnectionFailed: ...`
218
- `WALLET_NOT_SUPPORTED` | `501` | `Wallet Not Supported` | `NotabeneWalletNotSupported: ...`
219
207
 
220
- ## Customization
208
+ ### Modal
221
209
 
222
- `nonCustodialDeclarationType`: `SIGNATURE` | `DECLARATION`
210
+ Instantiate the modal and open it
223
211
 
224
- For deciding which ownership proof type you want to use.
212
+ ```js
213
+ const connect = notabene.createConnectWallet({asset:'ETH'}, options);
214
+ const {valid, ivms101, proof } = await connect.openModal();
215
+ ```
225
216
 
226
- `SIGNATURE`: The ownership proof will be signed by the originator using a wallet. (DEFAULT)
227
- `DECLARATION`: The ownership proof will be declared by the originator using a checkbox.
217
+ ### Linked Component
228
218
 
229
- ---
219
+ 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.
230
220
 
231
- `counterpartyManualEntry`: `TRUE` | `FALSE`
221
+ ```js
222
+ const connect = notabene.createConnectWallet({asset:'ETH'}, options, {
223
+ callback: /// a serverside backend url
224
+ redirectUri: // URI of website or mobile app to redirect user to after completion
225
+ });
232
226
 
233
- For deciding if you would like to allow your customer to provide a manual counterparty vasp name in the counterparty field.
227
+ // NodeJS redirect. Link also works in an email.
228
+ res.redirect(withdrawal.url);
229
+ ```
230
+
231
+ Bear in mind that this is a full screen view for your users.
232
+
233
+ The two parameters that should be configured are:
234
+
235
+ - `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.
236
+ - `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.
237
+
238
+ **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.
234
239
 
235
240
  ---
236
241
 
237
- ### Fields Properties
242
+ ## Error handling
238
243
 
239
- Possible fields customization support:
244
+ If any error occurs, the `error` event is passed containing a message.
240
245
 
241
- | field name | `forceDisplay` | `optional` | description |
242
- | ------------------------ | -------------- | ---------- | ------------------------------------------------------- |
243
- | `dateAndPlaceOfBirth` | ☑️ | -- | Recipient (or Sender) Date and Place of Birth |
244
- | `geographicAddress` | ☑️ | ☑️ | Recipient (or Sender) Address |
245
- | `name` | ☑️ | -- | Recipient (or Sender) Last Name / Company Name |
246
- | `nationalIdentification` | ☑️ | --️ | Recipient (or Sender) National Identification |
247
- | `country` | ☑️ | ☑️ | Recipient (or Sender) Country of Residence (for natural person) / Country of Registration (for legal person) |
246
+ ```ts
247
+ withdrawal.on('error', {message} => ...)
248
+ ```
248
249
 
249
- **Field Options**
250
+ ## Transaction Options
250
251
 
251
- - **forceDisplay** - Force a field that is not required by your jurisdiction to be displayed - defaults to **false**
252
- - **optional** - Bypass the jurisdiction rules validation for that specific field - defaults to **false**
252
+ All components can be configured using an optional [TransactionOptions](./docs/interfaces/TransactionOptions.md) object.
253
253
 
254
- ```js
255
- {
256
- counterparty: {
257
- optional: true;
254
+ The following shows the full set of options in typescript:
255
+
256
+ ```ts
257
+ const options: TransactionOptions = {
258
+ proofs: {
259
+ microTransfer: {
260
+ destination: '0x...',
261
+ timeout: 86440,
262
+ },
263
+ fallbacks: [ProofTypes.Screenshot, ProofTypes.SelfDeclaration],
258
264
  },
259
- geographicAddress: {
260
- forceDisplay: true,
261
- optional: true;
265
+ allowedAgentTypes: [AgentType.PRIVATE, AgentType.VASP],
266
+ allowedCounterpartyTypes: [
267
+ PersonType.LEGAL,
268
+ PersonType.NATURAL,
269
+ PersonType.SELF,
270
+ ],
271
+ fields: {
272
+ naturalPerson: {
273
+ name: true, // Default true
274
+ website: { optional: true },
275
+ email: true,
276
+ phone: true,
277
+ geographicAddress: false,
278
+ nationalIdentification: false,
279
+ dateOfBirth: false,
280
+ placeOfBirth: false,
281
+ countryOfResidence: true,
282
+ },
283
+ legalPerson: {
284
+ name: true, // Default true
285
+ lei: true, // Default true
286
+ website: { optional: true }, // Default true
287
+ email: true,
288
+ phone: true,
289
+ geographicAddress: false,
290
+ nationalIdentification: false,
291
+ countryOfRegistration: true,
292
+ },
262
293
  },
294
+ };
295
+ const withdrawal = notabene.createWithdrawalAssist(tx, options);
296
+ ```
297
+
298
+ ### Common use cases
299
+
300
+ #### Only allow first party transactions
301
+
302
+ ```ts
303
+ const firstParty: TransactionOptions = {
304
+ allowedCounterpartyTypes: [
305
+ PersonType.SELF,
306
+ ],
307
+ };
308
+ ```
309
+
310
+ #### Only VASP to VASP transactions
311
+
312
+ ```ts
313
+ const vasp2vasp: TransactionOptions = {
314
+ allowedAgentTypes: [AgentType.VASP],
315
+ };
316
+ ```
317
+
318
+ #### Only Self-hosted wallet transactions
319
+
320
+ ```ts
321
+ const options: TransactionOptions = {
322
+ allowedAgentTypes: [AgentType.PRIVATE],
323
+ };
324
+ ```
325
+
326
+ ### Configuring ownership proofs
327
+
328
+ By default components support message signing proofs.
329
+
330
+
331
+ #### Supporting Micro Transactions (aka Satoshi tests)
332
+
333
+ You can support Micro Transfers (aka Satoshi tests) by adding a deposit address for the test.
334
+
335
+ Your compliance team will have to determine how to handle and verify these transactions in the rules engine or individually.
336
+
337
+ ```ts
338
+ const options: TransactionOptions = {
339
+ proofs: {
340
+ microTransfer: {
341
+ destination: '0x...',
342
+ timeout: 86440, // Optional timeout in seconds, which is displayed to the user
343
+ },
344
+ fallbacks: [ProofTypes.Screenshot, ProofTypes.SelfDeclaration],
345
+ }
346
+ }
347
+ ```
348
+
349
+ Notabene does not currently verify these tests automatically as you likely already have the infrastructure to do so.
350
+
351
+ You will receive a response back from the component containing a proof object. For MicroTransfers it will look like this:
352
+
353
+ ```ts
354
+ type MicroTransferProof {
355
+ type: ProofTypes.MicroTransfer;
356
+ status: ProofStatus.PENDING;
357
+ did: DID;
358
+ address: CAIP10; // CAIP10 account to be verified
359
+ txhash: string; // Transaction Hash to verify
360
+ chain: CAIP2; // CAIP2 identifier of blockchain
361
+ amountSubunits: string; // Amount in subunits eg (satoshi or wei) to be verified
263
362
  }
264
363
  ```
265
364
 
365
+ #### Fallback Proof Options
266
366
 
367
+ 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:
267
368
 
268
- ### Transaction Custom Asset Price
369
+ ```ts
370
+ const options: TransactionOptions = {
371
+ proofs: {
372
+ fallbacks: [ProofTypes.Screenshot, ProofTypes.SelfDeclaration],
373
+ }
374
+ }
375
+ ```
376
+ The two options are:
269
377
 
270
- 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.
378
+ - `screenshot` Where a user is requested to upload a screenshot of their wallet
379
+ - `self-declaration` Where a user self declares that they control the wallet address
271
380
 
272
- ```js
273
- notabene.setTransaction({
274
- transactionAsset: 'ASSET_UNSUPPORTED_FROM_NOTABENE',
275
- beneficiaryAccountNumber: '0x8d12a197cb00d4747a1fe03395095ce2a5cc6819',
276
- transactionAmount: '2000000000',
277
- customAssetPrice: {
278
- priceUSD: 1700.12, // Asset price in USD
279
- decimals: 10 // Decimals used for the given transactionAmount
280
- };
281
- });
381
+ ### Counterparty Field Properties
382
+
383
+ 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.
384
+
385
+ We recommend working closely with your compliance team for this. Bearing in mind that different jurisdictions have different rules.
386
+
387
+ Each field can be configured like this:
388
+
389
+ - `true` required field
390
+ - `false` don't show
391
+ - `{ optional: true }` show but don't require
392
+ - `{ transmit: true }` Include in beneficiary field of IVMS101 to be transmitted to counterparty
393
+
394
+ Eg:
395
+ ```ts
396
+ {
397
+ naturalPerson: {
398
+ website: { optional: true },
399
+ email: true,
400
+ phone: false,
401
+ }
402
+ }
403
+ ```
404
+ The above will always ask the user for the following for natural persons:
405
+
406
+ - `name` since it is on by default (you can disable it explicitly by setting it to `false`)
407
+ - `website` is show but is optional
408
+ - `email` is required
409
+
410
+
411
+ #### Full Example
412
+
413
+ ```ts
414
+ const options: TransactionOptions = {
415
+ fields: {
416
+ naturalPerson: {
417
+ name: true, // Default true
418
+ website: { optional: true },
419
+ email: true,
420
+ phone: true,
421
+ geographicAddress: false,
422
+ nationalIdentification: false,
423
+ dateOfBirth: {
424
+ transmit: true
425
+ },
426
+ placeOfBirth: false,
427
+ countryOfResidence: true,
428
+ },
429
+ legalPerson: {
430
+ name: true, // Default true
431
+ lei: true, // Default true
432
+ website: { optional: true }, // Default true
433
+ email: true,
434
+ phone: true,
435
+ geographicAddress: false,
436
+ nationalIdentification: false,
437
+ countryOfRegistration: true,
438
+ },
439
+ },
440
+ };
282
441
  ```
283
442
 
443
+ #### Field reference
444
+
445
+ | Field name | Natural | Legal | IVMS101 | Transmitted | description |
446
+ |--------------------------|---------|-------|---------|-------------|-----------------------------------------------|
447
+ | `name` | ✅ | ✅ | ✅ | ✅ | Full name |
448
+ | `email` | 🟩 | 🟩 | -- | -- | Email (for your internal purposes) |
449
+ | `website` | -- | ✅ | -- | -- | Business Website (for your internal purposes) |
450
+ | `phone` | 🟩 | 🟩 | -- | -- | Mobile Phone (for your internal purposes) |
451
+ | `geographicAddress` | 🟩 | 🟩 | ✅ | 🟩 | Residencial or business address |
452
+ | `nationalIdentification` | 🟩 | 🟩 | ✅ | 🟩 | National Identification number |
453
+ | `dateOfBirth` | 🟩 | -- | ✅ | 🟩 | Date of birth |
454
+ | `placeOfBirth` | 🟩 | -- | ✅ | 🟩 | Place of birth |
455
+ | `countryOfResidence` | 🟩 | -- | ✅ | 🟩 | Country of Residence |
456
+ | `lei` | -- | ✅ | ✅ | ✅ | LEI (Legal Entity Identifier) |
457
+ | `countryOfRegistration` | -- | 🟩 | ✅ | 🟩 | Country of Registration |
458
+
459
+
284
460
  ## [License](LICENSE.md)
285
461
 
286
- BSD 3-Clause © Notabene Inc.
462
+ MIT © Notabene Inc.
package/dist/notabene.cjs CHANGED
@@ -1 +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;
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,"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]))}),(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.on(a.COMPLETE,s=>{e(s.response)}),this.on("error",s=>{t(new Error(s.message))})})}openModal(){return this.modal&&this.closeModal(),this.modal=document.createElement("dialog"),this.modal.style.border="none",this.modal.style.backgroundColor="transparent",this.modal.style.maxWidth="100vw",this.modal.style.maxHeight="100vh",this.modal.style.width="600px",this.modal.style.height="800px",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()}),this.completion()}closeModal(){var e;this.modal&&(console.log("closeModal"),(e=this.modal)==null||e.close(),this.modal.remove(),this.modal=void 0)}}function p(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 f{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=p({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)}createConnectWallet(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=f;