@notabene/javascript-sdk 1.34.0 → 2.0.0-RC

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +500 -259
  3. package/dist/{es/index.js → js/notabene.js} +1 -1
  4. package/dist/notabene.cjs +1 -0
  5. package/dist/notabene.d.ts +1565 -0
  6. package/dist/notabene.js +343 -0
  7. package/dist/tsdoc-metadata.json +11 -0
  8. package/package.json +50 -64
  9. package/src/__tests__/notabene.test.ts +270 -0
  10. package/src/components/EmbeddedComponent.ts +237 -0
  11. package/src/components/__tests__/EmbeddedComponent.test.ts +530 -0
  12. package/src/ivms/types.ts +232 -152
  13. package/src/locales.ts +47 -0
  14. package/src/notabene.ts +292 -288
  15. package/src/types.ts +1068 -78
  16. package/src/utils/MessageEventManager.ts +115 -0
  17. package/src/utils/__tests__/MessageEventManager.test.ts +119 -0
  18. package/src/utils/__tests__/urls.test.ts +112 -0
  19. package/src/utils/arbitraries.ts +244 -0
  20. package/src/utils/caip.ts +16 -0
  21. package/src/utils/urls.ts +40 -0
  22. package/.editorconfig +0 -10
  23. package/.envrc.template +0 -1
  24. package/.eslintignore +0 -3
  25. package/.eslintrc.js +0 -13
  26. package/.gitlab-ci.yml +0 -74
  27. package/.husky/commit-msg +0 -4
  28. package/.husky/pre-commit +0 -4
  29. package/.husky/pre-push +0 -4
  30. package/.nvmrc +0 -1
  31. package/.prettierrc +0 -4
  32. package/.releaserc.json +0 -16
  33. package/.tool-versions +0 -3
  34. package/.vscode/extensions.json +0 -7
  35. package/.vscode/settings.json +0 -11
  36. package/CODEOWNERS +0 -1
  37. package/dist/lib/index.js +0 -376
  38. package/jest.config.js +0 -5
  39. package/public/index.html +0 -93
  40. package/src/lib/index.ts +0 -2
  41. package/src/module/index.ts +0 -10
  42. package/src/zoidComponentProps.ts +0 -81
  43. package/tsconfig.json +0 -18
  44. /package/{public/js/.gitkeep → src/arbitraries.ts} +0 -0
package/src/notabene.ts CHANGED
@@ -1,318 +1,322 @@
1
- // @ts-ignore
2
- import { dom, node } from 'jsx-pragmatic';
3
- // @ts-ignore
4
- import zoid, { destroy } from 'zoid';
5
- import {
6
- Fallback,
7
- FieldsProps,
8
- NonCustodialDeclarationType,
9
- OptInFeature,
1
+ import EmbeddedComponent from './components/EmbeddedComponent';
2
+ import type {
3
+ Agent,
4
+ BlockchainAddress,
5
+ CAIP10,
6
+ CAIP19,
7
+ CAIP2,
8
+ CallbackOptions,
9
+ Cancel,
10
+ Completed,
11
+ ComponentMessage,
12
+ ComponentResponse,
13
+ ConnectionOptions,
14
+ ConnectionRequest,
15
+ Counterparty,
16
+ CryptoCredential,
17
+ DeclarationProof,
18
+ Deposit,
19
+ DepositRequest,
20
+ DepositRequestOptions,
21
+ Destination,
22
+ DID,
23
+ DTI,
24
+ Error,
25
+ FieldTypes,
26
+ HostMessage,
27
+ InvalidValue,
28
+ IVMS101,
29
+ LegalPerson,
30
+ LEI,
31
+ MicroTransferProof,
32
+ NationalIdentification,
33
+ NaturalPerson,
34
+ NotabeneAsset,
35
+ OwnershipProof,
36
+ Ready,
37
+ ResizeRequest,
38
+ ScreenshotProof,
39
+ SignatureProof,
10
40
  Theme,
41
+ ThresholdOptions,
11
42
  Transaction,
12
- TransactionTypeAllowed,
13
- WidgetType,
43
+ TransactionAsset,
44
+ TransactionOptions,
45
+ TransactionResponse,
46
+ TravelAddress,
47
+ UpdateValue,
48
+ V1Transaction,
49
+ ValidationError,
50
+ VASP,
51
+ VASPOptions,
52
+ Wallet,
53
+ Withdrawal,
54
+ } from './types';
55
+ import {
56
+ AgentType,
57
+ CMType,
58
+ HMType,
59
+ PersonType,
60
+ ProofStatus,
61
+ ProofTypes,
62
+ Status,
63
+ ValidationSections,
14
64
  } from './types';
15
- import { popupProps, widgetProps } from './zoidComponentProps';
65
+ import { type MessageCallback } from './utils/MessageEventManager';
66
+ import { decodeFragmentToObject, encodeObjectToFragment } from './utils/urls';
67
+ // Must be exported for React Native SDK to use
68
+ export { default as EmbeddedComponent } from './components/EmbeddedComponent';
69
+ export type {
70
+ Agent,
71
+ BlockchainAddress,
72
+ CAIP2,
73
+ CAIP10,
74
+ CAIP19,
75
+ CryptoCredential,
76
+ TravelAddress,
77
+ NotabeneAsset,
78
+ DTI,
79
+ VASPOptions,
80
+ NationalIdentification,
81
+ FieldTypes,
82
+ DID,
83
+ MessageCallback,
84
+ CallbackOptions,
85
+ Cancel,
86
+ Completed,
87
+ ComponentMessage,
88
+ ComponentResponse,
89
+ ConnectionRequest,
90
+ Counterparty,
91
+ DeclarationProof,
92
+ Deposit,
93
+ DepositRequest,
94
+ Destination,
95
+ Error,
96
+ HostMessage,
97
+ InvalidValue,
98
+ IVMS101,
99
+ LegalPerson,
100
+ LEI,
101
+ MicroTransferProof,
102
+ NaturalPerson,
103
+ OwnershipProof,
104
+ Ready,
105
+ ResizeRequest,
106
+ ScreenshotProof,
107
+ SignatureProof,
108
+ Theme,
109
+ ThresholdOptions,
110
+ Transaction,
111
+ TransactionAsset,
112
+ TransactionOptions,
113
+ TransactionResponse,
114
+ UpdateValue,
115
+ V1Transaction,
116
+ ValidationError,
117
+ VASP,
118
+ Wallet,
119
+ Withdrawal,
120
+ };
121
+ export {
122
+ CMType,
123
+ HMType,
124
+ ProofStatus,
125
+ ProofTypes,
126
+ PersonType,
127
+ Status,
128
+ AgentType,
129
+ ValidationSections,
130
+ decodeFragmentToObject,
131
+ };
132
+
133
+ /**
134
+ * Configuration for the Notabene SDK
135
+ *
136
+ * @public
137
+ */
138
+ export interface NotabeneConfig {
139
+ /**
140
+ * The URL of the Notabene API node
141
+ */
142
+ nodeUrl?: string;
16
143
 
17
- interface NotabeneConfig {
18
- widget: string;
19
- container: string;
20
- authToken: string;
21
- vaspDID: string;
22
- onValidStateChange(isValid: boolean): void;
23
- onError(err: any): void;
144
+ /**
145
+ * The authentication token for the Notabene API
146
+ */
147
+ authToken?: string;
148
+
149
+ /**
150
+ * The URL of the Notabene UX components
151
+ */
152
+ uxUrl?: string;
153
+
154
+ /**
155
+ * Custom theme configuration for the UX components
156
+ */
24
157
  theme?: Theme;
25
- dictionary?: { [key: string]: string };
26
- transactionTypeAllowed?: TransactionTypeAllowed;
27
- nonCustodialDeclarationType?: NonCustodialDeclarationType;
28
- beneficiaryDetails?: string[]; // @deprecated beneficiaryDetails - do not delete yet
29
- fieldsProps?: FieldsProps;
30
- fallbacks?: Fallback[];
31
- optInFeatures?: OptInFeature[];
32
- }
33
158
 
159
+ /**
160
+ * The locale to use for the UX components
161
+ */
162
+ locale?: string;
163
+ }
164
+ /**
165
+ * Primary constructor for Notabene UX elements
166
+ *
167
+ * This class provides methods to create and manage various Notabene components
168
+ * such as withdrawal assist, deposit assist, connect, and deposit request.
169
+ * It also handles URL generation and fragment decoding for these components.
170
+ *
171
+ * @public
172
+ */
34
173
  export default class Notabene {
35
- private widget: zoid.ZoidComponent;
36
- private popup: zoid.ZoidComponent;
37
- private config: NotabeneConfig;
38
- private tx: Transaction | undefined;
39
- private error?: Error;
40
- private widgetRendered: boolean;
41
- private popupRendered: boolean;
42
- private shouldBeDestroyed: boolean;
174
+ private nodeUrl?: string;
175
+ private authToken?: string;
176
+ private uxUrl: string;
177
+ private theme?: Theme;
178
+ private locale?: string;
43
179
 
180
+ /**
181
+ * Creates a new instance of the Notabene SDK
182
+ *
183
+ * @param config - Configuration options for the Notabene SDK
184
+ */
44
185
  constructor(config: NotabeneConfig) {
45
- this.config = config;
46
- this.config.nonCustodialDeclarationType =
47
- config.nonCustodialDeclarationType || 'SIGNATURE';
48
- this.config.transactionTypeAllowed = config.transactionTypeAllowed || 'ALL';
49
- this.widgetRendered = false;
50
- this.shouldBeDestroyed = false;
51
- this.popupRendered = false;
52
- this.config.fallbacks = this.config.fallbacks || [
53
- { flow: 'WALLET_NOT_SUPPORTED', action: 'DECLARATION' },
54
- ];
186
+ this.uxUrl = config.uxUrl || 'https://connect.notabene.id';
187
+ this.nodeUrl = config.nodeUrl;
188
+ this.authToken = config.authToken;
189
+ this.theme = config.theme;
190
+ this.locale = config.locale;
55
191
  }
56
192
 
57
193
  /**
58
- * Renders a new widget
59
- * @param type - the type of widget to render
194
+ * Generates a URL for a Notabene component
195
+ *
196
+ * @param path - The path of the component
197
+ * @param value - Transaction data
198
+ * @param configuration - Optional transaction configuration
199
+ * @param callbacks - Optional callback configuration
200
+ * @returns component URL
201
+ * @internal
60
202
  */
61
- public async renderWidget(
62
- type: WidgetType = WidgetType.WITHDRAWAL
63
- ): Promise<void> {
64
- this._renderWidget(type);
65
- }
203
+ componentUrl<V, O>(
204
+ path: string,
205
+ value: V,
206
+ configuration?: O,
207
+ callbacks?: CallbackOptions,
208
+ ): string {
209
+ const url = new URL(this.uxUrl);
210
+ url.pathname = path;
66
211
 
67
- private async _renderWidget(type: WidgetType): Promise<void> {
68
- if (this.widgetRendered) {
69
- console.error(
70
- 'Notabene: Widget already rendered, please destroy it first'
71
- );
72
- this.config.onError(
73
- new Error('Widget already rendered, please destroy it first')
74
- );
75
- return;
76
- }
77
-
78
- this.widget = await this.buildWidget();
79
- this.popup = await this.buildPopup();
80
- this.widget.updateProps({
81
- transaction: this.tx,
82
- type,
212
+ const hash = encodeObjectToFragment({
213
+ authToken: this.authToken,
214
+ value,
215
+ configuration,
83
216
  });
84
- this.popup.updateProps({
85
- transaction: this.tx,
86
- type,
87
- });
88
- this.popup.hide();
89
- await this.widget.render(this.config.container);
90
- await this.renderPopup();
91
- }
217
+ url.hash = hash;
218
+ if (this.nodeUrl) url.searchParams.set('nodeUrl', this.nodeUrl);
92
219
 
93
- private async renderPopup(): Promise<void> {
94
- if (!this.popup) return;
95
-
96
- if (!this.popupRendered) {
97
- await this.popup.render(this.config.container);
98
- this.popupRendered = true;
220
+ if (this.theme) {
221
+ url.searchParams.set('theme', JSON.stringify(this.theme));
99
222
  }
100
- }
101
-
102
- public async destroyWidget(): Promise<void> {
103
- if (!this.widgetRendered || !this.popupRendered) {
104
- this.shouldBeDestroyed = true;
105
- return;
223
+ if (this.locale) {
224
+ url.searchParams.set('locale', this.locale);
106
225
  }
107
- await destroy();
108
- this.shouldBeDestroyed = false;
109
- this.widgetRendered = false;
110
- this.popupRendered = false;
111
- }
112
-
113
- public setTransaction(tx: Transaction) {
114
- this.tx = tx;
115
- if (this.widgetRendered) {
116
- this.widget.updateProps({
117
- transaction: tx,
118
- });
119
- this.popup.updateProps({
120
- transaction: tx,
121
- });
226
+ if (callbacks) {
227
+ if (callbacks.callback)
228
+ url.searchParams.set('callback_url', callbacks.callback);
229
+ if (callbacks.redirectUri)
230
+ url.searchParams.set('redirect_uri', callbacks.redirectUri);
122
231
  }
123
- }
124
-
125
- private cleanUpDestroyedComponents() {
126
- if (!this.shouldBeDestroyed) return;
127
- this.destroyWidget();
128
- }
129
-
130
- private getWidgetUrl(): string {
131
- const url = new URL(this.config.widget);
132
- url.hash = `authToken=${this.config.authToken}`;
133
232
  return url.toString();
134
233
  }
135
234
 
136
- private getAdditionalInfoUrl(): string {
137
- const url = new URL(this.config.widget);
138
- url.search = 'popup=true';
139
- url.hash = `authToken=${this.config.authToken}`;
140
-
141
- return url.toString();
235
+ /**
236
+ * Creates a new embedded component
237
+ *
238
+ * @param path - The path of the component
239
+ * @param value - Transaction data
240
+ * @param options - Optional transaction options
241
+ * @param callbacks - Optional callback configuration
242
+ * @returns A new EmbeddedComponent instance
243
+ * @internal
244
+ */
245
+ createComponent<V, O>(
246
+ path: string,
247
+ value: Partial<V>,
248
+ options?: O,
249
+ callbacks?: CallbackOptions,
250
+ ) {
251
+ return new EmbeddedComponent<V, O>(
252
+ this.componentUrl(path, value, options, callbacks),
253
+ value,
254
+ options,
255
+ );
142
256
  }
143
257
 
144
- private handleError(err: any): void {
145
- this.error = err;
146
- if (this.widget && this.popup) {
147
- this.widget.updateProps({
148
- error: err,
149
- });
150
- this.popup.updateProps({
151
- error: err,
152
- });
153
- }
154
- if (!err || !this.config.onError) return;
155
- this.config.onError(err);
258
+ /**
259
+ * Creates a withdrawal assist component
260
+ *
261
+ * @param value - Withdrawal transaction data
262
+ * @param options - Optional transaction options
263
+ * @param callbacks - Optional callback configuration
264
+ * @returns A new EmbeddedComponent instance for withdrawal assistance
265
+ */
266
+ public createWithdrawalAssist(
267
+ value: Partial<Withdrawal>,
268
+ options?: TransactionOptions,
269
+ callbacks?: CallbackOptions,
270
+ ) {
271
+ return this.createComponent<Withdrawal, TransactionOptions>(
272
+ 'withdrawal-assist',
273
+ value,
274
+ options,
275
+ callbacks,
276
+ );
156
277
  }
157
278
 
158
- private buildWidget(): zoid.ZoidComponent {
159
- if (!this.config.authToken) {
160
- console.error('Notabene: authToken is required');
161
- return;
162
- }
163
-
164
- const builtWidget = zoid.create({
165
- tag: 'widget',
166
- url: this.getWidgetUrl(),
167
- dimensions: {
168
- width: '100%',
169
- height: '280px',
170
- },
171
- attributes: {
172
- iframe: {
173
- allow: 'usb *;bluetooth *',
174
- },
175
- },
176
- props: widgetProps,
177
- })({
178
- vaspDID: this.config.vaspDID,
179
- transaction: {},
180
- theme: this.config.theme,
181
- dictionary: this.config.dictionary,
182
- transactionTypeAllowed: this.config.transactionTypeAllowed,
183
- nonCustodialDeclarationType: this.config.nonCustodialDeclarationType,
184
- beneficiaryDetails: this.config.beneficiaryDetails,
185
- fieldsProps: this.config.fieldsProps,
186
- fallbacks: this.config.fallbacks,
187
- optInFeatures: this.config.optInFeatures,
188
- onRequireAdditionalInformation: () => {
189
- this.popup.updateProps({
190
- popupOpen: true,
191
- });
192
- this.popup.show();
193
- },
194
- onValidStateChange: (isValid: boolean) => {
195
- this.config.onValidStateChange(isValid);
196
- },
197
- error: this.error,
198
- onError: (err: any) => {
199
- this.handleError(err);
200
- console.debug('Notabene: Error handler called');
201
- },
202
- storeTransaction: (tx: Transaction) => {
203
- this.setTransaction(tx);
204
- },
205
- });
206
-
207
- builtWidget.event.on(zoid.EVENT.RENDERED, () => {
208
- this.widgetRendered = true;
209
- this.cleanUpDestroyedComponents();
210
- });
211
-
212
- return builtWidget;
279
+ /**
280
+ * Creates a connect component
281
+ *
282
+ * @param value - Connection request data
283
+ * @param options - Optional transaction options
284
+ * @param callbacks - Optional callback configuration
285
+ * @returns A new EmbeddedComponent instance for connection
286
+ * @alpha
287
+ */
288
+ public createConnectWallet(
289
+ value: ConnectionRequest,
290
+ options?: ConnectionOptions,
291
+ callbacks?: CallbackOptions,
292
+ ) {
293
+ return this.createComponent<ConnectionRequest, ConnectionOptions>(
294
+ 'connect',
295
+ value,
296
+ options,
297
+ callbacks,
298
+ );
213
299
  }
214
300
 
215
- private buildPopup(): zoid.ZoidComponent {
216
- if (!this.config.authToken) {
217
- console.error('Notabene: authToken is required');
218
- return;
219
- }
220
-
221
- const builtPopup = zoid.create({
222
- tag: 'popup',
223
- url: this.getAdditionalInfoUrl(),
224
- children: () => {
225
- return {
226
- Transaction: this.tx,
227
- };
228
- },
229
- dimensions: {
230
- width: '100%',
231
- height: '100%',
232
- },
233
- attributes: {
234
- iframe: {
235
- allow: 'usb *;bluetooth *',
236
- },
237
- },
238
- props: popupProps,
239
- containerTemplate: ({ uid, doc, frame, prerenderFrame }: any) => {
240
- return node(
241
- 'div',
242
- { id: uid, class: 'nb-container' },
243
- node(
244
- 'style',
245
- null,
246
- `
247
- #${uid}.container {
248
- border: 5px solid red;
249
- }
250
- .nb-overlay {
251
- position: fixed;
252
- width: 100vw;
253
- height: 100vh;
254
- top: 0;
255
- left: 0;
256
- display: flex;
257
- align-items: center;
258
- justify-content: center;
259
- background-color: rgba(0,0,0,0.5);
260
- }
261
- .nb-popup {
262
- width: 100%;
263
- height: 100%;
264
- }
265
- .nb-preloader {
266
- display: none;
267
- }
268
- `
269
- ),
270
- node(
271
- 'div',
272
- { class: 'nb-overlay' },
273
- node('node', { el: frame, class: 'nb-popup' }),
274
- node('node', { el: prerenderFrame, class: 'nb-preloader' })
275
- )
276
- ).render(dom({ doc }));
277
- },
278
- })({
279
- vaspDID: this.config.vaspDID,
280
- transaction: this.tx,
281
- beneficiaryDetails: this.config.beneficiaryDetails,
282
- fieldsProps: this.config.fieldsProps,
283
- storeTransaction: (tx: Transaction) => {
284
- this.setTransaction(tx);
285
- console.debug('Notabene: Transaction stored');
286
- },
287
- close: () => {
288
- this.popup.close();
289
- console.debug('Notabene: Popup closing');
290
- },
291
- setPopupOpen: (isOpen: boolean) => {
292
- this.popup.updateProps({
293
- popupOpen: isOpen,
294
- });
295
- },
296
- error: this.error,
297
- onError: (err: any) => {
298
- this.handleError(err);
299
- console.debug('Notabene: Error handler called');
300
- },
301
- popupOpen: false,
302
- theme: this.config.theme,
303
- dictionary: this.config.dictionary,
304
- transactionTypeAllowed: this.config.transactionTypeAllowed,
305
- nonCustodialDeclarationType: this.config.nonCustodialDeclarationType,
306
- fallbacks: this.config.fallbacks,
307
- optInFeatures: this.config.optInFeatures,
308
- });
309
-
310
- builtPopup.event.on(zoid.EVENT.RENDERED, () => {
311
- this.popupRendered = true;
312
- this.cleanUpDestroyedComponents();
313
- });
314
- return builtPopup;
301
+ /**
302
+ * Creates a deposit request component
303
+ *
304
+ * @param value - Deposit request data
305
+ * @param options - Optional transaction options
306
+ * @param callbacks - Optional callback configuration
307
+ * @returns A new EmbeddedComponent instance for deposit requests
308
+ * @public
309
+ */
310
+ public createDepositRequest(
311
+ value: DepositRequest,
312
+ options?: DepositRequestOptions,
313
+ callbacks?: CallbackOptions,
314
+ ) {
315
+ return this.createComponent<DepositRequest, DepositRequestOptions>(
316
+ 'deposit-request',
317
+ value,
318
+ options,
319
+ callbacks,
320
+ );
315
321
  }
316
322
  }
317
-
318
- if (window) window.Notabene = Notabene;