@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
@@ -0,0 +1,50 @@
1
+ import { addPopup, removePopup } from './popup'
2
+
3
+ describe('Popup tests', () => {
4
+ test('addPopup should add correct popup', () => {
5
+ const link = 'https://some.domain?link_style=eyJpciI6IDIsICJpbyI6IDAuOH0='
6
+ addPopup(link)
7
+
8
+ const stylesElement = document.getElementById('mesh-link-popup__styles')
9
+ expect(stylesElement).toBeTruthy()
10
+ expect(stylesElement).toMatchSnapshot()
11
+
12
+ const popupElement = document.getElementById('mesh-link-popup')
13
+ expect(popupElement).toBeTruthy()
14
+
15
+ const iframeElement = document.getElementById('mesh-link-popup__iframe')
16
+ expect(iframeElement).toBeTruthy()
17
+ expect(iframeElement?.attributes.getNamedItem('src')?.nodeValue).toBe(link)
18
+ })
19
+
20
+ test('addPopup when popup already added should replace popup', () => {
21
+ addPopup('http://localhost/1')
22
+ addPopup('http://localhost/2')
23
+
24
+ const stylesElement = document.getElementById('mesh-link-popup__styles')
25
+ expect(stylesElement).toBeTruthy()
26
+
27
+ const popupElement = document.getElementById('mesh-link-popup')
28
+ expect(popupElement).toBeTruthy()
29
+
30
+ const iframeElement = document.getElementById('mesh-link-popup__iframe')
31
+ expect(iframeElement).toBeTruthy()
32
+ expect(iframeElement?.attributes.getNamedItem('src')?.nodeValue).toBe(
33
+ 'http://localhost/2'
34
+ )
35
+ })
36
+
37
+ test('removePopup should remove popup', () => {
38
+ addPopup('http://localhost/1')
39
+ removePopup()
40
+
41
+ const stylesElement = document.getElementById('mesh-link-popup__styles')
42
+ expect(stylesElement).toBeFalsy()
43
+
44
+ const popupElement = document.getElementById('mesh-link-popup')
45
+ expect(popupElement).toBeFalsy()
46
+
47
+ const iframeElement = document.getElementById('mesh-link-popup__iframe')
48
+ expect(iframeElement).toBeFalsy()
49
+ })
50
+ })
@@ -0,0 +1,132 @@
1
+ import { LinkStyle } from './types'
2
+ import { getLinkStyle, getNumber } from './style'
3
+
4
+ const popupId = 'mesh-link-popup'
5
+ const backdropId = 'mesh-link-popup__backdrop'
6
+ const popupContentId = 'mesh-link-popup__popup-content'
7
+ const stylesId = 'mesh-link-popup__styles'
8
+ export const iframeId = 'mesh-link-popup__iframe'
9
+
10
+ const getPopupHtml = (link: string) => `
11
+ <div id="${popupId}">
12
+ <div id="${backdropId}"></div>
13
+ <div id="${popupContentId}">
14
+ <iframe id="${iframeId}" src="${link}" allow="clipboard-read *; clipboard-write *" />
15
+ </div>
16
+ </div>
17
+ `
18
+
19
+ const getStyles = (style?: LinkStyle) => `
20
+ <style id="${stylesId}">
21
+ body {
22
+ position: fixed;
23
+ left: 0;
24
+ top: 0;
25
+ bottom: 0;
26
+ right: 0;
27
+ overflow: hidden;
28
+ }
29
+
30
+ #${popupId} {
31
+ all: unset;
32
+ position: fixed;
33
+ left: 0;
34
+ top: 0;
35
+ bottom: 0;
36
+ right: 0;
37
+ display: flex;
38
+ flex-direction: column;
39
+ align-items: center;
40
+ justify-content: center;
41
+ z-index: 10000;
42
+ }
43
+
44
+ #${backdropId} {
45
+ position: absolute;
46
+ left: 0;
47
+ top: 0;
48
+ bottom: 0;
49
+ right: 0;
50
+ z-index: 10000;
51
+ background: black;
52
+ opacity: ${getNumber(0.6, style?.io)};
53
+ }
54
+
55
+ #${popupContentId} {
56
+ position: absolute;
57
+ height: 80%;
58
+ max-height: 710px;
59
+ min-height: 685px;
60
+ margin: auto;
61
+ z-index: 10001;
62
+ width: 30%;
63
+ max-width: 430px;
64
+ min-width: 380px;
65
+ display: flex;
66
+ flex-direction: column;
67
+ border-radius: ${getNumber(24, style?.ir)}px;
68
+ background: white;
69
+ flex-grow: 1;
70
+ }
71
+
72
+ #${popupContentId} iframe {
73
+ border: none;
74
+ width: 100%;
75
+ flex-grow: 1;
76
+ border-radius: ${getNumber(24, style?.ir)}px;
77
+ }
78
+
79
+ @media only screen and (max-width: 768px) {
80
+ #${popupContentId} {
81
+ height: 100vh;
82
+ width: 100vw;
83
+ max-width: 100%;
84
+ min-width: 100%;
85
+ max-height: 100%;
86
+ min-height: 100%;
87
+ border-radius: 0px;
88
+ }
89
+
90
+ #${popupContentId} iframe {
91
+ border-radius: 0px;
92
+ }
93
+ }
94
+
95
+ @media only screen and (max-height: 710px) {
96
+ #${popupContentId} {
97
+ max-height: 100%;
98
+ min-height: 100%;
99
+ }
100
+ }
101
+ </style>
102
+ `
103
+
104
+ export function removePopup(): void {
105
+ const existingPopup = window.document.getElementById(popupId)
106
+ existingPopup?.parentElement?.removeChild(existingPopup)
107
+
108
+ const existingStyles = window.document.getElementById(stylesId)
109
+ existingStyles?.parentElement?.removeChild(existingStyles)
110
+ }
111
+
112
+ export function addPopup(iframeLink: string): void {
113
+ const style = getLinkStyle(iframeLink)
114
+ removePopup()
115
+ const popup = getPopupHtml(iframeLink)
116
+ const stylesElement = htmlToElement(getStyles(style))
117
+ if (stylesElement) {
118
+ window.document.head.appendChild(stylesElement)
119
+ }
120
+
121
+ const popupElement = htmlToElement(popup)
122
+ if (popupElement) {
123
+ window.document.body.appendChild(popupElement)
124
+ }
125
+ }
126
+
127
+ function htmlToElement(html: string): Node | null {
128
+ const template = document.createElement('template')
129
+ html = html.trim()
130
+ template.innerHTML = html
131
+ return template.content.firstChild
132
+ }
@@ -0,0 +1,17 @@
1
+ import { sdkSpecs } from './sdk-specs';
2
+
3
+ const sdkType = sdkSpecs
4
+
5
+ describe('SDK Specs', () => {
6
+ test('should return the correct SDK type', () => {
7
+ const packageJSONContent = JSON.parse(
8
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
9
+ require('fs').readFileSync('package.json', 'utf8')
10
+ );
11
+
12
+ expect(sdkType).toEqual({
13
+ platform: 'web',
14
+ version: packageJSONContent.version
15
+ });
16
+ })
17
+ })
@@ -0,0 +1,6 @@
1
+ import { sdkVersion } from './version'
2
+
3
+ export const sdkSpecs = {
4
+ platform: 'web',
5
+ version: sdkVersion
6
+ }
@@ -0,0 +1,33 @@
1
+ import { getLinkStyle, getNumber } from './style'
2
+
3
+ describe('Test style utils', () => {
4
+ test('verify function returns a style object', () => {
5
+ const link = 'https://some.domain?link_style=eyJpciI6IDI0LCAiaW8iOiAwLjF9'
6
+ const received = getLinkStyle(link)
7
+ expect(received).toEqual({ ir: 24, io: 0.1 })
8
+ })
9
+
10
+ test('verify function returns nothing on missing query param', () => {
11
+ const link = 'https://some.domain?other=12'
12
+ const received = getLinkStyle(link)
13
+ expect(received).toBeNull()
14
+ })
15
+
16
+ test('verify function returns nothing on wrong encoded value', () => {
17
+ const link = 'https://some.domain?link_style=eyJpciI6IDI0LCAiaW8iOiAwL'
18
+ const received = getLinkStyle(link)
19
+ expect(received).toBeUndefined()
20
+ })
21
+
22
+ test('verify function returns nothing on empty link', () => {
23
+ const link = ''
24
+ const received = getLinkStyle(link)
25
+ expect(received).toBeUndefined()
26
+ })
27
+
28
+ test('verify function returns correct number', () => {
29
+ expect(getNumber(10, 11)).toBe(11)
30
+ expect(getNumber(10, undefined)).toBe(10)
31
+ expect(getNumber(1, 0)).toBe(0)
32
+ })
33
+ })
@@ -0,0 +1,15 @@
1
+ import { LinkStyle } from './types'
2
+
3
+ export function getLinkStyle(url: string): LinkStyle | undefined {
4
+ try {
5
+ const params = new URLSearchParams(new URL(url).search)
6
+ const style = params.get('link_style')
7
+ return style && JSON.parse(window.atob(style))
8
+ } catch (e) {
9
+ return undefined
10
+ }
11
+ }
12
+
13
+ export function getNumber(def: number, value?: number): number {
14
+ return value !== undefined ? value : def
15
+ }
@@ -0,0 +1,156 @@
1
+ import type { BrokerType } from '@meshconnect/node-api'
2
+ import { SessionSymmary, LinkEventType } from './event-types'
3
+ import { Hash, Chain } from 'viem'
4
+
5
+ export type EventType =
6
+ | 'brokerageAccountAccessToken'
7
+ | 'delayedAuthentication'
8
+ | 'loaded'
9
+ | 'oauthLinkOpen'
10
+ | 'transferFinished'
11
+
12
+ export interface Link {
13
+ /**
14
+ * A function that takes linkToken parameter from `/api/v1/linktoken` endpoint as an input, and opens the Link UI popup
15
+ */
16
+ openLink: (linkToken: string) => Promise<void>
17
+ /**
18
+ * A function to close Link UI popup
19
+ */
20
+ closeLink: () => void
21
+ }
22
+
23
+ export interface AccountToken {
24
+ account: Account
25
+ accessToken: string
26
+ refreshToken?: string
27
+ }
28
+
29
+ export interface Account {
30
+ accountId: string
31
+ accountName: string
32
+ fund?: number
33
+ cash?: number
34
+ isReconnected?: boolean
35
+ }
36
+
37
+ export interface BrandInfo {
38
+ brokerLogo: string
39
+ brokerPrimaryColor?: string
40
+ }
41
+
42
+ export interface LinkPayload {
43
+ accessToken?: AccessTokenPayload
44
+ delayedAuth?: DelayedAuthPayload
45
+ }
46
+
47
+ export interface AccessTokenPayload {
48
+ accountTokens: AccountToken[]
49
+ brokerBrandInfo: BrandInfo
50
+ expiresInSeconds?: number
51
+ refreshTokenExpiresInSeconds?: number
52
+ brokerType: BrokerType
53
+ brokerName: string
54
+ }
55
+
56
+ export interface DelayedAuthPayload {
57
+ refreshTokenExpiresInSeconds?: number
58
+ brokerType: BrokerType
59
+ refreshToken: string
60
+ brokerName: string
61
+ brokerBrandInfo: BrandInfo
62
+ }
63
+
64
+ export interface TransferFinishedPayload {
65
+ status: 'success'
66
+ txId: string
67
+ fromAddress: string
68
+ toAddress: string
69
+ symbol: string
70
+ amount: number
71
+ networkId: string
72
+ }
73
+
74
+ export interface IntegrationAccessToken {
75
+ accountId: string
76
+ accountName: string
77
+ accessToken: string
78
+ brokerType: BrokerType
79
+ brokerName: string
80
+ }
81
+
82
+ export interface WagmiInjectedConnectorData {
83
+ id: string
84
+ name: string
85
+ type: string
86
+ icon?: string
87
+ uid: string
88
+ }
89
+
90
+ export interface ConnectReturnTypeAndTxHash {
91
+ accounts: string[]
92
+ chainId: number
93
+ txSigned: Hash
94
+ }
95
+
96
+ export interface IncomingConfig {
97
+ chains: Chain[]
98
+ transports: Record<number, string | string[]>
99
+ }
100
+
101
+ export interface AbiItem {
102
+ name: string
103
+ type: string
104
+ inputs: { name: string; type: string }[]
105
+ outputs?: { name: string; type: string }[]
106
+ stateMutability?: string
107
+ }
108
+
109
+ export type Abi = AbiItem[]
110
+
111
+ export interface LinkOptions {
112
+ /**
113
+ * Client ID that can be obtained at https://dashboard.meshconnect.com/company/keys
114
+ */
115
+ clientId: string
116
+
117
+ /**
118
+ * A callback function that is called when an integration is successfully connected.
119
+ * It receives a payload of type `LinkPayload`.
120
+ */
121
+ onIntegrationConnected: (payload: LinkPayload) => void
122
+
123
+ /**
124
+ * (Optional) A callback function that is called when the Front iframe is closed.
125
+ */
126
+ onExit?: (error?: string, summary?: SessionSymmary) => void
127
+
128
+ /**
129
+ * (Optional) A callback function that is called when a transfer is finished.
130
+ * It receives a payload of type `TransferFinishedPayload`.
131
+ */
132
+ onTransferFinished?: (payload: TransferFinishedPayload) => void
133
+
134
+ /**
135
+ * (Optional) A callback function that is called when various events occur within the Front iframe.
136
+ * It receives an object with type `LinkEventTypeKeys` indicating the event, and an optional 'payload' containing additional data.
137
+ */
138
+ onEvent?: (event: LinkEventType) => void
139
+
140
+ /**
141
+ * (Optional) An array of integration access tokens.
142
+ * These access tokens are used to initialize crypto transfers flow at 'Select asset step'
143
+ */
144
+ accessTokens?: IntegrationAccessToken[]
145
+
146
+ /**
147
+ * (Optional) An array of integration access tokens.
148
+ * Can be used to initialize the crypto transfers flow as an alternative to the target addresses.
149
+ */
150
+ transferDestinationTokens?: IntegrationAccessToken[]
151
+ }
152
+
153
+ export interface LinkStyle {
154
+ ir: number
155
+ io: number
156
+ }
@@ -0,0 +1 @@
1
+ export const sdkVersion = '2.1.0-rc.loc'