@notabene/javascript-sdk 1.34.0 → 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/src/notabene.ts CHANGED
@@ -1,318 +1,298 @@
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
+ AgentType,
5
+ CallbackOptions,
6
+ ComponentMessage,
7
+ ConnectionRequest,
8
+ ConnectionResponse,
9
+ Counterparty,
10
+ DeclarationProof,
11
+ Deposit,
12
+ DepositRequest,
13
+ Destination,
14
+ HostMessage,
15
+ IVMS101,
16
+ MicroTransferProof,
17
+ OwnershipProof,
18
+ PersonType,
19
+ ProofStatus,
20
+ ProofTypes,
21
+ ScreenshotProof,
22
+ SignatureProof,
23
+ Status,
10
24
  Theme,
11
25
  Transaction,
12
- TransactionTypeAllowed,
13
- WidgetType,
26
+ TransactionAsset,
27
+ TransactionOptions,
28
+ VASP,
29
+ Wallet,
30
+ Withdrawal,
14
31
  } from './types';
15
- import { popupProps, widgetProps } from './zoidComponentProps';
32
+ import { CMType, TransactionResponse } from './types';
33
+ import { encodeObjectToFragment } from './utils/urls';
16
34
 
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;
35
+ export type {
36
+ CMType,
37
+ ComponentMessage,
38
+ EmbeddedComponent,
39
+ ConnectionRequest,
40
+ ConnectionResponse,
41
+ HostMessage,
42
+ Theme,
43
+ Counterparty,
44
+ Withdrawal,
45
+ Deposit,
46
+ Transaction,
47
+ DepositRequest,
48
+ TransactionResponse,
49
+ Destination as destination,
50
+ TransactionAsset,
51
+ SignatureProof,
52
+ ScreenshotProof,
53
+ MicroTransferProof,
54
+ DeclarationProof,
55
+ Notabene,
56
+ ProofStatus,
57
+ ProofTypes,
58
+ IVMS101,
59
+ PersonType,
60
+ Status,
61
+ VASP,
62
+ Wallet,
63
+ Agent,
64
+ AgentType,
65
+ OwnershipProof,
66
+ TransactionOptions,
67
+ CallbackOptions,
68
+ };
69
+
70
+ /**
71
+ * Configuration for the Notabene SDK
72
+ *
73
+ * @public
74
+ */
75
+ /**
76
+ * Configuration for the Notabene SDK
77
+ *
78
+ * @public
79
+ */
80
+ export interface NotabeneConfig {
81
+ /**
82
+ * The URL of the Notabene API node
83
+ */
84
+ nodeUrl?: string;
85
+
86
+ /**
87
+ * The authentication token for the Notabene API
88
+ */
89
+ authToken?: string;
90
+
91
+ /**
92
+ * The URL of the Notabene UX components
93
+ */
94
+ uxUrl?: string;
95
+
96
+ /**
97
+ * Custom theme configuration for the UX components
98
+ */
24
99
  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
100
 
101
+ /**
102
+ * The locale to use for the UX components
103
+ */
104
+ locale?: string;
105
+ }
106
+ /**
107
+ * Primary constructor for Notabene UX elements
108
+ *
109
+ * This class provides methods to create and manage various Notabene components
110
+ * such as withdrawal assist, deposit assist, connect, and deposit request.
111
+ * It also handles URL generation and fragment decoding for these components.
112
+ *
113
+ * @public
114
+ */
34
115
  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;
116
+ private nodeUrl?: string;
117
+ private authToken?: string;
118
+ private uxUrl: string;
119
+ private theme?: Theme;
120
+ private locale?: string;
43
121
 
122
+ /**
123
+ * Creates a new instance of the Notabene SDK
124
+ *
125
+ * @param config - Configuration options for the Notabene SDK
126
+ */
44
127
  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
- ];
128
+ this.uxUrl = config.uxUrl || 'https://connect.notabene.id';
129
+ this.nodeUrl = config.nodeUrl;
130
+ this.authToken = config.authToken;
131
+ this.theme = config.theme;
132
+ this.locale = config.locale;
55
133
  }
56
134
 
57
135
  /**
58
- * Renders a new widget
59
- * @param type - the type of widget to render
136
+ * Generates a URL for a Notabene component
137
+ *
138
+ * @param path - The path of the component
139
+ * @param value - Transaction data
140
+ * @param configuration - Optional transaction configuration
141
+ * @param callbacks - Optional callback configuration
142
+ * @returns component URL
143
+ * @internal
60
144
  */
61
- public async renderWidget(
62
- type: WidgetType = WidgetType.WITHDRAWAL
63
- ): Promise<void> {
64
- this._renderWidget(type);
65
- }
66
-
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
- }
145
+ componentUrl<V>(
146
+ path: string,
147
+ value: V,
148
+ configuration?: TransactionOptions,
149
+ callbacks?: CallbackOptions,
150
+ ): string {
151
+ const url = new URL(this.uxUrl);
152
+ url.pathname = path;
77
153
 
78
- this.widget = await this.buildWidget();
79
- this.popup = await this.buildPopup();
80
- this.widget.updateProps({
81
- transaction: this.tx,
82
- type,
154
+ const hash = encodeObjectToFragment({
155
+ authToken: this.authToken,
156
+ value,
157
+ configuration,
83
158
  });
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
- }
159
+ url.hash = hash;
160
+ if (this.nodeUrl) url.searchParams.set('nodeUrl', this.nodeUrl);
92
161
 
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;
162
+ if (this.theme) {
163
+ url.searchParams.set('theme', JSON.stringify(this.theme));
99
164
  }
100
- }
101
-
102
- public async destroyWidget(): Promise<void> {
103
- if (!this.widgetRendered || !this.popupRendered) {
104
- this.shouldBeDestroyed = true;
105
- return;
165
+ if (this.locale) {
166
+ url.searchParams.set('locale', this.locale);
106
167
  }
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
- });
168
+ if (callbacks) {
169
+ if (callbacks.callback)
170
+ url.searchParams.set('callback_url', callbacks.callback);
171
+ if (callbacks.redirectUri)
172
+ url.searchParams.set('redirect_uri', callbacks.redirectUri);
122
173
  }
174
+ return url.toString();
123
175
  }
124
176
 
125
- private cleanUpDestroyedComponents() {
126
- if (!this.shouldBeDestroyed) return;
127
- this.destroyWidget();
177
+ /**
178
+ * Creates a new embedded component
179
+ *
180
+ * @param path - The path of the component
181
+ * @param value - Transaction data
182
+ * @param options - Optional transaction options
183
+ * @param callbacks - Optional callback configuration
184
+ * @returns A new EmbeddedComponent instance
185
+ * @internal
186
+ */
187
+ createComponent<V, R>(
188
+ path: string,
189
+ value: V,
190
+ options?: TransactionOptions,
191
+ callbacks?: CallbackOptions,
192
+ ) {
193
+ return new EmbeddedComponent<V, R>(
194
+ this.componentUrl(path, value, options, callbacks),
195
+ value,
196
+ );
128
197
  }
129
198
 
130
- private getWidgetUrl(): string {
131
- const url = new URL(this.config.widget);
132
- url.hash = `authToken=${this.config.authToken}`;
133
- return url.toString();
199
+ /**
200
+ * Creates a withdrawal assist component
201
+ *
202
+ * @param value - Withdrawal transaction data
203
+ * @param options - Optional transaction options
204
+ * @param callbacks - Optional callback configuration
205
+ * @returns A new EmbeddedComponent instance for withdrawal assistance
206
+ */
207
+ public createWithdrawalAssist(
208
+ value: Partial<Withdrawal>,
209
+ options?: TransactionOptions,
210
+ callbacks?: CallbackOptions,
211
+ ) {
212
+ return this.createComponent<
213
+ Partial<Withdrawal>,
214
+ TransactionResponse<Withdrawal>
215
+ >('withdrawal-assist', value, options, callbacks);
134
216
  }
135
217
 
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();
218
+ /**
219
+ * Creates a deposit assist component
220
+ *
221
+ * @param value - Deposit transaction data
222
+ * @param options - Optional transaction options
223
+ * @param callbacks - Optional callback configuration
224
+ * @returns A new EmbeddedComponent instance for deposit assistance
225
+ * @alpha
226
+ */
227
+ public createDepositAssist(
228
+ value: Partial<Deposit>,
229
+ options?: any,
230
+ callbacks?: CallbackOptions,
231
+ ) {
232
+ return this.createComponent<Partial<Deposit>, TransactionResponse<Deposit>>(
233
+ 'deposit-assist',
234
+ value,
235
+ options,
236
+ callbacks,
237
+ );
142
238
  }
143
239
 
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);
240
+ /**
241
+ * Creates a connect component
242
+ *
243
+ * @param value - Connection request data
244
+ * @param options - Optional transaction options
245
+ * @param callbacks - Optional callback configuration
246
+ * @returns A new EmbeddedComponent instance for connection
247
+ */
248
+ public createConnectWallet(
249
+ value: ConnectionRequest,
250
+ options?: TransactionOptions,
251
+ callbacks?: CallbackOptions,
252
+ ) {
253
+ return this.createComponent<ConnectionRequest, ConnectionResponse>(
254
+ 'connect',
255
+ value,
256
+ options,
257
+ callbacks,
258
+ );
156
259
  }
157
260
 
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;
261
+ /**
262
+ * Creates a deposit request component
263
+ *
264
+ * @param value - Deposit request data
265
+ * @param options - Optional transaction options
266
+ * @param callbacks - Optional callback configuration
267
+ * @returns A new EmbeddedComponent instance for deposit requests
268
+ * @alpha
269
+ */
270
+ public createDepositRequest(
271
+ value: DepositRequest,
272
+ options?: TransactionOptions,
273
+ callbacks?: CallbackOptions,
274
+ ) {
275
+ return this.createComponent<
276
+ DepositRequest,
277
+ TransactionResponse<DepositRequest>
278
+ >('deposit-request', value, options, callbacks);
213
279
  }
214
280
 
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');
281
+ /**
282
+ * Decodes a URL fragment into an object
283
+ *
284
+ * @param fragment - The URL fragment to decode
285
+ * @returns An object containing the decoded key-value pairs
286
+ */
287
+ public decodeFragmentToObject(fragment: string): Record<string, string> {
288
+ const pairs = fragment.slice(1).split('&');
289
+ return pairs.reduce(
290
+ (obj, pair) => {
291
+ const [key, value] = pair.split('=');
292
+ obj[decodeURIComponent(key)] = decodeURIComponent(value);
293
+ return obj;
300
294
  },
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;
295
+ {} as Record<string, string>,
296
+ );
315
297
  }
316
298
  }
317
-
318
- if (window) window.Notabene = Notabene;