@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 +256 -80
- package/dist/notabene.cjs +1 -1
- package/dist/notabene.d.ts +525 -169
- package/dist/notabene.js +136 -13
- package/dist/tsdoc-metadata.json +1 -1
- package/package.json +24 -20
- package/src/components/EmbeddedComponent.ts +80 -48
- package/src/components/__tests__/EmbeddedComponent.test.ts +40 -12
- package/src/ivms/types.ts +177 -140
- package/src/notabene.ts +126 -14
- package/src/types.ts +281 -117
- package/src/utils/__tests__/MessageEventManager.test.ts +1 -1
package/README.md
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
# JavaScript SDK
|
|
7
7
|
|
|
8
|
-
[](https://gitlab.com/notabene/open-source/javascript-sdk/-/releases)
|
|
8
|
+
[](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
|
-
- [
|
|
31
|
-
- [
|
|
32
|
-
- [
|
|
33
|
-
- [
|
|
34
|
-
- [
|
|
35
|
-
|
|
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@
|
|
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('
|
|
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
|
-
|
|
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
|
-
|
|
188
|
+
```ts
|
|
189
|
+
assetPrice: {
|
|
190
|
+
currency: 'USD', // ISO currency code
|
|
191
|
+
price: 1700.12, // Asset price
|
|
192
|
+
};
|
|
193
|
+
```
|
|
187
194
|
|
|
188
|
-
|
|
195
|
+
## Connect Wallet
|
|
189
196
|
|
|
190
|
-
|
|
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
|
-
|
|
199
|
-
...,
|
|
200
|
-
onError: (err) => {
|
|
201
|
-
const errorData = err.data;
|
|
199
|
+
### Asset specification
|
|
202
200
|
|
|
203
|
-
|
|
204
|
-
},
|
|
205
|
-
});
|
|
206
|
-
```
|
|
201
|
+
The `asset` field the following types of assets specified:
|
|
207
202
|
|
|
208
|
-
|
|
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
|
-
|
|
208
|
+
### Modal
|
|
221
209
|
|
|
222
|
-
|
|
210
|
+
Instantiate the modal and open it
|
|
223
211
|
|
|
224
|
-
|
|
212
|
+
```js
|
|
213
|
+
const connect = notabene.createConnectWallet({asset:'ETH'}, options);
|
|
214
|
+
const {valid, ivms101, proof } = await connect.openModal();
|
|
215
|
+
```
|
|
225
216
|
|
|
226
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
242
|
+
## Error handling
|
|
238
243
|
|
|
239
|
-
|
|
244
|
+
If any error occurs, the `error` event is passed containing a message.
|
|
240
245
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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
|
-
|
|
250
|
+
## Transaction Options
|
|
250
251
|
|
|
251
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
|
|
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,"
|
|
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;
|