@meshconnect/web-link-sdk 2.0.1 → 2.0.4

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/Link.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { LinkOptions, Link } from './utils/types';
2
- export declare const createLink: (options: LinkOptions) => Link;
1
+ import { LinkOptions, Link } from './utils/types';
2
+ export declare const createLink: (options: LinkOptions) => Link;
package/Link.js CHANGED
@@ -1,145 +1,161 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- var __generator = (this && this.__generator) || function (thisArg, body) {
11
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
- function verb(n) { return function (v) { return step([n, v]); }; }
14
- function step(op) {
15
- if (f) throw new TypeError("Generator is already executing.");
16
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
- if (y = 0, t) op = [op[0] & 2, t.value];
19
- switch (op[0]) {
20
- case 0: case 1: t = op; break;
21
- case 4: _.label++; return { value: op[1], done: false };
22
- case 5: _.label++; y = op[1]; op = [0]; continue;
23
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
- default:
25
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
- if (t[2]) _.ops.pop();
30
- _.trys.pop(); continue;
31
- }
32
- op = body.call(thisArg, _);
33
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
- }
36
- };
37
- import { addPopup, iframeId, removePopup } from './utils/popup';
38
- import { isLinkEventTypeKey } from './utils/event-types';
39
- var currentOptions;
40
- var iframeUrlObject;
41
- var iframeElement = function () {
42
- return document.getElementById(iframeId);
43
- };
44
- function eventsListener(event) {
45
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
46
- switch (event.data.type) {
47
- case 'brokerageAccountAccessToken': {
48
- var payload = {
49
- accessToken: event.data.payload
50
- };
51
- (_a = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(currentOptions, {
52
- type: 'integrationConnected',
53
- payload: payload
54
- });
55
- (_b = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onIntegrationConnected) === null || _b === void 0 ? void 0 : _b.call(currentOptions, payload);
56
- break;
57
- }
58
- case 'delayedAuthentication': {
59
- var payload = {
60
- delayedAuth: event.data.payload
61
- };
62
- (_c = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _c === void 0 ? void 0 : _c.call(currentOptions, {
63
- type: 'integrationConnected',
64
- payload: payload
65
- });
66
- (_d = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onIntegrationConnected) === null || _d === void 0 ? void 0 : _d.call(currentOptions, payload);
67
- break;
68
- }
69
- case 'transferFinished': {
70
- var payload = event.data.payload;
71
- (_e = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _e === void 0 ? void 0 : _e.call(currentOptions, {
72
- type: 'transferCompleted',
73
- payload: payload
74
- });
75
- (_f = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onTransferFinished) === null || _f === void 0 ? void 0 : _f.call(currentOptions, payload);
76
- break;
77
- }
78
- case 'close':
79
- case 'done': {
80
- var payload = (_g = event.data) === null || _g === void 0 ? void 0 : _g.payload;
81
- (_h = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onExit) === null || _h === void 0 ? void 0 : _h.call(currentOptions, payload.errorMessage, payload);
82
- removePopup();
83
- break;
84
- }
85
- case 'oauthLinkOpen': {
86
- if (event.data.link) {
87
- var w = 700;
88
- var h = 800;
89
- var left = screen.width / 2 - w / 2;
90
- var top_1 = screen.height / 2 - h / 2;
91
- (_j = window
92
- .open(event.data.link, '_blank', "popup,noopener,noreferrer,resizable,scrollbars,width=".concat(w, ",height=").concat(h, ",top=").concat(top_1, ",left=").concat(left))) === null || _j === void 0 ? void 0 : _j.focus();
93
- }
94
- break;
95
- }
96
- case 'loaded': {
97
- if (currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.accessTokens) {
98
- (_k = iframeElement().contentWindow) === null || _k === void 0 ? void 0 : _k.postMessage({ type: 'frontAccessTokens', payload: currentOptions.accessTokens }, (iframeUrlObject === null || iframeUrlObject === void 0 ? void 0 : iframeUrlObject.origin) || 'https://web.meshconnect.com');
99
- }
100
- if (currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.transferDestinationTokens) {
101
- (_l = iframeElement().contentWindow) === null || _l === void 0 ? void 0 : _l.postMessage({
102
- type: 'frontTransferDestinationTokens',
103
- payload: currentOptions.transferDestinationTokens
104
- }, (iframeUrlObject === null || iframeUrlObject === void 0 ? void 0 : iframeUrlObject.origin) || 'https://web.meshconnect.com');
105
- }
106
- (_m = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _m === void 0 ? void 0 : _m.call(currentOptions, { type: 'pageLoaded' });
107
- break;
108
- }
109
- default: {
110
- if (isLinkEventTypeKey(event.data.type)) {
111
- (_o = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _o === void 0 ? void 0 : _o.call(currentOptions, event.data);
112
- }
113
- break;
114
- }
115
- }
116
- }
117
- export var createLink = function (options) {
118
- var openLink = function (linkToken) { return __awaiter(void 0, void 0, void 0, function () {
119
- var linkUrl;
120
- var _a;
121
- return __generator(this, function (_b) {
122
- if (!linkToken) {
123
- (_a = options === null || options === void 0 ? void 0 : options.onExit) === null || _a === void 0 ? void 0 : _a.call(options, 'Invalid link token!');
124
- return [2 /*return*/];
125
- }
126
- currentOptions = options;
127
- linkUrl = window.atob(linkToken);
128
- iframeUrlObject = new URL(linkUrl);
129
- window.removeEventListener('message', eventsListener);
130
- addPopup(linkUrl);
131
- window.addEventListener('message', eventsListener);
132
- return [2 /*return*/];
133
- });
134
- }); };
135
- var closeLink = function () {
136
- var _a;
137
- removePopup();
138
- window.removeEventListener('message', eventsListener);
139
- (_a = options.onExit) === null || _a === void 0 ? void 0 : _a.call(options);
140
- };
141
- return {
142
- openLink: openLink,
143
- closeLink: closeLink
144
- };
145
- };
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ import { addPopup, iframeId, removePopup } from './utils/popup';
49
+ import { isLinkEventTypeKey } from './utils/event-types';
50
+ import { sdkSpecs } from './utils/sdk-specs';
51
+ var currentOptions;
52
+ var iframeUrlObject;
53
+ var iframeElement = function () {
54
+ return document.getElementById(iframeId);
55
+ };
56
+ function eventsListener(event) {
57
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
58
+ switch (event.data.type) {
59
+ case 'brokerageAccountAccessToken': {
60
+ var payload = {
61
+ accessToken: event.data.payload
62
+ };
63
+ (_a = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _a === void 0 ? void 0 : _a.call(currentOptions, {
64
+ type: 'integrationConnected',
65
+ payload: payload
66
+ });
67
+ (_b = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onIntegrationConnected) === null || _b === void 0 ? void 0 : _b.call(currentOptions, payload);
68
+ break;
69
+ }
70
+ case 'delayedAuthentication': {
71
+ var payload = {
72
+ delayedAuth: event.data.payload
73
+ };
74
+ (_c = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _c === void 0 ? void 0 : _c.call(currentOptions, {
75
+ type: 'integrationConnected',
76
+ payload: payload
77
+ });
78
+ (_d = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onIntegrationConnected) === null || _d === void 0 ? void 0 : _d.call(currentOptions, payload);
79
+ break;
80
+ }
81
+ case 'transferFinished': {
82
+ var payload = event.data.payload;
83
+ (_e = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _e === void 0 ? void 0 : _e.call(currentOptions, {
84
+ type: 'transferCompleted',
85
+ payload: payload
86
+ });
87
+ (_f = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onTransferFinished) === null || _f === void 0 ? void 0 : _f.call(currentOptions, payload);
88
+ break;
89
+ }
90
+ case 'close':
91
+ case 'done': {
92
+ var payload = (_g = event.data) === null || _g === void 0 ? void 0 : _g.payload;
93
+ (_h = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onExit) === null || _h === void 0 ? void 0 : _h.call(currentOptions, payload === null || payload === void 0 ? void 0 : payload.errorMessage, payload);
94
+ removePopup();
95
+ break;
96
+ }
97
+ case 'oauthLinkOpen': {
98
+ if (event.data.link) {
99
+ var w = 700;
100
+ var h = 800;
101
+ var left = screen.width / 2 - w / 2;
102
+ var top_1 = screen.height / 2 - h / 2;
103
+ (_j = window
104
+ .open(event.data.link, '_blank', "popup,noopener,noreferrer,resizable,scrollbars,width=".concat(w, ",height=").concat(h, ",top=").concat(top_1, ",left=").concat(left))) === null || _j === void 0 ? void 0 : _j.focus();
105
+ }
106
+ break;
107
+ }
108
+ case 'loaded': {
109
+ (_k = iframeElement().contentWindow) === null || _k === void 0 ? void 0 : _k.postMessage({
110
+ type: 'meshSDKSpecs',
111
+ payload: __assign({}, sdkSpecs)
112
+ }, (iframeUrlObject === null || iframeUrlObject === void 0 ? void 0 : iframeUrlObject.origin) || 'https://web.meshconnect.com');
113
+ if (currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.accessTokens) {
114
+ (_l = iframeElement().contentWindow) === null || _l === void 0 ? void 0 : _l.postMessage({ type: 'frontAccessTokens', payload: currentOptions.accessTokens }, (iframeUrlObject === null || iframeUrlObject === void 0 ? void 0 : iframeUrlObject.origin) || 'https://web.meshconnect.com');
115
+ }
116
+ if (currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.transferDestinationTokens) {
117
+ (_m = iframeElement().contentWindow) === null || _m === void 0 ? void 0 : _m.postMessage({
118
+ type: 'frontTransferDestinationTokens',
119
+ payload: currentOptions.transferDestinationTokens
120
+ }, (iframeUrlObject === null || iframeUrlObject === void 0 ? void 0 : iframeUrlObject.origin) || 'https://web.meshconnect.com');
121
+ }
122
+ (_o = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _o === void 0 ? void 0 : _o.call(currentOptions, { type: 'pageLoaded' });
123
+ break;
124
+ }
125
+ default: {
126
+ if (isLinkEventTypeKey(event.data.type)) {
127
+ (_p = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.onEvent) === null || _p === void 0 ? void 0 : _p.call(currentOptions, event.data);
128
+ }
129
+ break;
130
+ }
131
+ }
132
+ }
133
+ export var createLink = function (options) {
134
+ var openLink = function (linkToken) { return __awaiter(void 0, void 0, void 0, function () {
135
+ var linkUrl;
136
+ var _a;
137
+ return __generator(this, function (_b) {
138
+ if (!linkToken) {
139
+ (_a = options === null || options === void 0 ? void 0 : options.onExit) === null || _a === void 0 ? void 0 : _a.call(options, 'Invalid link token!');
140
+ return [2 /*return*/];
141
+ }
142
+ currentOptions = options;
143
+ linkUrl = window.atob(linkToken);
144
+ iframeUrlObject = new URL(linkUrl);
145
+ window.removeEventListener('message', eventsListener);
146
+ addPopup(linkUrl);
147
+ window.addEventListener('message', eventsListener);
148
+ return [2 /*return*/];
149
+ });
150
+ }); };
151
+ var closeLink = function () {
152
+ var _a;
153
+ removePopup();
154
+ window.removeEventListener('message', eventsListener);
155
+ (_a = options.onExit) === null || _a === void 0 ? void 0 : _a.call(options);
156
+ };
157
+ return {
158
+ openLink: openLink,
159
+ closeLink: closeLink
160
+ };
161
+ };
package/README.md CHANGED
@@ -1,127 +1,120 @@
1
- # @meshconnect/web-link-sdk
2
-
3
- A client-side JS library for integrating with Mesh Connect
4
-
5
- ### Install
6
-
7
- With `npm`:
8
-
9
- ```
10
- npm install --save @meshconnect/web-link-sdk
11
- ```
12
-
13
- With `yarn`
14
-
15
- ```
16
- yarn add @meshconnect/web-link-sdk
17
- ```
18
-
19
- ### Getting Link token
20
-
21
- Link token should be obtained from the GET `/api/v1/linktoken` endpoint. Api reference for this request is available [here](https://integration-api.getfront.com/apireference#tag/Managed-Account-Authentication/paths/~1api~1v1~1linktoken/post). Request must be preformed from the server side because it requires the client secret. You will get the response in the following format:
22
-
23
- ```json
24
- {
25
- "content": {
26
- "linkToken": "{linktoken}"
27
- },
28
- },
29
- "status": "ok",
30
- "message": ""
31
- }
32
- ```
33
-
34
- You can use `linkToken` value from this response to open the popup window with `openLink` method.
35
-
36
- ### Generating connection method
37
-
38
- ```tsx
39
- import { createLink } from '@meshconnect/web-link-sdk';
40
-
41
- // ...
42
-
43
- const linkConnection = createLink({
44
- clientId: '<Your Mesh Connect Client Id>',
45
- onIntegrationConnected: (data: LinkPayload) => {
46
- // use broker account data
47
- },
48
- onExit: (error?: string) => {
49
- if (error) {
50
- // handle error
51
- } else {
52
- // ...
53
- }
54
- }
55
-
56
- ```
57
-
58
- ### Using connection to open auth link
59
-
60
- To open authentication link provided by Front Finance Integration API you need to call `openLink` method:
61
-
62
- ```tsx
63
- linkConnection.openLink(linkToken)
64
- ```
65
-
66
- ℹ️ See full source code example at [react-example/src/ui/Link.tsx](../../examples/react-example/src/ui/Link.tsx)
67
-
68
- ```tsx
69
- import {
70
- createLink,
71
- Link,
72
- LinkPayload
73
- } from '@meshconnect/web-link-sdk'
74
-
75
- // ...
76
-
77
- const [linkConnection, setLinkConnection] = useState<Link | null>(
78
- null
79
- )
80
-
81
- useEffect(() => {
82
- setLinkConnection(createLink(options))
83
- }, [])
84
-
85
- useEffect(() => {
86
- if (authLink) {
87
- linkConnection?.openLink(linkToken)
88
- }
89
- }, [linkConnection, authLink])
90
-
91
- return <></>
92
- ```
93
-
94
- ### Getting tokens
95
-
96
- After successfull authentication on the Link session, the popup will be closed and the broker tokens will be passed to the `onIntegrationConnected` function.
97
- `Link` instance will check if URL contains query parameters, load broker tokens and fire the events.
98
-
99
- ### Available Connection configuration options
100
-
101
- ℹ️ See [src/types/index.ts](src/utils/types.ts) for exported types.
102
-
103
- #### `createLink` arguments
104
-
105
- | key | type | description |
106
- |--------------------------|---------------------------------------------------------| ------------------------------------------------------------------------------------ |
107
- | `clientId` | `string` | Keys from https://dashboard.getfront.com/company/keys page |
108
- | `onIntegrationConnected` | `(payload: LinkPayload) => void` | Callback called when users connects their accounts |
109
- | `onExit` | `((error?: string \| undefined) => void) \| undefined` | Called if connection not happened |
110
- | `onTransferFinished` | `(payload: TransferFinishedPayload) => void` | Callback called when a crypto transfer is executed |
111
- | `onEvent` | `(payload: LinkEventType) => void` | A callback function that is called when various events occur within the Front iframe |
112
- | `accessTokens` | `IntegrationAccessToken[]` | An array of integration access tokens |
113
-
114
- #### `createLink` return value
115
-
116
- | key | type | description |
117
- | ------------ | -------------------------------------- | ------------------------------ |
118
- | `openLink` | `(linkToken: string) => Promise<void>` | Opens the Link UI popup |
119
- | `closeLink` | `() => Promise<void>` | Closes the Link UI popup |
120
-
121
- ### Using tokens
122
-
123
- You can use broker tokens to perform requests to get current balance, assets and execute transactions. Full API reference can be found [here](https://integration-api.meshconnect.com/apireference).
124
-
125
- ## Typescript support
126
-
127
- TypeScript definitions for `@meshconnect/web-link-sdk` are built into the npm package.
1
+ # @meshconnect/web-link-sdk
2
+
3
+ A client-side JS library for integrating with Mesh Connect
4
+
5
+ ### Install
6
+
7
+ With `npm`:
8
+
9
+ ```
10
+ npm install --save @meshconnect/web-link-sdk
11
+ ```
12
+
13
+ With `yarn`
14
+
15
+ ```
16
+ yarn add @meshconnect/web-link-sdk
17
+ ```
18
+
19
+ ### Getting Link token
20
+
21
+ Link token should be obtained from the GET `/api/v1/linktoken` endpoint. Api reference for this request is available [here](https://integration-api.getfront.com/apireference#tag/Managed-Account-Authentication/paths/~1api~1v1~1linktoken/post). Request must be preformed from the server side because it requires the client secret. You will get the response in the following format:
22
+
23
+ ```json
24
+ {
25
+ "content": {
26
+ "linkToken": "{linktoken}"
27
+ },
28
+ "status": "ok",
29
+ "message": ""
30
+ }
31
+ ```
32
+
33
+ You can use `linkToken` value from this response to open the popup window with `openLink` method.
34
+
35
+ ### Generating connection method
36
+
37
+ ```tsx
38
+ import { createLink } from '@meshconnect/web-link-sdk';
39
+
40
+ // ...
41
+
42
+ const linkConnection = createLink({
43
+ clientId: '<Your Mesh Connect Client Id>',
44
+ onIntegrationConnected: (data: LinkPayload) => {
45
+ // use broker account data
46
+ },
47
+ onExit: (error?: string) => {
48
+ if (error) {
49
+ // handle error
50
+ } else {
51
+ // ...
52
+ }
53
+ }
54
+
55
+ ```
56
+
57
+ ### Using connection to open auth link
58
+
59
+ To open authentication link provided by Front Finance Integration API you need to call `openLink` method:
60
+
61
+ ```tsx
62
+ linkConnection.openLink(linkToken)
63
+ ```
64
+
65
+ ℹ️ See full source code example at [react-example/src/ui/Link.tsx](../../examples/react-example/src/ui/Link.tsx)
66
+
67
+ ```tsx
68
+ import { createLink, Link, LinkPayload } from '@meshconnect/web-link-sdk'
69
+
70
+ // ...
71
+
72
+ const [linkConnection, setLinkConnection] = useState<Link | null>(null)
73
+
74
+ useEffect(() => {
75
+ setLinkConnection(createLink(options))
76
+ }, [])
77
+
78
+ useEffect(() => {
79
+ if (authLink) {
80
+ linkConnection?.openLink(linkToken)
81
+ }
82
+ }, [linkConnection, authLink])
83
+
84
+ return <></>
85
+ ```
86
+
87
+ ### Getting tokens
88
+
89
+ After successfull authentication on the Link session, the popup will be closed and the broker tokens will be passed to the `onIntegrationConnected` function.
90
+ `Link` instance will check if URL contains query parameters, load broker tokens and fire the events.
91
+
92
+ ### Available Connection configuration options
93
+
94
+ ℹ️ See [src/types/index.ts](src/utils/types.ts) for exported types.
95
+
96
+ #### `createLink` arguments
97
+
98
+ | key | type | description |
99
+ | ------------------------ | ------------------------------------------------------ | ------------------------------------------------------------------------------------ |
100
+ | `clientId` | `string` | Keys from https://dashboard.getfront.com/company/keys page |
101
+ | `onIntegrationConnected` | `(payload: LinkPayload) => void` | Callback called when users connects their accounts |
102
+ | `onExit` | `((error?: string \| undefined) => void) \| undefined` | Called if connection not happened |
103
+ | `onTransferFinished` | `(payload: TransferFinishedPayload) => void` | Callback called when a crypto transfer is executed |
104
+ | `onEvent` | `(payload: LinkEventType) => void` | A callback function that is called when various events occur within the Front iframe |
105
+ | `accessTokens` | `IntegrationAccessToken[]` | An array of integration access tokens |
106
+
107
+ #### `createLink` return value
108
+
109
+ | key | type | description |
110
+ | ----------- | -------------------------------------- | ------------------------ |
111
+ | `openLink` | `(linkToken: string) => Promise<void>` | Opens the Link UI popup |
112
+ | `closeLink` | `() => Promise<void>` | Closes the Link UI popup |
113
+
114
+ ### Using tokens
115
+
116
+ You can use broker tokens to perform requests to get current balance, assets and execute transactions. Full API reference can be found [here](https://integration-api.meshconnect.com/apireference).
117
+
118
+ ## Typescript support
119
+
120
+ TypeScript definitions for `@meshconnect/web-link-sdk` are built into the npm package.