@meshconnect/web-link-sdk 2.1.0-rc.0 → 2.1.0-rc.2

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 (51) hide show
  1. package/jest.setup.ts +4 -0
  2. package/package.json +20 -9
  3. package/src/Link.test.ts +395 -0
  4. package/src/Link.ts +350 -0
  5. package/src/index.ts +3 -0
  6. package/src/utils/__snapshots__/popup.test.ts.snap +90 -0
  7. package/src/utils/event-types.test.ts +24 -0
  8. package/src/utils/event-types.ts +226 -0
  9. package/src/utils/popup.test.ts +50 -0
  10. package/src/utils/popup.ts +132 -0
  11. package/src/utils/sdk-specs.test.ts +17 -0
  12. package/src/utils/sdk-specs.ts +6 -0
  13. package/src/utils/style.test.ts +33 -0
  14. package/src/utils/style.ts +15 -0
  15. package/src/utils/types.ts +156 -0
  16. package/src/utils/version.ts +1 -0
  17. package/src/utils/wagmiCoreConnectorsUtils.ts +332 -0
  18. package/src/utils/wallet-browser-event-types.ts +102 -0
  19. package/tools/copy.js +25 -0
  20. package/tools/update-version.js +10 -0
  21. package/tsconfig.json +14 -0
  22. package/Link.d.ts +0 -2
  23. package/Link.js +0 -420
  24. package/cjs/Link.js +0 -424
  25. package/cjs/index.js +0 -21
  26. package/cjs/utils/event-types.js +0 -31
  27. package/cjs/utils/popup.js +0 -39
  28. package/cjs/utils/sdk-specs.js +0 -8
  29. package/cjs/utils/style.js +0 -18
  30. package/cjs/utils/types.js +0 -2
  31. package/cjs/utils/version.js +0 -4
  32. package/cjs/utils/wagmiCoreConnectorsUtils.js +0 -425
  33. package/cjs/utils/wallet-browser-event-types.js +0 -17
  34. package/index.d.ts +0 -3
  35. package/index.js +0 -3
  36. package/utils/event-types.d.ts +0 -152
  37. package/utils/event-types.js +0 -27
  38. package/utils/popup.d.ts +0 -3
  39. package/utils/popup.js +0 -34
  40. package/utils/sdk-specs.d.ts +0 -4
  41. package/utils/sdk-specs.js +0 -5
  42. package/utils/style.d.ts +0 -3
  43. package/utils/style.js +0 -13
  44. package/utils/types.d.ts +0 -134
  45. package/utils/types.js +0 -1
  46. package/utils/version.d.ts +0 -1
  47. package/utils/version.js +0 -1
  48. package/utils/wagmiCoreConnectorsUtils.d.ts +0 -11
  49. package/utils/wagmiCoreConnectorsUtils.js +0 -414
  50. package/utils/wallet-browser-event-types.d.ts +0 -59
  51. package/utils/wallet-browser-event-types.js +0 -13
package/jest.setup.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { TextEncoder, TextDecoder } from 'util';
2
+
3
+ global.TextEncoder = TextEncoder;
4
+ global.TextDecoder = TextDecoder;
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "@meshconnect/web-link-sdk",
3
- "version": "2.1.0-rc.0",
3
+ "version": "2.1.0-rc.2",
4
4
  "description": "A client-side JS library for integrating with Mesh Connect",
5
+ "main": "./src/index.ts",
6
+ "module": "./src/index.ts",
7
+ "types": "./src/index.ts",
8
+ "type": "module",
5
9
  "license": "MIT",
6
10
  "repository": "https://github.com/FrontFin/mesh-web-sdk.git",
7
11
  "homepage": "https://github.com/FrontFin/mesh-web-sdk",
@@ -25,13 +29,23 @@
25
29
  "@wagmi/core": "^2.10.5",
26
30
  "viem": "^2.x",
27
31
  "@wagmi/connectors": "^5.0.7"
32
+ },
33
+ "scripts": {
34
+ "build": "yarn updateVersion && rimraf dist && yarn build:esm && yarn build:cjs && yarn copy",
35
+ "build:esm": "tsc --outDir dist",
36
+ "build:cjs": "tsc --module commonjs --outDir dist/cjs",
37
+ "typecheck": "tsc --noEmit --skipLibCheck",
38
+ "lint": "eslint **/*.ts",
39
+ "copy": "node ./tools/copy",
40
+ "updateVersion": "node ./tools/update-version",
41
+ "publish:npm": "yarn build && cd dist && yarn publish --access public --tag rc",
42
+ "test": "jest",
43
+ "test:cov": "jest --ci --coverage"
28
44
  },
29
45
  "jest": {
30
46
  "preset": "ts-jest",
31
47
  "testEnvironment": "jsdom",
32
- "setupFiles": [
33
- "./jest.setup.ts"
34
- ],
48
+ "setupFiles": ["./jest.setup.ts"],
35
49
  "testPathIgnorePatterns": [
36
50
  "/node_modules/",
37
51
  "/dist/"
@@ -54,8 +68,5 @@
54
68
  "testEnvironmentOptions": {
55
69
  "url": "http://localhost/"
56
70
  }
57
- },
58
- "main": "cjs/index.js",
59
- "module": "index.js",
60
- "types": "index.d.ts"
61
- }
71
+ }
72
+ }
@@ -0,0 +1,395 @@
1
+ import { createLink } from './Link'
2
+ import { DoneEvent, LinkEventType } from './utils/event-types'
3
+ import {
4
+ AccessTokenPayload,
5
+ DelayedAuthPayload,
6
+ EventType,
7
+ LinkPayload,
8
+ IntegrationAccessToken,
9
+ TransferFinishedPayload
10
+ } from './utils/types'
11
+
12
+ type EventPayload = {
13
+ type: EventType
14
+ payload?: AccessTokenPayload | DelayedAuthPayload | TransferFinishedPayload
15
+ message?: string
16
+ link?: string
17
+ }
18
+
19
+ const BASE64_ENCODED_URL = Buffer.from('http://localhost/1').toString('base64')
20
+
21
+ describe('createLink tests', () => {
22
+ window.open = jest.fn()
23
+
24
+ test('createLink when invalid link provided should not open popup', () => {
25
+ const exitFunction = jest.fn<void, [string | undefined]>()
26
+ const frontConnection = createLink({
27
+ clientId: 'test',
28
+ onIntegrationConnected: jest.fn(),
29
+ onExit: exitFunction
30
+ })
31
+
32
+ frontConnection.openLink('')
33
+
34
+ expect(exitFunction).toBeCalledWith('Invalid link token!')
35
+ const iframeElement = document.getElementById('mesh-link-popup__iframe')
36
+ expect(iframeElement).toBeFalsy()
37
+ })
38
+
39
+ test('createLink when valid link provided should open popup', () => {
40
+ const frontConnection = createLink({
41
+ clientId: 'test',
42
+ onIntegrationConnected: jest.fn()
43
+ })
44
+
45
+ frontConnection.openLink(BASE64_ENCODED_URL)
46
+ const iframeElement = document.getElementById('mesh-link-popup__iframe')
47
+ expect(iframeElement).toBeTruthy()
48
+ expect(iframeElement?.attributes.getNamedItem('src')?.nodeValue).toBe(
49
+ 'http://localhost/1'
50
+ )
51
+ })
52
+
53
+ test('createLink closePopup should close popup', () => {
54
+ const exitFunction = jest.fn<void, [string | undefined]>()
55
+ const frontConnection = createLink({
56
+ clientId: 'test',
57
+ onIntegrationConnected: jest.fn(),
58
+ onExit: exitFunction
59
+ })
60
+
61
+ frontConnection.openLink(BASE64_ENCODED_URL)
62
+ frontConnection.closeLink()
63
+
64
+ const iframeElement = document.getElementById('mesh-link-popup__iframe')
65
+ expect(iframeElement).toBeFalsy()
66
+
67
+ expect(exitFunction).toBeCalled()
68
+ })
69
+
70
+ test.each(['close', 'done'] as const)(
71
+ 'createLink "%s" event should close popup',
72
+ eventName => {
73
+ const exitFunction = jest.fn<void, [string | undefined]>()
74
+ const frontConnection = createLink({
75
+ clientId: 'test',
76
+ onIntegrationConnected: jest.fn(),
77
+ onExit: exitFunction
78
+ })
79
+
80
+ const payload: DoneEvent['payload'] = {
81
+ page: 'some page',
82
+ errorMessage: 'some msg'
83
+ }
84
+ frontConnection.openLink(BASE64_ENCODED_URL)
85
+ window.dispatchEvent(
86
+ new MessageEvent<LinkEventType>('message', {
87
+ data: {
88
+ type: eventName,
89
+ payload: payload
90
+ }
91
+ })
92
+ )
93
+
94
+ const iframeElement = document.getElementById('mesh-link-popup__iframe')
95
+ expect(iframeElement).toBeFalsy()
96
+
97
+ expect(exitFunction).toBeCalledWith('some msg', payload)
98
+ }
99
+ )
100
+
101
+ test('createLink "brokerageAccountAccessToken" event should send tokens', () => {
102
+ const onEventHandler = jest.fn<void, [LinkEventType]>()
103
+ const onBrokerConnectedHandler = jest.fn<void, [LinkPayload]>()
104
+ const frontConnection = createLink({
105
+ clientId: 'test',
106
+ onIntegrationConnected: onBrokerConnectedHandler,
107
+ onEvent: onEventHandler
108
+ })
109
+
110
+ frontConnection.openLink(BASE64_ENCODED_URL)
111
+
112
+ const payload: AccessTokenPayload = {
113
+ accountTokens: [],
114
+ brokerBrandInfo: { brokerLogo: '' },
115
+ brokerType: 'robinhood',
116
+ brokerName: 'R'
117
+ }
118
+ window.dispatchEvent(
119
+ new MessageEvent<EventPayload>('message', {
120
+ data: {
121
+ type: 'brokerageAccountAccessToken',
122
+ payload: payload
123
+ }
124
+ })
125
+ )
126
+
127
+ expect(onEventHandler).toBeCalledWith({
128
+ type: 'integrationConnected',
129
+ payload: { accessToken: payload }
130
+ })
131
+ expect(onBrokerConnectedHandler).toBeCalledWith({ accessToken: payload })
132
+ })
133
+
134
+ test('createLink "delayedAuthentication" event should send dalayed tokens', () => {
135
+ const onEventHandler = jest.fn<void, [LinkEventType]>()
136
+ const onBrokerConnectedHandler = jest.fn<void, [LinkPayload]>()
137
+ const frontConnection = createLink({
138
+ clientId: 'test',
139
+ onIntegrationConnected: onBrokerConnectedHandler,
140
+ onEvent: onEventHandler
141
+ })
142
+
143
+ frontConnection.openLink(BASE64_ENCODED_URL)
144
+
145
+ const payload: DelayedAuthPayload = {
146
+ brokerBrandInfo: { brokerLogo: '' },
147
+ brokerType: 'robinhood',
148
+ brokerName: 'R',
149
+ refreshToken: 'rt'
150
+ }
151
+ window.dispatchEvent(
152
+ new MessageEvent<EventPayload>('message', {
153
+ data: {
154
+ type: 'delayedAuthentication',
155
+ payload: payload
156
+ }
157
+ })
158
+ )
159
+
160
+ expect(onEventHandler).toBeCalledWith({
161
+ type: 'integrationConnected',
162
+ payload: { delayedAuth: payload }
163
+ })
164
+ expect(onBrokerConnectedHandler).toBeCalledWith({ delayedAuth: payload })
165
+ })
166
+
167
+ test('createLink "transferFinished" event should send transfer payload', () => {
168
+ const onEventHandler = jest.fn<void, [LinkEventType]>()
169
+ const onTransferFinishedHandler = jest.fn<void, [TransferFinishedPayload]>()
170
+ const frontConnection = createLink({
171
+ clientId: 'test',
172
+ onIntegrationConnected: jest.fn(),
173
+ onEvent: onEventHandler,
174
+ onTransferFinished: onTransferFinishedHandler
175
+ })
176
+
177
+ frontConnection.openLink(BASE64_ENCODED_URL)
178
+
179
+ const payload: TransferFinishedPayload = {
180
+ status: 'success',
181
+ txId: 'tid',
182
+ fromAddress: 'fa',
183
+ toAddress: 'ta',
184
+ symbol: 'BTC',
185
+ amount: 0.001,
186
+ networkId: 'nid'
187
+ }
188
+ window.dispatchEvent(
189
+ new MessageEvent<EventPayload>('message', {
190
+ data: {
191
+ type: 'transferFinished',
192
+ payload: payload
193
+ }
194
+ })
195
+ )
196
+
197
+ expect(onEventHandler).toBeCalledWith({
198
+ type: 'transferCompleted',
199
+ payload: payload
200
+ })
201
+ expect(onTransferFinishedHandler).toBeCalledWith(payload)
202
+ })
203
+
204
+ test('createLink "oauthLinkOpen" event should open new window', () => {
205
+ const frontConnection = createLink({
206
+ clientId: 'test',
207
+ onIntegrationConnected: jest.fn()
208
+ })
209
+
210
+ frontConnection.openLink(BASE64_ENCODED_URL)
211
+
212
+ window.dispatchEvent(
213
+ new MessageEvent<EventPayload>('message', {
214
+ data: {
215
+ type: 'oauthLinkOpen',
216
+ link: 'https://localhost/2'
217
+ }
218
+ })
219
+ )
220
+
221
+ expect(window.open).toBeCalledWith(
222
+ 'https://localhost/2',
223
+ '_blank',
224
+ 'popup,noopener,noreferrer,resizable,scrollbars,width=700,height=800,top=-400,left=-350'
225
+ )
226
+ })
227
+
228
+ test('createLink "loaded" event should trigger the passing for tokens', () => {
229
+ const tokens: IntegrationAccessToken[] = [
230
+ {
231
+ accessToken: 'at',
232
+ accountId: 'aid',
233
+ accountName: 'an',
234
+ brokerType: 'acorns',
235
+ brokerName: 'A'
236
+ }
237
+ ]
238
+ const destinationTokens: IntegrationAccessToken[] = [
239
+ {
240
+ accessToken: 'ttoken',
241
+ accountId: 'tid',
242
+ accountName: 'tname',
243
+ brokerType: 'acorns',
244
+ brokerName: 'tbrokername'
245
+ }
246
+ ]
247
+ const frontConnection = createLink({
248
+ clientId: 'test',
249
+ onIntegrationConnected: jest.fn(),
250
+ accessTokens: tokens,
251
+ transferDestinationTokens: destinationTokens
252
+ })
253
+
254
+ frontConnection.openLink(BASE64_ENCODED_URL)
255
+
256
+ const iframeElement = document.getElementById(
257
+ 'mesh-link-popup__iframe'
258
+ ) as HTMLIFrameElement | null
259
+ expect(iframeElement?.contentWindow).toBeTruthy()
260
+
261
+ const postMessageSpy = jest.spyOn(
262
+ iframeElement?.contentWindow as Window,
263
+ 'postMessage'
264
+ )
265
+
266
+ window.dispatchEvent(
267
+ new MessageEvent<EventPayload>('message', {
268
+ data: {
269
+ type: 'loaded'
270
+ }
271
+ })
272
+ )
273
+
274
+ const packageJSONContent = JSON.parse(
275
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
276
+ require('fs').readFileSync('package.json', 'utf8')
277
+ )
278
+ expect(postMessageSpy).toBeCalledWith(
279
+ {
280
+ type: 'meshSDKSpecs',
281
+ payload: {
282
+ platform: 'web',
283
+ version: packageJSONContent.version
284
+ }
285
+ },
286
+ 'http://localhost'
287
+ )
288
+
289
+ expect(postMessageSpy).toBeCalledWith(
290
+ { type: 'frontAccessTokens', payload: tokens },
291
+ 'http://localhost'
292
+ )
293
+
294
+ expect(postMessageSpy).toBeCalledWith(
295
+ { type: 'frontTransferDestinationTokens', payload: destinationTokens },
296
+ 'http://localhost'
297
+ )
298
+ })
299
+
300
+ test('createLink "integrationConnected" event should send event', () => {
301
+ const onEventHandler = jest.fn<void, [LinkEventType]>()
302
+ const frontConnection = createLink({
303
+ clientId: 'test',
304
+ onIntegrationConnected: jest.fn(),
305
+ onEvent: onEventHandler
306
+ })
307
+
308
+ frontConnection.openLink(BASE64_ENCODED_URL)
309
+
310
+ window.dispatchEvent(
311
+ new MessageEvent('message', {
312
+ data: {
313
+ type: 'integrationConnected'
314
+ }
315
+ })
316
+ )
317
+
318
+ expect(onEventHandler).toBeCalled()
319
+ })
320
+
321
+ test('createLink unknown event should not send any events', () => {
322
+ const onEventHandler = jest.fn<void, [LinkEventType]>()
323
+ const frontConnection = createLink({
324
+ clientId: 'test',
325
+ onIntegrationConnected: jest.fn(),
326
+ onEvent: onEventHandler
327
+ })
328
+
329
+ frontConnection.openLink(BASE64_ENCODED_URL)
330
+
331
+ window.dispatchEvent(
332
+ new MessageEvent('message', {
333
+ data: {
334
+ type: 'unknown'
335
+ }
336
+ })
337
+ )
338
+
339
+ expect(onEventHandler).not.toBeCalled()
340
+ })
341
+
342
+ test('createLink "brokerageAccountAccessToken" event should send tokens - used with openLink function', () => {
343
+ const onEventHandler = jest.fn<void, [LinkEventType]>()
344
+ const onBrokerConnectedHandler = jest.fn<void, [LinkPayload]>()
345
+ const frontConnection = createLink({
346
+ clientId: 'test',
347
+ onIntegrationConnected: onBrokerConnectedHandler,
348
+ onEvent: onEventHandler
349
+ })
350
+
351
+ frontConnection.openLink(
352
+ Buffer.from('http://localhost/1').toString('base64')
353
+ )
354
+
355
+ const payload: AccessTokenPayload = {
356
+ accountTokens: [],
357
+ brokerBrandInfo: { brokerLogo: '' },
358
+ brokerType: 'robinhood',
359
+ brokerName: 'R'
360
+ }
361
+ window.dispatchEvent(
362
+ new MessageEvent<EventPayload>('message', {
363
+ data: {
364
+ type: 'brokerageAccountAccessToken',
365
+ payload: payload
366
+ }
367
+ })
368
+ )
369
+
370
+ expect(onEventHandler).toBeCalledWith({
371
+ type: 'integrationConnected',
372
+ payload: { accessToken: payload }
373
+ })
374
+ expect(onBrokerConnectedHandler).toBeCalledWith({ accessToken: payload })
375
+ })
376
+
377
+ test('createLink closeLink should close popup', () => {
378
+ const exitFunction = jest.fn<void, [string | undefined]>()
379
+ const frontConnection = createLink({
380
+ clientId: 'test',
381
+ onIntegrationConnected: jest.fn(),
382
+ onExit: exitFunction
383
+ })
384
+
385
+ frontConnection.openLink(
386
+ Buffer.from('http://localhost/1').toString('base64')
387
+ )
388
+ frontConnection.closeLink()
389
+
390
+ const iframeElement = document.getElementById('mesh-link-popup__iframe')
391
+ expect(iframeElement).toBeFalsy()
392
+
393
+ expect(exitFunction).toBeCalled()
394
+ })
395
+ })