@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/src/notabene.ts CHANGED
@@ -1,323 +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
- counterpartyManualEntry?: boolean;
33
- }
34
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
+ */
35
173
  export default class Notabene {
36
- private widget: zoid.ZoidComponent;
37
- private popup: zoid.ZoidComponent;
38
- private config: NotabeneConfig;
39
- private tx: Transaction | undefined;
40
- private error?: Error;
41
- private widgetRendered: boolean;
42
- private popupRendered: boolean;
43
- private shouldBeDestroyed: boolean;
174
+ private nodeUrl?: string;
175
+ private authToken?: string;
176
+ private uxUrl: string;
177
+ private theme?: Theme;
178
+ private locale?: string;
44
179
 
180
+ /**
181
+ * Creates a new instance of the Notabene SDK
182
+ *
183
+ * @param config - Configuration options for the Notabene SDK
184
+ */
45
185
  constructor(config: NotabeneConfig) {
46
- this.config = config;
47
- this.config.nonCustodialDeclarationType =
48
- config.nonCustodialDeclarationType || 'SIGNATURE';
49
- this.config.transactionTypeAllowed = config.transactionTypeAllowed || 'ALL';
50
- this.widgetRendered = false;
51
- this.shouldBeDestroyed = false;
52
- this.popupRendered = false;
53
- this.config.fallbacks = this.config.fallbacks || [
54
- { flow: 'WALLET_NOT_SUPPORTED', action: 'DECLARATION' },
55
- ];
56
- this.config.counterpartyManualEntry = this.config.counterpartyManualEntry !== undefined ? this.config.counterpartyManualEntry : true;
57
-
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;
58
191
  }
59
192
 
60
193
  /**
61
- * Renders a new widget
62
- * @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
63
202
  */
64
- public async renderWidget(
65
- type: WidgetType = WidgetType.WITHDRAWAL
66
- ): Promise<void> {
67
- this._renderWidget(type);
68
- }
69
-
70
- private async _renderWidget(type: WidgetType): Promise<void> {
71
- if (this.widgetRendered) {
72
- console.error(
73
- 'Notabene: Widget already rendered, please destroy it first'
74
- );
75
- this.config.onError(
76
- new Error('Widget already rendered, please destroy it first')
77
- );
78
- return;
79
- }
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;
80
211
 
81
- this.widget = await this.buildWidget();
82
- this.popup = await this.buildPopup();
83
- this.widget.updateProps({
84
- transaction: this.tx,
85
- type,
86
- });
87
- this.popup.updateProps({
88
- transaction: this.tx,
89
- type,
212
+ const hash = encodeObjectToFragment({
213
+ authToken: this.authToken,
214
+ value,
215
+ configuration,
90
216
  });
91
- this.popup.hide();
92
- await this.widget.render(this.config.container);
93
- await this.renderPopup();
94
- }
95
-
96
- private async renderPopup(): Promise<void> {
97
- if (!this.popup) return;
217
+ url.hash = hash;
218
+ if (this.nodeUrl) url.searchParams.set('nodeUrl', this.nodeUrl);
98
219
 
99
- if (!this.popupRendered) {
100
- await this.popup.render(this.config.container);
101
- this.popupRendered = true;
220
+ if (this.theme) {
221
+ url.searchParams.set('theme', JSON.stringify(this.theme));
102
222
  }
103
- }
104
-
105
- public async destroyWidget(): Promise<void> {
106
- if (!this.widgetRendered || !this.popupRendered) {
107
- this.shouldBeDestroyed = true;
108
- return;
223
+ if (this.locale) {
224
+ url.searchParams.set('locale', this.locale);
109
225
  }
110
- await destroy();
111
- this.shouldBeDestroyed = false;
112
- this.widgetRendered = false;
113
- this.popupRendered = false;
114
- }
115
-
116
- public setTransaction(tx: Transaction) {
117
- this.tx = tx;
118
- if (this.widgetRendered) {
119
- this.widget.updateProps({
120
- transaction: tx,
121
- });
122
- this.popup.updateProps({
123
- transaction: tx,
124
- });
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);
125
231
  }
126
- }
127
-
128
- private cleanUpDestroyedComponents() {
129
- if (!this.shouldBeDestroyed) return;
130
- this.destroyWidget();
131
- }
132
-
133
- private getWidgetUrl(): string {
134
- const url = new URL(this.config.widget);
135
- url.hash = `authToken=${this.config.authToken}`;
136
232
  return url.toString();
137
233
  }
138
234
 
139
- private getAdditionalInfoUrl(): string {
140
- const url = new URL(this.config.widget);
141
- url.search = 'popup=true';
142
- url.hash = `authToken=${this.config.authToken}`;
143
-
144
- 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
+ );
145
256
  }
146
257
 
147
- private handleError(err: any): void {
148
- this.error = err;
149
- if (this.widget && this.popup) {
150
- this.widget.updateProps({
151
- error: err,
152
- });
153
- this.popup.updateProps({
154
- error: err,
155
- });
156
- }
157
- if (!err || !this.config.onError) return;
158
- 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
+ );
159
277
  }
160
278
 
161
- private buildWidget(): zoid.ZoidComponent {
162
- if (!this.config.authToken) {
163
- console.error('Notabene: authToken is required');
164
- return;
165
- }
166
-
167
- const builtWidget = zoid.create({
168
- tag: 'widget',
169
- url: this.getWidgetUrl(),
170
- dimensions: {
171
- width: '100%',
172
- height: '280px',
173
- },
174
- attributes: {
175
- iframe: {
176
- allow: 'usb *;bluetooth *',
177
- },
178
- },
179
- props: widgetProps,
180
- })({
181
- vaspDID: this.config.vaspDID,
182
- transaction: {},
183
- theme: this.config.theme,
184
- dictionary: this.config.dictionary,
185
- transactionTypeAllowed: this.config.transactionTypeAllowed,
186
- nonCustodialDeclarationType: this.config.nonCustodialDeclarationType,
187
- beneficiaryDetails: this.config.beneficiaryDetails,
188
- fieldsProps: this.config.fieldsProps,
189
- fallbacks: this.config.fallbacks,
190
- optInFeatures: this.config.optInFeatures,
191
- counterpartyManualEntry: this.config.counterpartyManualEntry,
192
- onRequireAdditionalInformation: () => {
193
- this.popup.updateProps({
194
- popupOpen: true,
195
- });
196
- this.popup.show();
197
- },
198
- onValidStateChange: (isValid: boolean) => {
199
- this.config.onValidStateChange(isValid);
200
- },
201
- error: this.error,
202
- onError: (err: any) => {
203
- this.handleError(err);
204
- console.debug('Notabene: Error handler called');
205
- },
206
- storeTransaction: (tx: Transaction) => {
207
- this.setTransaction(tx);
208
- },
209
- });
210
-
211
- builtWidget.event.on(zoid.EVENT.RENDERED, () => {
212
- this.widgetRendered = true;
213
- this.cleanUpDestroyedComponents();
214
- });
215
-
216
- 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
+ );
217
299
  }
218
300
 
219
- private buildPopup(): zoid.ZoidComponent {
220
- if (!this.config.authToken) {
221
- console.error('Notabene: authToken is required');
222
- return;
223
- }
224
-
225
- const builtPopup = zoid.create({
226
- tag: 'popup',
227
- url: this.getAdditionalInfoUrl(),
228
- children: () => {
229
- return {
230
- Transaction: this.tx,
231
- };
232
- },
233
- dimensions: {
234
- width: '100%',
235
- height: '100%',
236
- },
237
- attributes: {
238
- iframe: {
239
- allow: 'usb *;bluetooth *',
240
- },
241
- },
242
- props: popupProps,
243
- containerTemplate: ({ uid, doc, frame, prerenderFrame }: any) => {
244
- return node(
245
- 'div',
246
- { id: uid, class: 'nb-container' },
247
- node(
248
- 'style',
249
- null,
250
- `
251
- #${uid}.container {
252
- border: 5px solid red;
253
- }
254
- .nb-overlay {
255
- position: fixed;
256
- width: 100vw;
257
- height: 100vh;
258
- top: 0;
259
- left: 0;
260
- display: flex;
261
- align-items: center;
262
- justify-content: center;
263
- background-color: rgba(0,0,0,0.5);
264
- }
265
- .nb-popup {
266
- width: 100%;
267
- height: 100%;
268
- }
269
- .nb-preloader {
270
- display: none;
271
- }
272
- `
273
- ),
274
- node(
275
- 'div',
276
- { class: 'nb-overlay' },
277
- node('node', { el: frame, class: 'nb-popup' }),
278
- node('node', { el: prerenderFrame, class: 'nb-preloader' })
279
- )
280
- ).render(dom({ doc }));
281
- },
282
- })({
283
- vaspDID: this.config.vaspDID,
284
- transaction: this.tx,
285
- beneficiaryDetails: this.config.beneficiaryDetails,
286
- fieldsProps: this.config.fieldsProps,
287
- counterpartyManualEntry: this.config.counterpartyManualEntry,
288
- storeTransaction: (tx: Transaction) => {
289
- this.setTransaction(tx);
290
- console.debug('Notabene: Transaction stored');
291
- },
292
- close: () => {
293
- this.popup.close();
294
- console.debug('Notabene: Popup closing');
295
- },
296
- setPopupOpen: (isOpen: boolean) => {
297
- this.popup.updateProps({
298
- popupOpen: isOpen,
299
- });
300
- },
301
- error: this.error,
302
- onError: (err: any) => {
303
- this.handleError(err);
304
- console.debug('Notabene: Error handler called');
305
- },
306
- popupOpen: false,
307
- theme: this.config.theme,
308
- dictionary: this.config.dictionary,
309
- transactionTypeAllowed: this.config.transactionTypeAllowed,
310
- nonCustodialDeclarationType: this.config.nonCustodialDeclarationType,
311
- fallbacks: this.config.fallbacks,
312
- optInFeatures: this.config.optInFeatures,
313
- });
314
-
315
- builtPopup.event.on(zoid.EVENT.RENDERED, () => {
316
- this.popupRendered = true;
317
- this.cleanUpDestroyedComponents();
318
- });
319
- 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
+ );
320
321
  }
321
322
  }
322
-
323
- if (window) window.Notabene = Notabene;