@kryptos_connect/mobile-sdk 1.0.0 → 1.0.3
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/README.md +341 -40
- package/dist/index.d.mts +16 -17
- package/dist/index.d.ts +16 -17
- package/dist/index.js +1866 -1406
- package/dist/index.mjs +1894 -1428
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// src/KryptosConnectButton.tsx
|
|
2
|
-
import
|
|
2
|
+
import React36 from "react";
|
|
3
3
|
import {
|
|
4
|
-
StyleSheet as
|
|
5
|
-
Text as
|
|
6
|
-
TouchableOpacity as
|
|
7
|
-
View as
|
|
4
|
+
StyleSheet as StyleSheet20,
|
|
5
|
+
Text as Text18,
|
|
6
|
+
TouchableOpacity as TouchableOpacity8,
|
|
7
|
+
View as View20
|
|
8
8
|
} from "react-native";
|
|
9
9
|
|
|
10
10
|
// src/assets/LogoIcon.tsx
|
|
@@ -46,6 +46,152 @@ var LogoIcon = ({ size = 36 }) => {
|
|
|
46
46
|
|
|
47
47
|
// src/contexts/KryptosContext.tsx
|
|
48
48
|
import React2 from "react";
|
|
49
|
+
|
|
50
|
+
// src/services/api.ts
|
|
51
|
+
import axios from "axios";
|
|
52
|
+
|
|
53
|
+
// src/config/index.ts
|
|
54
|
+
var getBaseUrl = () => {
|
|
55
|
+
return getGlobalBaseUrl() || "https://connect-api.kryptos.io/";
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// src/services/api.ts
|
|
59
|
+
var api = axios.create({
|
|
60
|
+
headers: {
|
|
61
|
+
"Content-Type": "application/json"
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
api.interceptors.request.use((config) => {
|
|
65
|
+
config.baseURL = getBaseUrl();
|
|
66
|
+
return config;
|
|
67
|
+
});
|
|
68
|
+
var SCOPES = "openid profile offline_access email portfolios:read transactions:read integrations:read tax:read accounting:read reports:read workspace:read users:read";
|
|
69
|
+
async function sendEmailOtp(linkToken, email, clientId) {
|
|
70
|
+
const res = await api.post(
|
|
71
|
+
"/v1/sendEmailOTP",
|
|
72
|
+
{
|
|
73
|
+
email,
|
|
74
|
+
purpose: "login",
|
|
75
|
+
clientId
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
headers: {
|
|
79
|
+
"X-LINK-TOKEN": linkToken
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
return res.data;
|
|
84
|
+
}
|
|
85
|
+
async function loginWithOtp(linkToken, email, code, clientId) {
|
|
86
|
+
const res = await api.post(
|
|
87
|
+
"/v1/loginUserUsingOTP",
|
|
88
|
+
{
|
|
89
|
+
email,
|
|
90
|
+
code,
|
|
91
|
+
clientId,
|
|
92
|
+
purpose: "login"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
headers: {
|
|
96
|
+
"X-LINK-TOKEN": linkToken
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
return res.data;
|
|
101
|
+
}
|
|
102
|
+
async function createAnonymousUser(linkToken, clientId) {
|
|
103
|
+
const res = await api.post(
|
|
104
|
+
"/link-token/login",
|
|
105
|
+
{ clientId },
|
|
106
|
+
{
|
|
107
|
+
headers: {
|
|
108
|
+
"X-LINK-TOKEN": linkToken
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
return res.data;
|
|
113
|
+
}
|
|
114
|
+
async function addUserIntegration(linkToken, integration) {
|
|
115
|
+
const res = await api.post(
|
|
116
|
+
"/integrations/keys",
|
|
117
|
+
{ keys: [...integration] },
|
|
118
|
+
{
|
|
119
|
+
headers: {
|
|
120
|
+
"X-LINK-TOKEN": linkToken
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
return res.data?.data;
|
|
125
|
+
}
|
|
126
|
+
async function giveUserConsent(linkToken) {
|
|
127
|
+
const res = await api.post(
|
|
128
|
+
"/consent",
|
|
129
|
+
{
|
|
130
|
+
granted_scopes: SCOPES
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
headers: {
|
|
134
|
+
"X-LINK-TOKEN": linkToken
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
return res.data?.data;
|
|
139
|
+
}
|
|
140
|
+
async function testCredentials(linkToken, data) {
|
|
141
|
+
const res = await api.post("/integrations/credentials/test", data, {
|
|
142
|
+
headers: {
|
|
143
|
+
"X-LINK-TOKEN": linkToken
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
return res.data?.data;
|
|
147
|
+
}
|
|
148
|
+
async function getSupportedProviders(linkToken) {
|
|
149
|
+
const res = await api.get("/integrations/providers", {
|
|
150
|
+
headers: {
|
|
151
|
+
"X-LINK-TOKEN": linkToken
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
return res.data?.data;
|
|
155
|
+
}
|
|
156
|
+
async function getUserIntegrations(linkToken) {
|
|
157
|
+
const res = await api.get("/integrations", {
|
|
158
|
+
headers: {
|
|
159
|
+
"X-LINK-TOKEN": linkToken
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
return res.data?.data;
|
|
163
|
+
}
|
|
164
|
+
async function getUserUsedChains(linkToken, address) {
|
|
165
|
+
const res = await api.get("/integrations/user-used-chain", {
|
|
166
|
+
headers: {
|
|
167
|
+
"X-LINK-TOKEN": linkToken
|
|
168
|
+
},
|
|
169
|
+
params: {
|
|
170
|
+
id: address
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
return res.data?.data?.chains || [];
|
|
174
|
+
}
|
|
175
|
+
async function getClientInfo(linkToken) {
|
|
176
|
+
const res = await api.get("/client", {
|
|
177
|
+
headers: {
|
|
178
|
+
"X-LINK-TOKEN": linkToken
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
return res.data?.data;
|
|
182
|
+
}
|
|
183
|
+
async function getUserInfo(linkToken) {
|
|
184
|
+
const res = await api.get("/link-token/session", {
|
|
185
|
+
headers: {
|
|
186
|
+
"X-LINK-TOKEN": linkToken
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
return res.data?.data;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/contexts/KryptosContext.tsx
|
|
193
|
+
var globalBaseUrl;
|
|
194
|
+
var getGlobalBaseUrl = () => globalBaseUrl;
|
|
49
195
|
var KryptosContext = React2.createContext(
|
|
50
196
|
void 0
|
|
51
197
|
);
|
|
@@ -57,6 +203,20 @@ var KryptosConnectProvider = ({ children, config }) => {
|
|
|
57
203
|
const [userConsent, setUserConsent] = React2.useState(
|
|
58
204
|
null
|
|
59
205
|
);
|
|
206
|
+
const [isAuthorized, setIsAuthorized] = React2.useState(false);
|
|
207
|
+
const [clientInfo, setClientInfo] = React2.useState(null);
|
|
208
|
+
React2.useEffect(() => {
|
|
209
|
+
globalBaseUrl = config.baseUrl;
|
|
210
|
+
}, [config.baseUrl]);
|
|
211
|
+
React2.useEffect(() => {
|
|
212
|
+
const fetchClientInfo = async () => {
|
|
213
|
+
if (linkToken) {
|
|
214
|
+
const res = await getClientInfo(linkToken);
|
|
215
|
+
setClientInfo(res);
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
fetchClientInfo();
|
|
219
|
+
}, [linkToken]);
|
|
60
220
|
return /* @__PURE__ */ React2.createElement(
|
|
61
221
|
KryptosContext.Provider,
|
|
62
222
|
{
|
|
@@ -71,7 +231,10 @@ var KryptosConnectProvider = ({ children, config }) => {
|
|
|
71
231
|
email,
|
|
72
232
|
setEmail,
|
|
73
233
|
userConsent,
|
|
74
|
-
setUserConsent
|
|
234
|
+
setUserConsent,
|
|
235
|
+
clientInfo,
|
|
236
|
+
isAuthorized,
|
|
237
|
+
setIsAuthorized
|
|
75
238
|
}
|
|
76
239
|
},
|
|
77
240
|
children
|
|
@@ -108,6 +271,7 @@ var lightTheme = {
|
|
|
108
271
|
successLight: "#D1FAE5",
|
|
109
272
|
warning: "#F59E0B",
|
|
110
273
|
warningLight: "#FEF3C7",
|
|
274
|
+
warningText: "#92400E",
|
|
111
275
|
overlay: "rgba(0, 0, 0, 0.5)",
|
|
112
276
|
white: "#FFFFFF",
|
|
113
277
|
black: "#000000"
|
|
@@ -187,6 +351,7 @@ var darkTheme = {
|
|
|
187
351
|
successLight: "#065F46",
|
|
188
352
|
warning: "#F59E0B",
|
|
189
353
|
warningLight: "#78350F",
|
|
354
|
+
warningText: "#FEF3C7",
|
|
190
355
|
overlay: "rgba(0, 0, 0, 0.7)",
|
|
191
356
|
white: "#FFFFFF",
|
|
192
357
|
black: "#000000"
|
|
@@ -232,198 +397,62 @@ var useTheme = () => {
|
|
|
232
397
|
return currentTheme;
|
|
233
398
|
};
|
|
234
399
|
|
|
235
|
-
// src/
|
|
236
|
-
import React12 from "react";
|
|
237
|
-
import { View as View5, Text as Text5, StyleSheet as StyleSheet5 } from "react-native";
|
|
238
|
-
|
|
239
|
-
// src/assets/LinkIcon.tsx
|
|
400
|
+
// src/components/Button.tsx
|
|
240
401
|
import React4 from "react";
|
|
241
|
-
import
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
strokeWidth: 2,
|
|
252
|
-
strokeLinecap: "round",
|
|
253
|
-
strokeLinejoin: "round"
|
|
254
|
-
}
|
|
255
|
-
), /* @__PURE__ */ React4.createElement(
|
|
256
|
-
Path2,
|
|
257
|
-
{
|
|
258
|
-
d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",
|
|
259
|
-
stroke: color,
|
|
260
|
-
strokeWidth: 2,
|
|
261
|
-
strokeLinecap: "round",
|
|
262
|
-
strokeLinejoin: "round"
|
|
263
|
-
}
|
|
264
|
-
));
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
// src/assets/ShieldIcon.tsx
|
|
268
|
-
import React5 from "react";
|
|
269
|
-
import Svg3, { Path as Path3 } from "react-native-svg";
|
|
270
|
-
var ShieldIcon = ({
|
|
271
|
-
size = 20,
|
|
272
|
-
color = "#00C693"
|
|
273
|
-
}) => {
|
|
274
|
-
return /* @__PURE__ */ React5.createElement(Svg3, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React5.createElement(
|
|
275
|
-
Path3,
|
|
276
|
-
{
|
|
277
|
-
d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",
|
|
278
|
-
stroke: color,
|
|
279
|
-
strokeWidth: 2,
|
|
280
|
-
strokeLinecap: "round",
|
|
281
|
-
strokeLinejoin: "round"
|
|
282
|
-
}
|
|
283
|
-
), /* @__PURE__ */ React5.createElement(
|
|
284
|
-
Path3,
|
|
285
|
-
{
|
|
286
|
-
d: "m9 12 2 2 4-4",
|
|
287
|
-
stroke: color,
|
|
288
|
-
strokeWidth: 2,
|
|
289
|
-
strokeLinecap: "round",
|
|
290
|
-
strokeLinejoin: "round"
|
|
291
|
-
}
|
|
292
|
-
));
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
// src/components/Alert.tsx
|
|
296
|
-
import React6 from "react";
|
|
297
|
-
import { StyleSheet, Text, View } from "react-native";
|
|
298
|
-
var Alert = ({
|
|
299
|
-
variant = "default",
|
|
402
|
+
import {
|
|
403
|
+
TouchableOpacity,
|
|
404
|
+
Text,
|
|
405
|
+
StyleSheet,
|
|
406
|
+
ActivityIndicator,
|
|
407
|
+
View
|
|
408
|
+
} from "react-native";
|
|
409
|
+
var Button = ({
|
|
410
|
+
variant = "primary",
|
|
411
|
+
size = "md",
|
|
300
412
|
children,
|
|
301
|
-
|
|
413
|
+
onPress,
|
|
414
|
+
disabled = false,
|
|
415
|
+
loading = false,
|
|
416
|
+
style,
|
|
417
|
+
textStyle
|
|
302
418
|
}) => {
|
|
303
419
|
const theme = useTheme();
|
|
304
420
|
const getVariantStyles = () => {
|
|
305
421
|
switch (variant) {
|
|
306
|
-
case "
|
|
422
|
+
case "primary":
|
|
307
423
|
return {
|
|
308
|
-
backgroundColor: theme.colors.
|
|
309
|
-
|
|
424
|
+
backgroundColor: disabled ? theme.colors.textTertiary : theme.colors.primary,
|
|
425
|
+
borderWidth: 0
|
|
310
426
|
};
|
|
311
|
-
|
|
427
|
+
case "secondary":
|
|
312
428
|
return {
|
|
313
|
-
backgroundColor: theme.colors.surface,
|
|
429
|
+
backgroundColor: disabled ? theme.colors.surfaceSecondary : theme.colors.surface,
|
|
430
|
+
borderWidth: 1,
|
|
314
431
|
borderColor: theme.colors.border
|
|
315
432
|
};
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
{
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
return /* @__PURE__ */ React6.createElement(
|
|
340
|
-
Text,
|
|
341
|
-
{
|
|
342
|
-
style: [
|
|
343
|
-
styles.description,
|
|
344
|
-
{
|
|
345
|
-
color: theme.colors.text,
|
|
346
|
-
fontSize: theme.fontSize.md
|
|
347
|
-
},
|
|
348
|
-
style
|
|
349
|
-
]
|
|
350
|
-
},
|
|
351
|
-
children
|
|
352
|
-
);
|
|
353
|
-
};
|
|
354
|
-
var styles = StyleSheet.create({
|
|
355
|
-
alert: {
|
|
356
|
-
borderWidth: 1,
|
|
357
|
-
marginVertical: 12
|
|
358
|
-
// theme.spacing.md - consistent alert spacing
|
|
359
|
-
},
|
|
360
|
-
title: {
|
|
361
|
-
fontWeight: "600",
|
|
362
|
-
marginBottom: 4
|
|
363
|
-
// theme.spacing.xs
|
|
364
|
-
},
|
|
365
|
-
description: {
|
|
366
|
-
lineHeight: 18,
|
|
367
|
-
textAlign: "center"
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
// src/components/Button.tsx
|
|
372
|
-
import React7 from "react";
|
|
373
|
-
import {
|
|
374
|
-
TouchableOpacity,
|
|
375
|
-
Text as Text2,
|
|
376
|
-
StyleSheet as StyleSheet2,
|
|
377
|
-
ActivityIndicator,
|
|
378
|
-
View as View2
|
|
379
|
-
} from "react-native";
|
|
380
|
-
var Button = ({
|
|
381
|
-
variant = "primary",
|
|
382
|
-
size = "md",
|
|
383
|
-
children,
|
|
384
|
-
onPress,
|
|
385
|
-
disabled = false,
|
|
386
|
-
loading = false,
|
|
387
|
-
style,
|
|
388
|
-
textStyle
|
|
389
|
-
}) => {
|
|
390
|
-
const theme = useTheme();
|
|
391
|
-
const getVariantStyles = () => {
|
|
392
|
-
switch (variant) {
|
|
393
|
-
case "primary":
|
|
394
|
-
return {
|
|
395
|
-
backgroundColor: disabled ? theme.colors.textTertiary : theme.colors.primary,
|
|
396
|
-
borderWidth: 0
|
|
397
|
-
};
|
|
398
|
-
case "secondary":
|
|
399
|
-
return {
|
|
400
|
-
backgroundColor: disabled ? theme.colors.surfaceSecondary : theme.colors.surface,
|
|
401
|
-
borderWidth: 1,
|
|
402
|
-
borderColor: theme.colors.border
|
|
403
|
-
};
|
|
404
|
-
case "outline":
|
|
405
|
-
return {
|
|
406
|
-
backgroundColor: "transparent",
|
|
407
|
-
borderWidth: 1,
|
|
408
|
-
borderColor: disabled ? theme.colors.textTertiary : theme.colors.primary
|
|
409
|
-
};
|
|
410
|
-
case "ghost":
|
|
411
|
-
return {
|
|
412
|
-
backgroundColor: "transparent",
|
|
413
|
-
borderWidth: 0
|
|
414
|
-
};
|
|
415
|
-
case "success":
|
|
416
|
-
return {
|
|
417
|
-
backgroundColor: disabled ? theme.colors.textTertiary : theme.colors.success,
|
|
418
|
-
borderWidth: 0
|
|
419
|
-
};
|
|
420
|
-
case "error":
|
|
421
|
-
return {
|
|
422
|
-
backgroundColor: disabled ? theme.colors.textTertiary : theme.colors.error,
|
|
423
|
-
borderWidth: 0
|
|
424
|
-
};
|
|
425
|
-
default:
|
|
426
|
-
return {};
|
|
433
|
+
case "outline":
|
|
434
|
+
return {
|
|
435
|
+
backgroundColor: "transparent",
|
|
436
|
+
borderWidth: 1,
|
|
437
|
+
borderColor: disabled ? theme.colors.textTertiary : theme.colors.primary
|
|
438
|
+
};
|
|
439
|
+
case "ghost":
|
|
440
|
+
return {
|
|
441
|
+
backgroundColor: "transparent",
|
|
442
|
+
borderWidth: 0
|
|
443
|
+
};
|
|
444
|
+
case "success":
|
|
445
|
+
return {
|
|
446
|
+
backgroundColor: disabled ? theme.colors.textTertiary : theme.colors.success,
|
|
447
|
+
borderWidth: 0
|
|
448
|
+
};
|
|
449
|
+
case "error":
|
|
450
|
+
return {
|
|
451
|
+
backgroundColor: disabled ? theme.colors.textTertiary : theme.colors.error,
|
|
452
|
+
borderWidth: 0
|
|
453
|
+
};
|
|
454
|
+
default:
|
|
455
|
+
return {};
|
|
427
456
|
}
|
|
428
457
|
};
|
|
429
458
|
const getTextColor = () => {
|
|
@@ -488,35 +517,35 @@ var Button = ({
|
|
|
488
517
|
}
|
|
489
518
|
};
|
|
490
519
|
const sizeStyles = getSizeStyles();
|
|
491
|
-
return /* @__PURE__ */
|
|
520
|
+
return /* @__PURE__ */ React4.createElement(
|
|
492
521
|
TouchableOpacity,
|
|
493
522
|
{
|
|
494
523
|
onPress,
|
|
495
524
|
disabled: disabled || loading,
|
|
496
525
|
activeOpacity: 0.7,
|
|
497
526
|
style: [
|
|
498
|
-
|
|
527
|
+
styles.button,
|
|
499
528
|
getVariantStyles(),
|
|
500
529
|
sizeStyles.button,
|
|
501
|
-
disabled &&
|
|
530
|
+
disabled && styles.disabled,
|
|
502
531
|
style
|
|
503
532
|
]
|
|
504
533
|
},
|
|
505
|
-
loading ? /* @__PURE__ */
|
|
506
|
-
|
|
534
|
+
loading ? /* @__PURE__ */ React4.createElement(ActivityIndicator, { size: "small", color: getTextColor() }) : typeof children === "string" ? /* @__PURE__ */ React4.createElement(
|
|
535
|
+
Text,
|
|
507
536
|
{
|
|
508
537
|
style: [
|
|
509
|
-
|
|
538
|
+
styles.text,
|
|
510
539
|
{ color: getTextColor() },
|
|
511
540
|
sizeStyles.text,
|
|
512
541
|
textStyle
|
|
513
542
|
]
|
|
514
543
|
},
|
|
515
544
|
children
|
|
516
|
-
) : /* @__PURE__ */
|
|
545
|
+
) : /* @__PURE__ */ React4.createElement(View, { style: styles.contentContainer }, children)
|
|
517
546
|
);
|
|
518
547
|
};
|
|
519
|
-
var
|
|
548
|
+
var styles = StyleSheet.create({
|
|
520
549
|
button: {
|
|
521
550
|
flexDirection: "row",
|
|
522
551
|
alignItems: "center",
|
|
@@ -537,162 +566,344 @@ var styles2 = StyleSheet2.create({
|
|
|
537
566
|
}
|
|
538
567
|
});
|
|
539
568
|
|
|
540
|
-
// src/components/
|
|
541
|
-
import
|
|
569
|
+
// src/components/Input.tsx
|
|
570
|
+
import React5 from "react";
|
|
542
571
|
import {
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
Text as
|
|
546
|
-
|
|
547
|
-
StyleSheet as StyleSheet3,
|
|
548
|
-
ScrollView,
|
|
549
|
-
KeyboardAvoidingView,
|
|
550
|
-
Platform,
|
|
551
|
-
Dimensions
|
|
572
|
+
View as View2,
|
|
573
|
+
TextInput,
|
|
574
|
+
Text as Text2,
|
|
575
|
+
StyleSheet as StyleSheet2
|
|
552
576
|
} from "react-native";
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
Path4,
|
|
563
|
-
{
|
|
564
|
-
d: "M15 5L5 15M5 5L15 15",
|
|
565
|
-
stroke: color,
|
|
566
|
-
strokeWidth: 2,
|
|
567
|
-
strokeLinecap: "round",
|
|
568
|
-
strokeLinejoin: "round"
|
|
569
|
-
}
|
|
570
|
-
));
|
|
571
|
-
};
|
|
572
|
-
|
|
573
|
-
// src/components/Modal.tsx
|
|
574
|
-
var { height: SCREEN_HEIGHT } = Dimensions.get("window");
|
|
575
|
-
var Modal = ({
|
|
576
|
-
isOpen,
|
|
577
|
-
onClose,
|
|
578
|
-
children,
|
|
579
|
-
size = "md",
|
|
580
|
-
closeOnOverlayClick = true,
|
|
581
|
-
disableClose = true,
|
|
582
|
-
style
|
|
577
|
+
var Input = ({
|
|
578
|
+
label,
|
|
579
|
+
error,
|
|
580
|
+
helperText,
|
|
581
|
+
status = "default",
|
|
582
|
+
containerStyle,
|
|
583
|
+
inputStyle,
|
|
584
|
+
labelStyle,
|
|
585
|
+
...props
|
|
583
586
|
}) => {
|
|
584
587
|
const theme = useTheme();
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
return { maxHeight: SCREEN_HEIGHT * 0.55 };
|
|
593
|
-
case "lg":
|
|
594
|
-
return { maxHeight: SCREEN_HEIGHT * 0.65 };
|
|
595
|
-
case "xl":
|
|
596
|
-
return { maxHeight: SCREEN_HEIGHT * 0.75 };
|
|
597
|
-
case "full":
|
|
598
|
-
return { maxHeight: SCREEN_HEIGHT * 0.85 };
|
|
588
|
+
const inputStatus = error ? "error" : status;
|
|
589
|
+
const getBorderColor = () => {
|
|
590
|
+
switch (inputStatus) {
|
|
591
|
+
case "error":
|
|
592
|
+
return theme.colors.error;
|
|
593
|
+
case "success":
|
|
594
|
+
return theme.colors.success;
|
|
599
595
|
default:
|
|
600
|
-
return
|
|
596
|
+
return theme.colors.border;
|
|
601
597
|
}
|
|
602
598
|
};
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
};
|
|
606
|
-
return /* @__PURE__ */ React9.createElement(
|
|
607
|
-
KeyboardAvoidingView,
|
|
599
|
+
return /* @__PURE__ */ React5.createElement(View2, { style: [styles2.wrapper, containerStyle] }, label && /* @__PURE__ */ React5.createElement(
|
|
600
|
+
Text2,
|
|
608
601
|
{
|
|
609
|
-
|
|
610
|
-
|
|
602
|
+
style: [
|
|
603
|
+
styles2.label,
|
|
604
|
+
{ color: theme.colors.text, fontSize: theme.fontSize.sm },
|
|
605
|
+
labelStyle
|
|
606
|
+
]
|
|
611
607
|
},
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
visible: isOpen,
|
|
616
|
-
transparent: true,
|
|
617
|
-
animationType: "none",
|
|
618
|
-
statusBarTranslucent: true,
|
|
619
|
-
onRequestClose: disableClose ? void 0 : onClose
|
|
620
|
-
},
|
|
621
|
-
/* @__PURE__ */ React9.createElement(
|
|
622
|
-
TouchableOpacity2,
|
|
623
|
-
{
|
|
624
|
-
activeOpacity: 1,
|
|
625
|
-
style: [styles3.overlay, { backgroundColor: theme.colors.overlay }],
|
|
626
|
-
onPress: handleOverlayPress
|
|
627
|
-
},
|
|
628
|
-
/* @__PURE__ */ React9.createElement(
|
|
629
|
-
View3,
|
|
630
|
-
{
|
|
631
|
-
style: [
|
|
632
|
-
styles3.container,
|
|
633
|
-
{
|
|
634
|
-
backgroundColor: theme.colors.background,
|
|
635
|
-
borderTopLeftRadius: theme.borderRadius.xl,
|
|
636
|
-
borderTopRightRadius: theme.borderRadius.xl,
|
|
637
|
-
...theme.shadow.lg,
|
|
638
|
-
paddingBottom: theme.spacing.xl
|
|
639
|
-
// 20
|
|
640
|
-
},
|
|
641
|
-
getSizeStyles(),
|
|
642
|
-
style
|
|
643
|
-
],
|
|
644
|
-
onStartShouldSetResponder: () => true
|
|
645
|
-
},
|
|
646
|
-
children
|
|
647
|
-
)
|
|
648
|
-
)
|
|
649
|
-
)
|
|
650
|
-
);
|
|
651
|
-
};
|
|
652
|
-
var ModalHeader = ({
|
|
653
|
-
children,
|
|
654
|
-
onClose,
|
|
655
|
-
showCloseButton = true,
|
|
656
|
-
style
|
|
657
|
-
}) => {
|
|
658
|
-
const theme = useTheme();
|
|
659
|
-
return /* @__PURE__ */ React9.createElement(
|
|
660
|
-
View3,
|
|
608
|
+
label
|
|
609
|
+
), /* @__PURE__ */ React5.createElement(
|
|
610
|
+
TextInput,
|
|
661
611
|
{
|
|
612
|
+
placeholderTextColor: theme.colors.textTertiary,
|
|
662
613
|
style: [
|
|
663
|
-
|
|
614
|
+
styles2.input,
|
|
664
615
|
{
|
|
665
|
-
|
|
616
|
+
backgroundColor: theme.colors.surface,
|
|
617
|
+
borderColor: getBorderColor(),
|
|
618
|
+
color: theme.colors.text,
|
|
619
|
+
fontSize: theme.fontSize.md,
|
|
620
|
+
borderRadius: theme.borderRadius.md,
|
|
666
621
|
paddingHorizontal: theme.spacing.lg,
|
|
667
622
|
paddingVertical: theme.spacing.md
|
|
668
623
|
},
|
|
669
|
-
|
|
624
|
+
inputStyle
|
|
625
|
+
],
|
|
626
|
+
...props
|
|
627
|
+
}
|
|
628
|
+
), error && /* @__PURE__ */ React5.createElement(
|
|
629
|
+
Text2,
|
|
630
|
+
{
|
|
631
|
+
style: [
|
|
632
|
+
styles2.error,
|
|
633
|
+
{ color: theme.colors.error, fontSize: theme.fontSize.sm }
|
|
670
634
|
]
|
|
671
635
|
},
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
636
|
+
error
|
|
637
|
+
), helperText && !error && /* @__PURE__ */ React5.createElement(
|
|
638
|
+
Text2,
|
|
639
|
+
{
|
|
640
|
+
style: [
|
|
641
|
+
styles2.helper,
|
|
642
|
+
{
|
|
643
|
+
color: theme.colors.textSecondary,
|
|
644
|
+
fontSize: theme.fontSize.sm
|
|
645
|
+
}
|
|
646
|
+
]
|
|
647
|
+
},
|
|
648
|
+
helperText
|
|
649
|
+
));
|
|
650
|
+
};
|
|
651
|
+
var styles2 = StyleSheet2.create({
|
|
652
|
+
wrapper: {
|
|
653
|
+
marginBottom: 16
|
|
654
|
+
// theme.spacing.lg - consistent form spacing
|
|
655
|
+
},
|
|
656
|
+
label: {
|
|
657
|
+
fontWeight: "500",
|
|
658
|
+
marginBottom: 8
|
|
659
|
+
// theme.spacing.sm
|
|
660
|
+
},
|
|
661
|
+
input: {
|
|
662
|
+
borderWidth: 1,
|
|
663
|
+
minHeight: 48
|
|
664
|
+
},
|
|
665
|
+
error: {
|
|
666
|
+
marginTop: 4
|
|
667
|
+
// theme.spacing.xs
|
|
668
|
+
},
|
|
669
|
+
helper: {
|
|
670
|
+
marginTop: 4
|
|
671
|
+
// theme.spacing.xs
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
// src/components/Alert.tsx
|
|
676
|
+
import React6 from "react";
|
|
677
|
+
import { StyleSheet as StyleSheet3, Text as Text3, View as View3 } from "react-native";
|
|
678
|
+
var Alert = ({
|
|
679
|
+
variant = "default",
|
|
680
|
+
children,
|
|
681
|
+
style
|
|
682
|
+
}) => {
|
|
683
|
+
const theme = useTheme();
|
|
684
|
+
const getVariantStyles = () => {
|
|
685
|
+
switch (variant) {
|
|
686
|
+
case "destructive":
|
|
687
|
+
return {
|
|
688
|
+
backgroundColor: theme.colors.errorLight,
|
|
689
|
+
borderColor: theme.colors.error
|
|
690
|
+
};
|
|
691
|
+
default:
|
|
692
|
+
return {
|
|
693
|
+
backgroundColor: theme.colors.surface,
|
|
694
|
+
borderColor: theme.colors.border
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
return /* @__PURE__ */ React6.createElement(
|
|
699
|
+
View3,
|
|
700
|
+
{
|
|
701
|
+
style: [
|
|
702
|
+
styles3.alert,
|
|
703
|
+
{
|
|
704
|
+
borderRadius: theme.borderRadius.md,
|
|
705
|
+
padding: theme.spacing.md
|
|
706
|
+
},
|
|
707
|
+
getVariantStyles(),
|
|
708
|
+
style
|
|
709
|
+
]
|
|
710
|
+
},
|
|
711
|
+
children
|
|
712
|
+
);
|
|
713
|
+
};
|
|
714
|
+
var AlertDescription = ({
|
|
715
|
+
children,
|
|
716
|
+
style
|
|
717
|
+
}) => {
|
|
718
|
+
const theme = useTheme();
|
|
719
|
+
return /* @__PURE__ */ React6.createElement(
|
|
720
|
+
Text3,
|
|
721
|
+
{
|
|
722
|
+
style: [
|
|
723
|
+
styles3.description,
|
|
724
|
+
{
|
|
725
|
+
color: theme.colors.text,
|
|
726
|
+
fontSize: theme.fontSize.md
|
|
727
|
+
},
|
|
728
|
+
style
|
|
729
|
+
]
|
|
730
|
+
},
|
|
731
|
+
children
|
|
732
|
+
);
|
|
733
|
+
};
|
|
734
|
+
var styles3 = StyleSheet3.create({
|
|
735
|
+
alert: {
|
|
736
|
+
borderWidth: 1,
|
|
737
|
+
marginVertical: 12
|
|
738
|
+
// theme.spacing.md - consistent alert spacing
|
|
739
|
+
},
|
|
740
|
+
title: {
|
|
741
|
+
fontWeight: "600",
|
|
742
|
+
marginBottom: 4
|
|
743
|
+
// theme.spacing.xs
|
|
744
|
+
},
|
|
745
|
+
description: {
|
|
746
|
+
lineHeight: 18,
|
|
747
|
+
textAlign: "center"
|
|
748
|
+
}
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
// src/components/Modal.tsx
|
|
752
|
+
import React8 from "react";
|
|
753
|
+
import {
|
|
754
|
+
Dimensions,
|
|
755
|
+
KeyboardAvoidingView,
|
|
756
|
+
Platform,
|
|
757
|
+
Modal as RNModal,
|
|
758
|
+
ScrollView,
|
|
759
|
+
StyleSheet as StyleSheet4,
|
|
760
|
+
Text as Text4,
|
|
761
|
+
TouchableOpacity as TouchableOpacity2,
|
|
762
|
+
View as View4
|
|
763
|
+
} from "react-native";
|
|
764
|
+
|
|
765
|
+
// src/assets/CloseIcon.tsx
|
|
766
|
+
import React7 from "react";
|
|
767
|
+
import Svg2, { Path as Path2 } from "react-native-svg";
|
|
768
|
+
var CloseIcon = ({
|
|
769
|
+
size = 20,
|
|
770
|
+
color = "#000"
|
|
771
|
+
}) => {
|
|
772
|
+
return /* @__PURE__ */ React7.createElement(Svg2, { width: size, height: size, viewBox: "0 0 20 20", fill: "none" }, /* @__PURE__ */ React7.createElement(
|
|
773
|
+
Path2,
|
|
774
|
+
{
|
|
775
|
+
d: "M15 5L5 15M5 5L15 15",
|
|
776
|
+
stroke: color,
|
|
777
|
+
strokeWidth: 2,
|
|
778
|
+
strokeLinecap: "round",
|
|
779
|
+
strokeLinejoin: "round"
|
|
780
|
+
}
|
|
781
|
+
));
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
// src/components/Modal.tsx
|
|
785
|
+
var { height: SCREEN_HEIGHT } = Dimensions.get("window");
|
|
786
|
+
var Modal = ({
|
|
787
|
+
isOpen,
|
|
788
|
+
onClose,
|
|
789
|
+
children,
|
|
790
|
+
size = "md",
|
|
791
|
+
closeOnOverlayClick = true,
|
|
792
|
+
disableClose = true,
|
|
793
|
+
style
|
|
794
|
+
}) => {
|
|
795
|
+
const theme = useTheme();
|
|
796
|
+
const getSizeStyles = () => {
|
|
797
|
+
switch (size) {
|
|
798
|
+
case "xs":
|
|
799
|
+
return { maxHeight: SCREEN_HEIGHT * 0.35 };
|
|
800
|
+
case "sm":
|
|
801
|
+
return { maxHeight: SCREEN_HEIGHT * 0.45 };
|
|
802
|
+
case "md":
|
|
803
|
+
return { maxHeight: SCREEN_HEIGHT * 0.55 };
|
|
804
|
+
case "lg":
|
|
805
|
+
return { maxHeight: SCREEN_HEIGHT * 0.65 };
|
|
806
|
+
case "xl":
|
|
807
|
+
return { maxHeight: SCREEN_HEIGHT * 0.75 };
|
|
808
|
+
case "full":
|
|
809
|
+
return { maxHeight: SCREEN_HEIGHT * 0.85 };
|
|
810
|
+
default:
|
|
811
|
+
return { maxHeight: SCREEN_HEIGHT * 0.6 };
|
|
812
|
+
}
|
|
813
|
+
};
|
|
814
|
+
const handleOverlayPress = () => {
|
|
815
|
+
if (!disableClose && closeOnOverlayClick) onClose();
|
|
816
|
+
};
|
|
817
|
+
return /* @__PURE__ */ React8.createElement(
|
|
818
|
+
KeyboardAvoidingView,
|
|
819
|
+
{
|
|
820
|
+
behavior: Platform.OS === "ios" ? "padding" : "height",
|
|
821
|
+
style: styles4.keyboardView
|
|
822
|
+
},
|
|
823
|
+
/* @__PURE__ */ React8.createElement(
|
|
824
|
+
RNModal,
|
|
825
|
+
{
|
|
826
|
+
visible: isOpen,
|
|
827
|
+
transparent: true,
|
|
828
|
+
animationType: "none",
|
|
829
|
+
statusBarTranslucent: true,
|
|
830
|
+
onRequestClose: disableClose ? void 0 : onClose
|
|
831
|
+
},
|
|
832
|
+
/* @__PURE__ */ React8.createElement(
|
|
833
|
+
TouchableOpacity2,
|
|
834
|
+
{
|
|
835
|
+
activeOpacity: 1,
|
|
836
|
+
style: [styles4.overlay, { backgroundColor: theme.colors.overlay }],
|
|
837
|
+
onPress: handleOverlayPress
|
|
838
|
+
},
|
|
839
|
+
/* @__PURE__ */ React8.createElement(
|
|
840
|
+
View4,
|
|
841
|
+
{
|
|
842
|
+
style: [
|
|
843
|
+
styles4.container,
|
|
844
|
+
{
|
|
845
|
+
backgroundColor: theme.colors.background,
|
|
846
|
+
borderTopLeftRadius: theme.borderRadius.xl,
|
|
847
|
+
borderTopRightRadius: theme.borderRadius.xl,
|
|
848
|
+
...theme.shadow.lg,
|
|
849
|
+
paddingBottom: theme.spacing.xl
|
|
850
|
+
// 20
|
|
851
|
+
},
|
|
852
|
+
getSizeStyles(),
|
|
853
|
+
style
|
|
854
|
+
],
|
|
855
|
+
onStartShouldSetResponder: () => true
|
|
856
|
+
},
|
|
857
|
+
children
|
|
858
|
+
)
|
|
859
|
+
)
|
|
860
|
+
)
|
|
861
|
+
);
|
|
862
|
+
};
|
|
863
|
+
var ModalHeader = ({
|
|
864
|
+
children,
|
|
865
|
+
onClose,
|
|
866
|
+
showCloseButton = true,
|
|
867
|
+
style
|
|
868
|
+
}) => {
|
|
869
|
+
const theme = useTheme();
|
|
870
|
+
return /* @__PURE__ */ React8.createElement(
|
|
871
|
+
View4,
|
|
872
|
+
{
|
|
873
|
+
style: [
|
|
874
|
+
styles4.header,
|
|
875
|
+
{
|
|
876
|
+
borderBottomColor: theme.colors.border,
|
|
877
|
+
paddingHorizontal: theme.spacing.lg,
|
|
878
|
+
paddingVertical: theme.spacing.md
|
|
879
|
+
},
|
|
880
|
+
style
|
|
881
|
+
]
|
|
882
|
+
},
|
|
883
|
+
/* @__PURE__ */ React8.createElement(View4, { style: styles4.headerContent }, typeof children === "string" ? /* @__PURE__ */ React8.createElement(
|
|
884
|
+
Text4,
|
|
885
|
+
{
|
|
886
|
+
style: [
|
|
887
|
+
styles4.title,
|
|
888
|
+
{ color: theme.colors.text, fontSize: theme.fontSize.lg }
|
|
889
|
+
]
|
|
890
|
+
},
|
|
891
|
+
children
|
|
892
|
+
) : children),
|
|
893
|
+
showCloseButton && onClose && /* @__PURE__ */ React8.createElement(
|
|
894
|
+
TouchableOpacity2,
|
|
895
|
+
{
|
|
896
|
+
onPress: onClose,
|
|
897
|
+
hitSlop: { top: 10, bottom: 10, left: 10, right: 10 },
|
|
898
|
+
style: [
|
|
899
|
+
styles4.closeButton,
|
|
900
|
+
{ backgroundColor: theme.colors.surface }
|
|
901
|
+
]
|
|
902
|
+
},
|
|
903
|
+
/* @__PURE__ */ React8.createElement(CloseIcon, { color: theme.colors.text, size: 20 })
|
|
904
|
+
)
|
|
905
|
+
);
|
|
906
|
+
};
|
|
696
907
|
var ModalBody = ({
|
|
697
908
|
children,
|
|
698
909
|
style,
|
|
@@ -700,12 +911,12 @@ var ModalBody = ({
|
|
|
700
911
|
}) => {
|
|
701
912
|
const theme = useTheme();
|
|
702
913
|
if (scrollable) {
|
|
703
|
-
return /* @__PURE__ */
|
|
914
|
+
return /* @__PURE__ */ React8.createElement(
|
|
704
915
|
ScrollView,
|
|
705
916
|
{
|
|
706
|
-
style:
|
|
917
|
+
style: styles4.bodyScroll,
|
|
707
918
|
contentContainerStyle: [
|
|
708
|
-
|
|
919
|
+
styles4.bodyContent,
|
|
709
920
|
{ padding: theme.spacing.lg },
|
|
710
921
|
style
|
|
711
922
|
],
|
|
@@ -715,18 +926,18 @@ var ModalBody = ({
|
|
|
715
926
|
children
|
|
716
927
|
);
|
|
717
928
|
}
|
|
718
|
-
return /* @__PURE__ */
|
|
929
|
+
return /* @__PURE__ */ React8.createElement(View4, { style: [styles4.body, { padding: theme.spacing.lg }, style] }, children);
|
|
719
930
|
};
|
|
720
931
|
var ModalFooter = ({
|
|
721
932
|
children,
|
|
722
933
|
style
|
|
723
934
|
}) => {
|
|
724
935
|
const theme = useTheme();
|
|
725
|
-
return /* @__PURE__ */
|
|
726
|
-
|
|
936
|
+
return /* @__PURE__ */ React8.createElement(
|
|
937
|
+
View4,
|
|
727
938
|
{
|
|
728
939
|
style: [
|
|
729
|
-
|
|
940
|
+
styles4.footer,
|
|
730
941
|
{
|
|
731
942
|
borderTopColor: theme.colors.border,
|
|
732
943
|
paddingHorizontal: theme.spacing.lg,
|
|
@@ -738,7 +949,7 @@ var ModalFooter = ({
|
|
|
738
949
|
children
|
|
739
950
|
);
|
|
740
951
|
};
|
|
741
|
-
var
|
|
952
|
+
var styles4 = StyleSheet4.create({
|
|
742
953
|
keyboardView: {
|
|
743
954
|
flex: 1
|
|
744
955
|
},
|
|
@@ -791,745 +1002,770 @@ var styles3 = StyleSheet3.create({
|
|
|
791
1002
|
flex: 1
|
|
792
1003
|
},
|
|
793
1004
|
footer: {
|
|
794
|
-
borderTopWidth: 1
|
|
1005
|
+
borderTopWidth: 1,
|
|
1006
|
+
marginBottom: 24
|
|
795
1007
|
}
|
|
796
1008
|
});
|
|
797
1009
|
|
|
798
|
-
// src/
|
|
799
|
-
import
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
"X-LINK-TOKEN": linkToken
|
|
823
|
-
}
|
|
824
|
-
}
|
|
1010
|
+
// src/components/OTP.tsx
|
|
1011
|
+
import React9 from "react";
|
|
1012
|
+
import {
|
|
1013
|
+
View as View5,
|
|
1014
|
+
TextInput as TextInput2,
|
|
1015
|
+
Text as Text5,
|
|
1016
|
+
StyleSheet as StyleSheet5
|
|
1017
|
+
} from "react-native";
|
|
1018
|
+
var OTP = ({
|
|
1019
|
+
length = 6,
|
|
1020
|
+
value = "",
|
|
1021
|
+
onChange,
|
|
1022
|
+
onComplete,
|
|
1023
|
+
error,
|
|
1024
|
+
label,
|
|
1025
|
+
disabled = false,
|
|
1026
|
+
containerStyle,
|
|
1027
|
+
inputStyle,
|
|
1028
|
+
setErrorMessage
|
|
1029
|
+
}) => {
|
|
1030
|
+
const theme = useTheme();
|
|
1031
|
+
const AUTO_SUBMIT_DELAY = 500;
|
|
1032
|
+
const [otp, setOtp] = React9.useState(
|
|
1033
|
+
value.split("").concat(Array(length).fill("")).slice(0, length)
|
|
825
1034
|
);
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
clientId,
|
|
835
|
-
purpose: "login"
|
|
836
|
-
},
|
|
837
|
-
{
|
|
838
|
-
headers: {
|
|
839
|
-
"X-LINK-TOKEN": linkToken
|
|
840
|
-
}
|
|
1035
|
+
const inputRefs = React9.useRef([]);
|
|
1036
|
+
React9.useEffect(() => {
|
|
1037
|
+
const isComplete = otp.every((digit) => digit !== "");
|
|
1038
|
+
let timer;
|
|
1039
|
+
if (isComplete && onComplete) {
|
|
1040
|
+
timer = setTimeout(() => {
|
|
1041
|
+
onComplete(otp.join(""));
|
|
1042
|
+
}, AUTO_SUBMIT_DELAY);
|
|
841
1043
|
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
1044
|
+
return () => {
|
|
1045
|
+
if (timer) clearTimeout(timer);
|
|
1046
|
+
};
|
|
1047
|
+
}, [otp, onComplete]);
|
|
1048
|
+
React9.useEffect(() => {
|
|
1049
|
+
setTimeout(() => {
|
|
1050
|
+
inputRefs.current[0]?.focus();
|
|
1051
|
+
}, 100);
|
|
1052
|
+
}, []);
|
|
1053
|
+
const handleChange = React9.useCallback(
|
|
1054
|
+
(index, val) => {
|
|
1055
|
+
if (disabled) return;
|
|
1056
|
+
setErrorMessage("");
|
|
1057
|
+
const numericValue = val.replace(/[^0-9]/g, "");
|
|
1058
|
+
const newValue = numericValue.slice(-1);
|
|
1059
|
+
if (val && !numericValue) {
|
|
1060
|
+
return;
|
|
852
1061
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
{ keys: [...integration] },
|
|
861
|
-
{
|
|
862
|
-
headers: {
|
|
863
|
-
"X-LINK-TOKEN": linkToken
|
|
1062
|
+
const newOtp = [...otp];
|
|
1063
|
+
newOtp[index] = newValue;
|
|
1064
|
+
setOtp(newOtp);
|
|
1065
|
+
const otpString = newOtp.join("");
|
|
1066
|
+
onChange?.(otpString);
|
|
1067
|
+
if (newValue && index < length - 1) {
|
|
1068
|
+
inputRefs.current[index + 1]?.focus();
|
|
864
1069
|
}
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
return res.data?.data;
|
|
868
|
-
}
|
|
869
|
-
async function giveUserConsent(linkToken) {
|
|
870
|
-
const res = await api.post(
|
|
871
|
-
"/consent",
|
|
872
|
-
{
|
|
873
|
-
granted_scopes: SCOPES
|
|
874
|
-
},
|
|
875
|
-
{
|
|
876
|
-
headers: {
|
|
877
|
-
"X-LINK-TOKEN": linkToken
|
|
1070
|
+
if (otpString.length === length && !otpString.includes("")) {
|
|
1071
|
+
onComplete?.(otpString);
|
|
878
1072
|
}
|
|
879
|
-
}
|
|
880
|
-
);
|
|
881
|
-
return res.data?.data;
|
|
882
|
-
}
|
|
883
|
-
async function testCredentials(linkToken, data) {
|
|
884
|
-
const res = await api.post("/integrations/credentials/test", data, {
|
|
885
|
-
headers: {
|
|
886
|
-
"X-LINK-TOKEN": linkToken
|
|
887
|
-
}
|
|
888
|
-
});
|
|
889
|
-
return res.data?.data;
|
|
890
|
-
}
|
|
891
|
-
async function getSupportedProviders(linkToken) {
|
|
892
|
-
const res = await api.get("/integrations/providers", {
|
|
893
|
-
headers: {
|
|
894
|
-
"X-LINK-TOKEN": linkToken
|
|
895
|
-
}
|
|
896
|
-
});
|
|
897
|
-
return res.data?.data;
|
|
898
|
-
}
|
|
899
|
-
async function getUserIntegrations(linkToken) {
|
|
900
|
-
const res = await api.get("/integrations", {
|
|
901
|
-
headers: {
|
|
902
|
-
"X-LINK-TOKEN": linkToken
|
|
903
|
-
}
|
|
904
|
-
});
|
|
905
|
-
return res.data?.data;
|
|
906
|
-
}
|
|
907
|
-
async function getUserUsedChains(linkToken, address) {
|
|
908
|
-
const res = await api.get("/integrations/user-used-chain", {
|
|
909
|
-
headers: {
|
|
910
|
-
"X-LINK-TOKEN": linkToken
|
|
911
1073
|
},
|
|
912
|
-
|
|
913
|
-
id: address
|
|
914
|
-
}
|
|
915
|
-
});
|
|
916
|
-
return res.data?.data?.chains || [];
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
// src/molecules/ConnectLogo.tsx
|
|
920
|
-
import React11, { isValidElement } from "react";
|
|
921
|
-
import {
|
|
922
|
-
Image,
|
|
923
|
-
StyleSheet as StyleSheet4,
|
|
924
|
-
Text as Text4,
|
|
925
|
-
View as View4
|
|
926
|
-
} from "react-native";
|
|
927
|
-
|
|
928
|
-
// src/assets/UnplugIcon.tsx
|
|
929
|
-
import React10 from "react";
|
|
930
|
-
import Svg5, { Path as Path5, Line } from "react-native-svg";
|
|
931
|
-
var UnplugIcon = ({
|
|
932
|
-
size = 24,
|
|
933
|
-
color = "#6B7280"
|
|
934
|
-
}) => {
|
|
935
|
-
return /* @__PURE__ */ React10.createElement(Svg5, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React10.createElement(
|
|
936
|
-
Path5,
|
|
937
|
-
{
|
|
938
|
-
d: "m19 5 3-3",
|
|
939
|
-
stroke: color,
|
|
940
|
-
strokeWidth: 2,
|
|
941
|
-
strokeLinecap: "round",
|
|
942
|
-
strokeLinejoin: "round"
|
|
943
|
-
}
|
|
944
|
-
), /* @__PURE__ */ React10.createElement(
|
|
945
|
-
Path5,
|
|
946
|
-
{
|
|
947
|
-
d: "m2 22 3-3",
|
|
948
|
-
stroke: color,
|
|
949
|
-
strokeWidth: 2,
|
|
950
|
-
strokeLinecap: "round",
|
|
951
|
-
strokeLinejoin: "round"
|
|
952
|
-
}
|
|
953
|
-
), /* @__PURE__ */ React10.createElement(
|
|
954
|
-
Path5,
|
|
955
|
-
{
|
|
956
|
-
d: "M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z",
|
|
957
|
-
stroke: color,
|
|
958
|
-
strokeWidth: 2,
|
|
959
|
-
strokeLinecap: "round",
|
|
960
|
-
strokeLinejoin: "round"
|
|
961
|
-
}
|
|
962
|
-
), /* @__PURE__ */ React10.createElement(
|
|
963
|
-
Path5,
|
|
964
|
-
{
|
|
965
|
-
d: "m18 12-6-6 2.3-2.3a2.4 2.4 0 0 1 3.4 0l2.6 2.6a2.4 2.4 0 0 1 0 3.4Z",
|
|
966
|
-
stroke: color,
|
|
967
|
-
strokeWidth: 2,
|
|
968
|
-
strokeLinecap: "round",
|
|
969
|
-
strokeLinejoin: "round"
|
|
970
|
-
}
|
|
971
|
-
), /* @__PURE__ */ React10.createElement(
|
|
972
|
-
Line,
|
|
973
|
-
{
|
|
974
|
-
x1: 7.5,
|
|
975
|
-
y1: 13.5,
|
|
976
|
-
x2: 10.5,
|
|
977
|
-
y2: 10.5,
|
|
978
|
-
stroke: color,
|
|
979
|
-
strokeWidth: 2,
|
|
980
|
-
strokeLinecap: "round"
|
|
981
|
-
}
|
|
982
|
-
));
|
|
983
|
-
};
|
|
984
|
-
|
|
985
|
-
// src/molecules/ConnectLogo.tsx
|
|
986
|
-
var KryptosLogo = () => {
|
|
987
|
-
const theme = useTheme();
|
|
988
|
-
return /* @__PURE__ */ React11.createElement(
|
|
989
|
-
View4,
|
|
990
|
-
{
|
|
991
|
-
style: [styles4.logoContainer, { backgroundColor: theme.colors.surface }]
|
|
992
|
-
},
|
|
993
|
-
/* @__PURE__ */ React11.createElement(LogoIcon, { size: 36 })
|
|
1074
|
+
[otp, length, onChange, onComplete, disabled]
|
|
994
1075
|
);
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
};
|
|
1007
|
-
const renderLogo = () => {
|
|
1008
|
-
if (isValidElement(appLogo)) {
|
|
1009
|
-
return appLogo;
|
|
1010
|
-
} else if (typeof appLogo === "string" && isValidUrl(appLogo)) {
|
|
1011
|
-
return /* @__PURE__ */ React11.createElement(
|
|
1012
|
-
Image,
|
|
1013
|
-
{
|
|
1014
|
-
source: { uri: appLogo },
|
|
1015
|
-
style: styles4.appLogoImage,
|
|
1016
|
-
resizeMode: "contain"
|
|
1017
|
-
}
|
|
1018
|
-
);
|
|
1019
|
-
} else if (typeof appLogo === "number" || typeof appLogo === "object" && appLogo !== null) {
|
|
1020
|
-
return /* @__PURE__ */ React11.createElement(
|
|
1021
|
-
Image,
|
|
1022
|
-
{
|
|
1023
|
-
source: appLogo,
|
|
1024
|
-
style: styles4.appLogoImage,
|
|
1025
|
-
resizeMode: "contain"
|
|
1076
|
+
const handleKeyPress = React9.useCallback(
|
|
1077
|
+
(index, e) => {
|
|
1078
|
+
if (disabled) return;
|
|
1079
|
+
if (e.nativeEvent.key === "Backspace") {
|
|
1080
|
+
if (!otp[index] && index > 0) {
|
|
1081
|
+
inputRefs.current[index - 1]?.focus();
|
|
1082
|
+
} else {
|
|
1083
|
+
const newOtp = [...otp];
|
|
1084
|
+
newOtp[index] = "";
|
|
1085
|
+
setOtp(newOtp);
|
|
1086
|
+
onChange?.(newOtp.join(""));
|
|
1026
1087
|
}
|
|
1027
|
-
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
1090
|
+
[otp, onChange, disabled]
|
|
1091
|
+
);
|
|
1092
|
+
const getBorderColor = (index) => {
|
|
1093
|
+
if (error) return theme.colors.error;
|
|
1094
|
+
if (otp[index]) return theme.colors.success;
|
|
1095
|
+
return theme.colors.border;
|
|
1032
1096
|
};
|
|
1033
|
-
return /* @__PURE__ */
|
|
1034
|
-
|
|
1097
|
+
return /* @__PURE__ */ React9.createElement(View5, { style: [styles5.wrapper, containerStyle] }, label && /* @__PURE__ */ React9.createElement(
|
|
1098
|
+
Text5,
|
|
1035
1099
|
{
|
|
1036
1100
|
style: [
|
|
1037
|
-
|
|
1038
|
-
{
|
|
1101
|
+
styles5.label,
|
|
1102
|
+
{ color: theme.colors.text, fontSize: theme.fontSize.sm }
|
|
1039
1103
|
]
|
|
1040
1104
|
},
|
|
1041
|
-
|
|
1042
|
-
))
|
|
1043
|
-
|
|
1044
|
-
var styles4 = StyleSheet4.create({
|
|
1045
|
-
container: {
|
|
1046
|
-
flexDirection: "row",
|
|
1047
|
-
alignItems: "center",
|
|
1048
|
-
justifyContent: "center",
|
|
1049
|
-
marginVertical: 24,
|
|
1050
|
-
// theme.spacing.xxl
|
|
1051
|
-
gap: 12
|
|
1052
|
-
// theme.spacing.md
|
|
1053
|
-
},
|
|
1054
|
-
logoContainer: {
|
|
1055
|
-
width: 56,
|
|
1056
|
-
height: 56,
|
|
1057
|
-
borderRadius: 12,
|
|
1058
|
-
// theme.borderRadius.md
|
|
1059
|
-
alignItems: "center",
|
|
1060
|
-
justifyContent: "center",
|
|
1061
|
-
overflow: "hidden"
|
|
1062
|
-
},
|
|
1063
|
-
iconContainer: {
|
|
1064
|
-
paddingHorizontal: 8
|
|
1065
|
-
// theme.spacing.sm
|
|
1066
|
-
},
|
|
1067
|
-
appLogoImage: {
|
|
1068
|
-
width: 32,
|
|
1069
|
-
height: 32
|
|
1070
|
-
},
|
|
1071
|
-
appLogoText: {
|
|
1072
|
-
fontSize: 24,
|
|
1073
|
-
// theme.fontSize.xxxl
|
|
1074
|
-
fontWeight: "700"
|
|
1075
|
-
}
|
|
1076
|
-
});
|
|
1077
|
-
|
|
1078
|
-
// src/molecules/Auth.tsx
|
|
1079
|
-
var Auth = ({
|
|
1080
|
-
open,
|
|
1081
|
-
onEmailSuccess,
|
|
1082
|
-
onGuestSuccess,
|
|
1083
|
-
onClose
|
|
1084
|
-
}) => {
|
|
1085
|
-
const { appName, linkToken, clientId, setUser, setEmail } = useKryptosConnect();
|
|
1086
|
-
const theme = useTheme();
|
|
1087
|
-
const [isLoading, setIsLoading] = React12.useState(false);
|
|
1088
|
-
const [errorMessage, setErrorMessage] = React12.useState("");
|
|
1089
|
-
const [emailValue, setEmailValue] = React12.useState("");
|
|
1090
|
-
const [emailError, setEmailError] = React12.useState("");
|
|
1091
|
-
const [loadingType, setLoadingType] = React12.useState(null);
|
|
1092
|
-
const validateEmail = (email) => {
|
|
1093
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1094
|
-
if (!email) {
|
|
1095
|
-
setEmailError("Email is required");
|
|
1096
|
-
return false;
|
|
1097
|
-
}
|
|
1098
|
-
if (!emailRegex.test(email)) {
|
|
1099
|
-
setEmailError("Invalid email address");
|
|
1100
|
-
return false;
|
|
1101
|
-
}
|
|
1102
|
-
setEmailError("");
|
|
1103
|
-
return true;
|
|
1104
|
-
};
|
|
1105
|
-
const handleClose = () => {
|
|
1106
|
-
onClose();
|
|
1107
|
-
setEmailValue("");
|
|
1108
|
-
setEmailError("");
|
|
1109
|
-
setErrorMessage("");
|
|
1110
|
-
};
|
|
1111
|
-
const handleEmailSubmit = async () => {
|
|
1112
|
-
if (!validateEmail(emailValue)) return;
|
|
1113
|
-
try {
|
|
1114
|
-
setIsLoading(true);
|
|
1115
|
-
setLoadingType("email");
|
|
1116
|
-
setErrorMessage("");
|
|
1117
|
-
await sendEmailOtp(linkToken, emailValue, clientId);
|
|
1118
|
-
setEmail(emailValue);
|
|
1119
|
-
setEmailError("");
|
|
1120
|
-
onEmailSuccess();
|
|
1121
|
-
} catch (error) {
|
|
1122
|
-
const err = error;
|
|
1123
|
-
setErrorMessage(
|
|
1124
|
-
err?.response?.data?.message || "Failed to send email OTP"
|
|
1125
|
-
);
|
|
1126
|
-
} finally {
|
|
1127
|
-
setIsLoading(false);
|
|
1128
|
-
setLoadingType(null);
|
|
1129
|
-
}
|
|
1130
|
-
};
|
|
1131
|
-
const handleContinueAsGuest = async () => {
|
|
1132
|
-
try {
|
|
1133
|
-
setIsLoading(true);
|
|
1134
|
-
setLoadingType("guest");
|
|
1135
|
-
setErrorMessage("");
|
|
1136
|
-
const res = await createAnonymousUser(linkToken, clientId);
|
|
1137
|
-
setUser(res);
|
|
1138
|
-
setEmailError("");
|
|
1139
|
-
onGuestSuccess();
|
|
1140
|
-
} catch (error) {
|
|
1141
|
-
const err = error;
|
|
1142
|
-
console.error(error);
|
|
1143
|
-
setErrorMessage(
|
|
1144
|
-
err?.response?.data?.message || "Failed to continue as guest"
|
|
1145
|
-
);
|
|
1146
|
-
} finally {
|
|
1147
|
-
setIsLoading(false);
|
|
1148
|
-
setLoadingType(null);
|
|
1149
|
-
}
|
|
1150
|
-
};
|
|
1151
|
-
const infoSections = [
|
|
1152
|
-
{
|
|
1153
|
-
icon: /* @__PURE__ */ React12.createElement(LinkIcon, { size: 20, color: theme.colors.primary }),
|
|
1154
|
-
title: "Simple and secure",
|
|
1155
|
-
text: "Connect your Web3 accounts with Kryptos in just a few clicks"
|
|
1156
|
-
},
|
|
1105
|
+
label
|
|
1106
|
+
), /* @__PURE__ */ React9.createElement(View5, { style: styles5.container }, Array.from({ length }, (_, index) => /* @__PURE__ */ React9.createElement(
|
|
1107
|
+
TextInput2,
|
|
1157
1108
|
{
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1109
|
+
key: index,
|
|
1110
|
+
ref: (el) => inputRefs.current[index] = el,
|
|
1111
|
+
style: [
|
|
1112
|
+
styles5.input,
|
|
1113
|
+
{
|
|
1114
|
+
backgroundColor: theme.colors.surface,
|
|
1115
|
+
borderColor: getBorderColor(index),
|
|
1116
|
+
color: theme.colors.text,
|
|
1117
|
+
fontSize: theme.fontSize.xxl,
|
|
1118
|
+
borderRadius: theme.borderRadius.md
|
|
1119
|
+
},
|
|
1120
|
+
inputStyle
|
|
1121
|
+
],
|
|
1122
|
+
keyboardType: "numeric",
|
|
1123
|
+
maxLength: 1,
|
|
1124
|
+
value: otp[index] || "",
|
|
1125
|
+
onChangeText: (val) => handleChange(index, val),
|
|
1126
|
+
onKeyPress: (e) => handleKeyPress(index, e),
|
|
1127
|
+
editable: !disabled,
|
|
1128
|
+
selectTextOnFocus: true,
|
|
1129
|
+
caretHidden: true
|
|
1161
1130
|
}
|
|
1162
|
-
|
|
1163
|
-
return /* @__PURE__ */ React12.createElement(Modal, { isOpen: open, onClose: handleClose, size: "full" }, /* @__PURE__ */ React12.createElement(ModalHeader, { onClose: handleClose }, ""), /* @__PURE__ */ React12.createElement(ModalBody, null, /* @__PURE__ */ React12.createElement(View5, { style: styles5.container }, /* @__PURE__ */ React12.createElement(Text5, { style: [styles5.title, { color: theme.colors.text }] }, "Connect ", appName, " to your Kryptos account"), /* @__PURE__ */ React12.createElement(ConnectLogo, null), infoSections.map((section, index) => /* @__PURE__ */ React12.createElement(View5, { key: `info-${index}`, style: styles5.infoSection }, /* @__PURE__ */ React12.createElement(View5, { style: styles5.infoIcon }, section.icon), /* @__PURE__ */ React12.createElement(View5, { style: styles5.infoContent }, /* @__PURE__ */ React12.createElement(Text5, { style: [styles5.infoTitle, { color: theme.colors.text }] }, section.title), /* @__PURE__ */ React12.createElement(
|
|
1131
|
+
))), error && /* @__PURE__ */ React9.createElement(
|
|
1164
1132
|
Text5,
|
|
1165
1133
|
{
|
|
1166
1134
|
style: [
|
|
1167
|
-
styles5.
|
|
1168
|
-
{ color: theme.colors.
|
|
1135
|
+
styles5.error,
|
|
1136
|
+
{ color: theme.colors.error, fontSize: theme.fontSize.sm }
|
|
1169
1137
|
]
|
|
1170
1138
|
},
|
|
1171
|
-
|
|
1172
|
-
))
|
|
1173
|
-
Text5,
|
|
1174
|
-
{
|
|
1175
|
-
style: {
|
|
1176
|
-
color: theme.colors.primary,
|
|
1177
|
-
textDecorationLine: "underline"
|
|
1178
|
-
}
|
|
1179
|
-
},
|
|
1180
|
-
"Privacy Policy"
|
|
1181
|
-
)), /* @__PURE__ */ React12.createElement(
|
|
1182
|
-
Button,
|
|
1183
|
-
{
|
|
1184
|
-
variant: "outline",
|
|
1185
|
-
size: "lg",
|
|
1186
|
-
onPress: handleContinueAsGuest,
|
|
1187
|
-
loading: loadingType === "guest",
|
|
1188
|
-
disabled: isLoading,
|
|
1189
|
-
style: styles5.button
|
|
1190
|
-
},
|
|
1191
|
-
"Continue as guest"
|
|
1192
|
-
))));
|
|
1139
|
+
error
|
|
1140
|
+
));
|
|
1193
1141
|
};
|
|
1194
1142
|
var styles5 = StyleSheet5.create({
|
|
1143
|
+
wrapper: {
|
|
1144
|
+
marginBottom: 16
|
|
1145
|
+
// theme.spacing.lg
|
|
1146
|
+
},
|
|
1147
|
+
label: {
|
|
1148
|
+
fontWeight: "500",
|
|
1149
|
+
marginBottom: 12,
|
|
1150
|
+
// theme.spacing.md - consistent label spacing
|
|
1151
|
+
textAlign: "center"
|
|
1152
|
+
},
|
|
1195
1153
|
container: {
|
|
1196
|
-
|
|
1154
|
+
flexDirection: "row",
|
|
1155
|
+
justifyContent: "center",
|
|
1156
|
+
gap: 8
|
|
1157
|
+
// theme.spacing.sm
|
|
1197
1158
|
},
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1159
|
+
input: {
|
|
1160
|
+
width: 48,
|
|
1161
|
+
height: 56,
|
|
1162
|
+
borderWidth: 1,
|
|
1202
1163
|
textAlign: "center",
|
|
1203
|
-
|
|
1204
|
-
// theme.spacing.lg - consistent section spacing
|
|
1164
|
+
fontWeight: "600"
|
|
1205
1165
|
},
|
|
1206
|
-
|
|
1166
|
+
error: {
|
|
1167
|
+
marginTop: 12,
|
|
1168
|
+
// theme.spacing.md - consistent error spacing
|
|
1169
|
+
textAlign: "center"
|
|
1170
|
+
}
|
|
1171
|
+
});
|
|
1172
|
+
|
|
1173
|
+
// src/components/SkeletonItem.tsx
|
|
1174
|
+
import React10, { useEffect, useRef } from "react";
|
|
1175
|
+
import { Animated, View as View6, StyleSheet as StyleSheet6 } from "react-native";
|
|
1176
|
+
var SkeletonItem = () => {
|
|
1177
|
+
const opacity = useRef(new Animated.Value(0.3)).current;
|
|
1178
|
+
useEffect(() => {
|
|
1179
|
+
Animated.loop(
|
|
1180
|
+
Animated.sequence([
|
|
1181
|
+
Animated.timing(opacity, {
|
|
1182
|
+
toValue: 1,
|
|
1183
|
+
duration: 600,
|
|
1184
|
+
useNativeDriver: true
|
|
1185
|
+
}),
|
|
1186
|
+
Animated.timing(opacity, {
|
|
1187
|
+
toValue: 0.3,
|
|
1188
|
+
duration: 600,
|
|
1189
|
+
useNativeDriver: true
|
|
1190
|
+
})
|
|
1191
|
+
])
|
|
1192
|
+
).start();
|
|
1193
|
+
}, []);
|
|
1194
|
+
return /* @__PURE__ */ React10.createElement(Animated.View, { style: [styles6.row, { opacity }] }, /* @__PURE__ */ React10.createElement(View6, { style: styles6.iconCircle }), /* @__PURE__ */ React10.createElement(View6, { style: styles6.textBlock }, /* @__PURE__ */ React10.createElement(View6, { style: styles6.lineLong }), /* @__PURE__ */ React10.createElement(View6, { style: styles6.lineShort })));
|
|
1195
|
+
};
|
|
1196
|
+
var styles6 = StyleSheet6.create({
|
|
1197
|
+
row: {
|
|
1207
1198
|
flexDirection: "row",
|
|
1208
|
-
marginBottom: 16,
|
|
1209
|
-
// theme.spacing.lg
|
|
1210
|
-
alignItems: "flex-start"
|
|
1211
|
-
},
|
|
1212
|
-
infoIcon: {
|
|
1213
|
-
width: 32,
|
|
1214
|
-
height: 32,
|
|
1215
|
-
borderRadius: 16,
|
|
1216
|
-
// theme.borderRadius.lg
|
|
1217
1199
|
alignItems: "center",
|
|
1218
|
-
|
|
1219
|
-
marginRight: 12
|
|
1220
|
-
// theme.spacing.md
|
|
1200
|
+
paddingVertical: 16
|
|
1221
1201
|
},
|
|
1222
|
-
|
|
1223
|
-
|
|
1202
|
+
iconCircle: {
|
|
1203
|
+
width: 45,
|
|
1204
|
+
height: 45,
|
|
1205
|
+
borderRadius: 22.5,
|
|
1206
|
+
backgroundColor: "#E5E5E5"
|
|
1224
1207
|
},
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
fontWeight: "600",
|
|
1229
|
-
marginBottom: 4
|
|
1230
|
-
// theme.spacing.xs
|
|
1208
|
+
textBlock: {
|
|
1209
|
+
marginLeft: 12,
|
|
1210
|
+
flex: 1
|
|
1231
1211
|
},
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1212
|
+
lineShort: {
|
|
1213
|
+
width: "50%",
|
|
1214
|
+
height: 14,
|
|
1215
|
+
borderRadius: 6,
|
|
1216
|
+
backgroundColor: "#E5E5E5"
|
|
1235
1217
|
},
|
|
1236
|
-
|
|
1218
|
+
lineLong: {
|
|
1219
|
+
marginBottom: 6,
|
|
1237
1220
|
width: "100%",
|
|
1238
|
-
|
|
1239
|
-
|
|
1221
|
+
height: 14,
|
|
1222
|
+
borderRadius: 6,
|
|
1223
|
+
backgroundColor: "#E5E5E5"
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
var SkeletonItem_default = SkeletonItem;
|
|
1227
|
+
|
|
1228
|
+
// src/components/Mode.tsx
|
|
1229
|
+
import React11 from "react";
|
|
1230
|
+
import { View as View7, Text as Text6, StyleSheet as StyleSheet7 } from "react-native";
|
|
1231
|
+
var Mode = () => {
|
|
1232
|
+
const { clientInfo } = useKryptosConnect();
|
|
1233
|
+
const theme = useTheme();
|
|
1234
|
+
if (!clientInfo) return null;
|
|
1235
|
+
if (clientInfo?.project_stage === "production") return null;
|
|
1236
|
+
return /* @__PURE__ */ React11.createElement(View7, { style: [styles7.container, { backgroundColor: theme.colors.warning }] }, /* @__PURE__ */ React11.createElement(Text6, { style: [styles7.text, { color: theme.colors.warningText }] }, "Sandbox Mode"));
|
|
1237
|
+
};
|
|
1238
|
+
var styles7 = StyleSheet7.create({
|
|
1239
|
+
container: {
|
|
1240
|
+
paddingVertical: 4,
|
|
1241
|
+
paddingHorizontal: 8,
|
|
1242
|
+
borderRadius: 8,
|
|
1243
|
+
alignItems: "center",
|
|
1244
|
+
justifyContent: "center"
|
|
1240
1245
|
},
|
|
1241
|
-
|
|
1246
|
+
text: {
|
|
1242
1247
|
fontSize: 12,
|
|
1243
|
-
|
|
1244
|
-
textAlign: "center",
|
|
1245
|
-
marginTop: 16
|
|
1246
|
-
// theme.spacing.lg
|
|
1248
|
+
fontWeight: "600"
|
|
1247
1249
|
}
|
|
1248
1250
|
});
|
|
1249
1251
|
|
|
1250
|
-
// src/components/
|
|
1252
|
+
// src/components/Footer.tsx
|
|
1251
1253
|
import React13 from "react";
|
|
1254
|
+
import { View as View9, StyleSheet as StyleSheet9 } from "react-native";
|
|
1255
|
+
|
|
1256
|
+
// src/components/PoweredByKryptos.tsx
|
|
1257
|
+
import React12 from "react";
|
|
1252
1258
|
import {
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
Text as
|
|
1256
|
-
|
|
1259
|
+
Linking,
|
|
1260
|
+
StyleSheet as StyleSheet8,
|
|
1261
|
+
Text as Text7,
|
|
1262
|
+
TouchableOpacity as TouchableOpacity3,
|
|
1263
|
+
View as View8
|
|
1257
1264
|
} from "react-native";
|
|
1258
|
-
var
|
|
1259
|
-
label,
|
|
1260
|
-
error,
|
|
1261
|
-
helperText,
|
|
1262
|
-
status = "default",
|
|
1263
|
-
containerStyle,
|
|
1264
|
-
inputStyle,
|
|
1265
|
-
labelStyle,
|
|
1266
|
-
...props
|
|
1267
|
-
}) => {
|
|
1265
|
+
var PoweredByKryptos = () => {
|
|
1268
1266
|
const theme = useTheme();
|
|
1269
|
-
const
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1267
|
+
const handlePress = () => {
|
|
1268
|
+
Linking.openURL("https://kryptos.io");
|
|
1269
|
+
};
|
|
1270
|
+
return /* @__PURE__ */ React12.createElement(View8, { style: styles8.container }, /* @__PURE__ */ React12.createElement(Text7, { style: [styles8.text, { color: theme.colors.textSecondary }] }, "Powered by", " "), /* @__PURE__ */ React12.createElement(TouchableOpacity3, { onPress: handlePress, activeOpacity: 0.7 }, /* @__PURE__ */ React12.createElement(LogoIcon, { size: 16 })));
|
|
1271
|
+
};
|
|
1272
|
+
var styles8 = StyleSheet8.create({
|
|
1273
|
+
container: {
|
|
1274
|
+
flexDirection: "row",
|
|
1275
|
+
alignItems: "center"
|
|
1276
|
+
},
|
|
1277
|
+
text: {
|
|
1278
|
+
fontSize: 12,
|
|
1279
|
+
fontWeight: "400"
|
|
1280
|
+
}
|
|
1281
|
+
});
|
|
1282
|
+
|
|
1283
|
+
// src/components/Footer.tsx
|
|
1284
|
+
var Footer = () => {
|
|
1285
|
+
const { clientInfo } = useKryptosConnect();
|
|
1286
|
+
const isSandbox = clientInfo?.project_stage === "sandbox";
|
|
1287
|
+
return /* @__PURE__ */ React13.createElement(
|
|
1288
|
+
View9,
|
|
1289
|
+
{
|
|
1290
|
+
style: [
|
|
1291
|
+
styles9.container,
|
|
1292
|
+
{ justifyContent: isSandbox ? "space-between" : "center" }
|
|
1293
|
+
]
|
|
1294
|
+
},
|
|
1295
|
+
/* @__PURE__ */ React13.createElement(PoweredByKryptos, null),
|
|
1296
|
+
/* @__PURE__ */ React13.createElement(Mode, null)
|
|
1297
|
+
);
|
|
1298
|
+
};
|
|
1299
|
+
var styles9 = StyleSheet9.create({
|
|
1300
|
+
container: {
|
|
1301
|
+
width: "100%",
|
|
1302
|
+
paddingVertical: 8,
|
|
1303
|
+
alignItems: "center",
|
|
1304
|
+
flexDirection: "row"
|
|
1305
|
+
}
|
|
1306
|
+
});
|
|
1307
|
+
|
|
1308
|
+
// src/molecules/Auth.tsx
|
|
1309
|
+
import React19 from "react";
|
|
1310
|
+
import { Linking as Linking2, StyleSheet as StyleSheet11, Text as Text9, View as View11 } from "react-native";
|
|
1311
|
+
|
|
1312
|
+
// src/assets/LinkIcon.tsx
|
|
1313
|
+
import React14 from "react";
|
|
1314
|
+
import Svg3, { Path as Path3 } from "react-native-svg";
|
|
1315
|
+
var LinkIcon = ({
|
|
1316
|
+
size = 20,
|
|
1317
|
+
color = "#00C693"
|
|
1318
|
+
}) => {
|
|
1319
|
+
return /* @__PURE__ */ React14.createElement(Svg3, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React14.createElement(
|
|
1320
|
+
Path3,
|
|
1321
|
+
{
|
|
1322
|
+
d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",
|
|
1323
|
+
stroke: color,
|
|
1324
|
+
strokeWidth: 2,
|
|
1325
|
+
strokeLinecap: "round",
|
|
1326
|
+
strokeLinejoin: "round"
|
|
1327
|
+
}
|
|
1328
|
+
), /* @__PURE__ */ React14.createElement(
|
|
1329
|
+
Path3,
|
|
1330
|
+
{
|
|
1331
|
+
d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",
|
|
1332
|
+
stroke: color,
|
|
1333
|
+
strokeWidth: 2,
|
|
1334
|
+
strokeLinecap: "round",
|
|
1335
|
+
strokeLinejoin: "round"
|
|
1336
|
+
}
|
|
1337
|
+
));
|
|
1338
|
+
};
|
|
1339
|
+
|
|
1340
|
+
// src/assets/ShieldIcon.tsx
|
|
1341
|
+
import React15 from "react";
|
|
1342
|
+
import Svg4, { Path as Path4 } from "react-native-svg";
|
|
1343
|
+
var ShieldIcon = ({
|
|
1344
|
+
size = 20,
|
|
1345
|
+
color = "#00C693"
|
|
1346
|
+
}) => {
|
|
1347
|
+
return /* @__PURE__ */ React15.createElement(Svg4, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React15.createElement(
|
|
1348
|
+
Path4,
|
|
1349
|
+
{
|
|
1350
|
+
d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",
|
|
1351
|
+
stroke: color,
|
|
1352
|
+
strokeWidth: 2,
|
|
1353
|
+
strokeLinecap: "round",
|
|
1354
|
+
strokeLinejoin: "round"
|
|
1355
|
+
}
|
|
1356
|
+
), /* @__PURE__ */ React15.createElement(
|
|
1357
|
+
Path4,
|
|
1358
|
+
{
|
|
1359
|
+
d: "m9 12 2 2 4-4",
|
|
1360
|
+
stroke: color,
|
|
1361
|
+
strokeWidth: 2,
|
|
1362
|
+
strokeLinecap: "round",
|
|
1363
|
+
strokeLinejoin: "round"
|
|
1364
|
+
}
|
|
1365
|
+
));
|
|
1366
|
+
};
|
|
1367
|
+
|
|
1368
|
+
// src/assets/eye.tsx
|
|
1369
|
+
import React16 from "react";
|
|
1370
|
+
import Svg5, { Path as Path5 } from "react-native-svg";
|
|
1371
|
+
var EyeIcon = ({
|
|
1372
|
+
size = 20,
|
|
1373
|
+
color = "#00C693"
|
|
1374
|
+
}) => {
|
|
1375
|
+
return /* @__PURE__ */ React16.createElement(Svg5, { fill: color, width: size, height: size, viewBox: "0 0 0.72 0.72" }, /* @__PURE__ */ React16.createElement(Path5, { d: "M0.658 0.348C0.597 0.207 0.483 0.12 0.36 0.12s-0.237 0.087 -0.298 0.228a0.03 0.03 0 0 0 0 0.024C0.123 0.513 0.237 0.6 0.36 0.6s0.237 -0.087 0.298 -0.228a0.03 0.03 0 0 0 0 -0.024M0.36 0.54c-0.095 0 -0.185 -0.069 -0.237 -0.18C0.175 0.249 0.265 0.18 0.36 0.18s0.185 0.069 0.237 0.18c-0.052 0.111 -0.142 0.18 -0.237 0.18m0 -0.3a0.12 0.12 0 1 0 0.12 0.12 0.12 0.12 0 0 0 -0.12 -0.12m0 0.18a0.06 0.06 0 1 1 0.06 -0.06 0.06 0.06 0 0 1 -0.06 0.06" }));
|
|
1376
|
+
};
|
|
1377
|
+
|
|
1378
|
+
// src/molecules/ConnectLogo.tsx
|
|
1379
|
+
import React18, { isValidElement } from "react";
|
|
1380
|
+
import {
|
|
1381
|
+
Image,
|
|
1382
|
+
StyleSheet as StyleSheet10,
|
|
1383
|
+
Text as Text8,
|
|
1384
|
+
View as View10
|
|
1385
|
+
} from "react-native";
|
|
1386
|
+
|
|
1387
|
+
// src/assets/UnplugIcon.tsx
|
|
1388
|
+
import React17 from "react";
|
|
1389
|
+
import Svg6, { Path as Path6, Line } from "react-native-svg";
|
|
1390
|
+
var UnplugIcon = ({
|
|
1391
|
+
size = 24,
|
|
1392
|
+
color = "#6B7280"
|
|
1393
|
+
}) => {
|
|
1394
|
+
return /* @__PURE__ */ React17.createElement(Svg6, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React17.createElement(
|
|
1395
|
+
Path6,
|
|
1396
|
+
{
|
|
1397
|
+
d: "m19 5 3-3",
|
|
1398
|
+
stroke: color,
|
|
1399
|
+
strokeWidth: 2,
|
|
1400
|
+
strokeLinecap: "round",
|
|
1401
|
+
strokeLinejoin: "round"
|
|
1278
1402
|
}
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
Text6,
|
|
1403
|
+
), /* @__PURE__ */ React17.createElement(
|
|
1404
|
+
Path6,
|
|
1282
1405
|
{
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
}
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
TextInput,
|
|
1406
|
+
d: "m2 22 3-3",
|
|
1407
|
+
stroke: color,
|
|
1408
|
+
strokeWidth: 2,
|
|
1409
|
+
strokeLinecap: "round",
|
|
1410
|
+
strokeLinejoin: "round"
|
|
1411
|
+
}
|
|
1412
|
+
), /* @__PURE__ */ React17.createElement(
|
|
1413
|
+
Path6,
|
|
1292
1414
|
{
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
borderColor: getBorderColor(),
|
|
1299
|
-
color: theme.colors.text,
|
|
1300
|
-
fontSize: theme.fontSize.md,
|
|
1301
|
-
borderRadius: theme.borderRadius.md,
|
|
1302
|
-
paddingHorizontal: theme.spacing.lg,
|
|
1303
|
-
paddingVertical: theme.spacing.md
|
|
1304
|
-
},
|
|
1305
|
-
inputStyle
|
|
1306
|
-
],
|
|
1307
|
-
...props
|
|
1415
|
+
d: "M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z",
|
|
1416
|
+
stroke: color,
|
|
1417
|
+
strokeWidth: 2,
|
|
1418
|
+
strokeLinecap: "round",
|
|
1419
|
+
strokeLinejoin: "round"
|
|
1308
1420
|
}
|
|
1309
|
-
),
|
|
1310
|
-
|
|
1421
|
+
), /* @__PURE__ */ React17.createElement(
|
|
1422
|
+
Path6,
|
|
1311
1423
|
{
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
),
|
|
1319
|
-
|
|
1424
|
+
d: "m18 12-6-6 2.3-2.3a2.4 2.4 0 0 1 3.4 0l2.6 2.6a2.4 2.4 0 0 1 0 3.4Z",
|
|
1425
|
+
stroke: color,
|
|
1426
|
+
strokeWidth: 2,
|
|
1427
|
+
strokeLinecap: "round",
|
|
1428
|
+
strokeLinejoin: "round"
|
|
1429
|
+
}
|
|
1430
|
+
), /* @__PURE__ */ React17.createElement(
|
|
1431
|
+
Line,
|
|
1320
1432
|
{
|
|
1321
|
-
|
|
1322
|
-
|
|
1433
|
+
x1: 7.5,
|
|
1434
|
+
y1: 13.5,
|
|
1435
|
+
x2: 10.5,
|
|
1436
|
+
y2: 10.5,
|
|
1437
|
+
stroke: color,
|
|
1438
|
+
strokeWidth: 2,
|
|
1439
|
+
strokeLinecap: "round"
|
|
1440
|
+
}
|
|
1441
|
+
));
|
|
1442
|
+
};
|
|
1443
|
+
|
|
1444
|
+
// src/molecules/ConnectLogo.tsx
|
|
1445
|
+
var KryptosLogo = () => {
|
|
1446
|
+
const theme = useTheme();
|
|
1447
|
+
return /* @__PURE__ */ React18.createElement(
|
|
1448
|
+
View10,
|
|
1449
|
+
{
|
|
1450
|
+
style: [styles10.logoContainer, { backgroundColor: theme.colors.surface }]
|
|
1451
|
+
},
|
|
1452
|
+
/* @__PURE__ */ React18.createElement(LogoIcon, { size: 36 })
|
|
1453
|
+
);
|
|
1454
|
+
};
|
|
1455
|
+
var ConnectLogo = () => {
|
|
1456
|
+
const { appName, appLogo } = useKryptosConnect();
|
|
1457
|
+
const theme = useTheme();
|
|
1458
|
+
const isValidUrl = (str) => {
|
|
1459
|
+
try {
|
|
1460
|
+
new URL(str);
|
|
1461
|
+
return true;
|
|
1462
|
+
} catch {
|
|
1463
|
+
return false;
|
|
1464
|
+
}
|
|
1465
|
+
};
|
|
1466
|
+
const renderLogo = () => {
|
|
1467
|
+
if (isValidElement(appLogo)) {
|
|
1468
|
+
return appLogo;
|
|
1469
|
+
} else if (typeof appLogo === "string" && isValidUrl(appLogo)) {
|
|
1470
|
+
return /* @__PURE__ */ React18.createElement(
|
|
1471
|
+
Image,
|
|
1323
1472
|
{
|
|
1324
|
-
|
|
1325
|
-
|
|
1473
|
+
source: { uri: appLogo },
|
|
1474
|
+
style: styles10.appLogoImage,
|
|
1475
|
+
resizeMode: "contain"
|
|
1476
|
+
}
|
|
1477
|
+
);
|
|
1478
|
+
} else if (typeof appLogo === "number" || typeof appLogo === "object" && appLogo !== null) {
|
|
1479
|
+
return /* @__PURE__ */ React18.createElement(
|
|
1480
|
+
Image,
|
|
1481
|
+
{
|
|
1482
|
+
source: appLogo,
|
|
1483
|
+
style: styles10.appLogoImage,
|
|
1484
|
+
resizeMode: "contain"
|
|
1326
1485
|
}
|
|
1486
|
+
);
|
|
1487
|
+
} else if (appName) {
|
|
1488
|
+
return /* @__PURE__ */ React18.createElement(Text8, { style: [styles10.appLogoText, { color: theme.colors.text }] }, appName.charAt(0).toUpperCase());
|
|
1489
|
+
}
|
|
1490
|
+
return /* @__PURE__ */ React18.createElement(Text8, { style: [styles10.appLogoText, { color: theme.colors.text }] }, "?");
|
|
1491
|
+
};
|
|
1492
|
+
return /* @__PURE__ */ React18.createElement(View10, { style: styles10.container }, /* @__PURE__ */ React18.createElement(KryptosLogo, null), /* @__PURE__ */ React18.createElement(View10, { style: styles10.iconContainer }, /* @__PURE__ */ React18.createElement(UnplugIcon, { size: 24, color: theme.colors.textSecondary })), /* @__PURE__ */ React18.createElement(
|
|
1493
|
+
View10,
|
|
1494
|
+
{
|
|
1495
|
+
style: [
|
|
1496
|
+
styles10.logoContainer,
|
|
1497
|
+
{ backgroundColor: theme.colors.surface }
|
|
1327
1498
|
]
|
|
1328
1499
|
},
|
|
1329
|
-
|
|
1500
|
+
renderLogo()
|
|
1330
1501
|
));
|
|
1331
1502
|
};
|
|
1332
|
-
var
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1503
|
+
var styles10 = StyleSheet10.create({
|
|
1504
|
+
container: {
|
|
1505
|
+
flexDirection: "row",
|
|
1506
|
+
alignItems: "center",
|
|
1507
|
+
justifyContent: "center",
|
|
1508
|
+
gap: 12
|
|
1509
|
+
// theme.spacing.md
|
|
1336
1510
|
},
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1511
|
+
logoContainer: {
|
|
1512
|
+
width: 56,
|
|
1513
|
+
height: 56,
|
|
1514
|
+
borderRadius: 12,
|
|
1515
|
+
// theme.borderRadius.md
|
|
1516
|
+
alignItems: "center",
|
|
1517
|
+
justifyContent: "center",
|
|
1518
|
+
overflow: "hidden"
|
|
1341
1519
|
},
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1520
|
+
iconContainer: {
|
|
1521
|
+
paddingHorizontal: 8
|
|
1522
|
+
// theme.spacing.sm
|
|
1345
1523
|
},
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1524
|
+
appLogoImage: {
|
|
1525
|
+
width: 32,
|
|
1526
|
+
height: 32
|
|
1349
1527
|
},
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
// theme.
|
|
1528
|
+
appLogoText: {
|
|
1529
|
+
fontSize: 24,
|
|
1530
|
+
// theme.fontSize.xxxl
|
|
1531
|
+
fontWeight: "700"
|
|
1353
1532
|
}
|
|
1354
1533
|
});
|
|
1355
1534
|
|
|
1356
|
-
// src/
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
StyleSheet as StyleSheet7
|
|
1363
|
-
} from "react-native";
|
|
1364
|
-
var OTP = ({
|
|
1365
|
-
length = 6,
|
|
1366
|
-
value = "",
|
|
1367
|
-
onChange,
|
|
1368
|
-
onComplete,
|
|
1369
|
-
error,
|
|
1370
|
-
label,
|
|
1371
|
-
disabled = false,
|
|
1372
|
-
containerStyle,
|
|
1373
|
-
inputStyle,
|
|
1374
|
-
setErrorMessage
|
|
1535
|
+
// src/molecules/Auth.tsx
|
|
1536
|
+
var Auth = ({
|
|
1537
|
+
open,
|
|
1538
|
+
onEmailSuccess,
|
|
1539
|
+
onGuestSuccess,
|
|
1540
|
+
onClose
|
|
1375
1541
|
}) => {
|
|
1542
|
+
const { appName, linkToken, clientId, setUser, setEmail } = useKryptosConnect();
|
|
1376
1543
|
const theme = useTheme();
|
|
1377
|
-
const
|
|
1378
|
-
const [
|
|
1379
|
-
|
|
1380
|
-
);
|
|
1381
|
-
const
|
|
1382
|
-
|
|
1383
|
-
const
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1544
|
+
const [isLoading, setIsLoading] = React19.useState(false);
|
|
1545
|
+
const [errorMessage, setErrorMessage] = React19.useState("");
|
|
1546
|
+
const [emailValue, setEmailValue] = React19.useState("");
|
|
1547
|
+
const [emailError, setEmailError] = React19.useState("");
|
|
1548
|
+
const [loadingType, setLoadingType] = React19.useState(null);
|
|
1549
|
+
const validateEmail = (email) => {
|
|
1550
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1551
|
+
if (!email) {
|
|
1552
|
+
setEmailError("Email is required");
|
|
1553
|
+
return false;
|
|
1554
|
+
}
|
|
1555
|
+
if (!emailRegex.test(email)) {
|
|
1556
|
+
setEmailError("Invalid email address");
|
|
1557
|
+
return false;
|
|
1558
|
+
}
|
|
1559
|
+
setEmailError("");
|
|
1560
|
+
return true;
|
|
1561
|
+
};
|
|
1562
|
+
const handleClose = () => {
|
|
1563
|
+
onClose();
|
|
1564
|
+
setEmailValue("");
|
|
1565
|
+
setEmailError("");
|
|
1566
|
+
setErrorMessage("");
|
|
1567
|
+
};
|
|
1568
|
+
const handleEmailSubmit = async () => {
|
|
1569
|
+
if (!validateEmail(emailValue)) return;
|
|
1570
|
+
try {
|
|
1571
|
+
setIsLoading(true);
|
|
1572
|
+
setLoadingType("email");
|
|
1573
|
+
setErrorMessage("");
|
|
1574
|
+
await sendEmailOtp(linkToken, emailValue, clientId);
|
|
1575
|
+
setEmail(emailValue);
|
|
1576
|
+
setEmailError("");
|
|
1577
|
+
onEmailSuccess();
|
|
1578
|
+
} catch (error) {
|
|
1579
|
+
const err = error;
|
|
1580
|
+
setErrorMessage(
|
|
1581
|
+
err?.response?.data?.message || "Failed to send email OTP"
|
|
1582
|
+
);
|
|
1583
|
+
} finally {
|
|
1584
|
+
setIsLoading(false);
|
|
1585
|
+
setLoadingType(null);
|
|
1586
|
+
}
|
|
1587
|
+
};
|
|
1588
|
+
const handleContinueAsGuest = async () => {
|
|
1589
|
+
try {
|
|
1590
|
+
setIsLoading(true);
|
|
1591
|
+
setLoadingType("guest");
|
|
1592
|
+
setErrorMessage("");
|
|
1593
|
+
const res = await createAnonymousUser(linkToken, clientId);
|
|
1594
|
+
setUser(res);
|
|
1595
|
+
setEmailError("");
|
|
1596
|
+
onGuestSuccess();
|
|
1597
|
+
} catch (error) {
|
|
1598
|
+
const err = error;
|
|
1599
|
+
console.error(error);
|
|
1600
|
+
setErrorMessage(
|
|
1601
|
+
err?.response?.data?.message || "Failed to continue as guest"
|
|
1602
|
+
);
|
|
1603
|
+
} finally {
|
|
1604
|
+
setIsLoading(false);
|
|
1605
|
+
setLoadingType(null);
|
|
1389
1606
|
}
|
|
1390
|
-
return () => {
|
|
1391
|
-
if (timer) clearTimeout(timer);
|
|
1392
|
-
};
|
|
1393
|
-
}, [otp, onComplete]);
|
|
1394
|
-
React14.useEffect(() => {
|
|
1395
|
-
setTimeout(() => {
|
|
1396
|
-
inputRefs.current[0]?.focus();
|
|
1397
|
-
}, 100);
|
|
1398
|
-
}, []);
|
|
1399
|
-
const handleChange = React14.useCallback(
|
|
1400
|
-
(index, val) => {
|
|
1401
|
-
if (disabled) return;
|
|
1402
|
-
setErrorMessage("");
|
|
1403
|
-
const numericValue = val.replace(/[^0-9]/g, "");
|
|
1404
|
-
const newValue = numericValue.slice(-1);
|
|
1405
|
-
if (val && !numericValue) {
|
|
1406
|
-
return;
|
|
1407
|
-
}
|
|
1408
|
-
const newOtp = [...otp];
|
|
1409
|
-
newOtp[index] = newValue;
|
|
1410
|
-
setOtp(newOtp);
|
|
1411
|
-
const otpString = newOtp.join("");
|
|
1412
|
-
onChange?.(otpString);
|
|
1413
|
-
if (newValue && index < length - 1) {
|
|
1414
|
-
inputRefs.current[index + 1]?.focus();
|
|
1415
|
-
}
|
|
1416
|
-
if (otpString.length === length && !otpString.includes("")) {
|
|
1417
|
-
onComplete?.(otpString);
|
|
1418
|
-
}
|
|
1419
|
-
},
|
|
1420
|
-
[otp, length, onChange, onComplete, disabled]
|
|
1421
|
-
);
|
|
1422
|
-
const handleKeyPress = React14.useCallback(
|
|
1423
|
-
(index, e) => {
|
|
1424
|
-
if (disabled) return;
|
|
1425
|
-
if (e.nativeEvent.key === "Backspace") {
|
|
1426
|
-
if (!otp[index] && index > 0) {
|
|
1427
|
-
inputRefs.current[index - 1]?.focus();
|
|
1428
|
-
} else {
|
|
1429
|
-
const newOtp = [...otp];
|
|
1430
|
-
newOtp[index] = "";
|
|
1431
|
-
setOtp(newOtp);
|
|
1432
|
-
onChange?.(newOtp.join(""));
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
},
|
|
1436
|
-
[otp, onChange, disabled]
|
|
1437
|
-
);
|
|
1438
|
-
const getBorderColor = (index) => {
|
|
1439
|
-
if (error) return theme.colors.error;
|
|
1440
|
-
if (otp[index]) return theme.colors.success;
|
|
1441
|
-
return theme.colors.border;
|
|
1442
1607
|
};
|
|
1443
|
-
|
|
1444
|
-
Text7,
|
|
1608
|
+
const infoSections = [
|
|
1445
1609
|
{
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
]
|
|
1610
|
+
icon: /* @__PURE__ */ React19.createElement(LinkIcon, { size: 20, color: theme.colors.primary }),
|
|
1611
|
+
title: "Simple and secure",
|
|
1612
|
+
text: "Link your accounts in just a few clicks"
|
|
1450
1613
|
},
|
|
1451
|
-
label
|
|
1452
|
-
), /* @__PURE__ */ React14.createElement(View7, { style: styles7.container }, Array.from({ length }, (_, index) => /* @__PURE__ */ React14.createElement(
|
|
1453
|
-
TextInput2,
|
|
1454
1614
|
{
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
fontSize: theme.fontSize.xxl,
|
|
1464
|
-
borderRadius: theme.borderRadius.md
|
|
1465
|
-
},
|
|
1466
|
-
inputStyle
|
|
1467
|
-
],
|
|
1468
|
-
keyboardType: "numeric",
|
|
1469
|
-
maxLength: 1,
|
|
1470
|
-
value: otp[index] || "",
|
|
1471
|
-
onChangeText: (val) => handleChange(index, val),
|
|
1472
|
-
onKeyPress: (e) => handleKeyPress(index, e),
|
|
1473
|
-
editable: !disabled,
|
|
1474
|
-
selectTextOnFocus: true,
|
|
1475
|
-
caretHidden: true
|
|
1615
|
+
icon: /* @__PURE__ */ React19.createElement(ShieldIcon, { size: 20, color: theme.colors.primary }),
|
|
1616
|
+
title: "Control what you share",
|
|
1617
|
+
text: "We never share your data without your permission"
|
|
1618
|
+
},
|
|
1619
|
+
{
|
|
1620
|
+
icon: /* @__PURE__ */ React19.createElement(EyeIcon, { size: 20, color: theme.colors.primary }),
|
|
1621
|
+
title: "View Only Access",
|
|
1622
|
+
text: "Kryptos retrieves view-only data and cannot perform any transactions on your behalf."
|
|
1476
1623
|
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1624
|
+
];
|
|
1625
|
+
return /* @__PURE__ */ React19.createElement(Modal, { isOpen: open, onClose: handleClose, size: "full" }, /* @__PURE__ */ React19.createElement(ModalHeader, { onClose: handleClose }, ""), /* @__PURE__ */ React19.createElement(ModalBody, null, /* @__PURE__ */ React19.createElement(View11, { style: styles11.container }, /* @__PURE__ */ React19.createElement(View11, { style: styles11.header }, /* @__PURE__ */ React19.createElement(Text9, { style: [styles11.title, { color: theme.colors.text }] }, "Link your accounts to", " ", /* @__PURE__ */ React19.createElement(Text9, { style: { fontWeight: "700" } }, appName), " using Kryptos"), /* @__PURE__ */ React19.createElement(ConnectLogo, null), infoSections.map((section, index) => /* @__PURE__ */ React19.createElement(View11, { key: `info-${index}`, style: styles11.infoSection }, /* @__PURE__ */ React19.createElement(View11, { style: styles11.infoIcon }, section.icon), /* @__PURE__ */ React19.createElement(View11, { style: styles11.infoContent }, /* @__PURE__ */ React19.createElement(
|
|
1626
|
+
Text9,
|
|
1627
|
+
{
|
|
1628
|
+
style: [styles11.infoTitle, { color: theme.colors.text }]
|
|
1629
|
+
},
|
|
1630
|
+
section.title
|
|
1631
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1632
|
+
Text9,
|
|
1479
1633
|
{
|
|
1480
1634
|
style: [
|
|
1481
|
-
|
|
1482
|
-
{ color: theme.colors.
|
|
1635
|
+
styles11.infoDescription,
|
|
1636
|
+
{ color: theme.colors.textSecondary }
|
|
1483
1637
|
]
|
|
1484
1638
|
},
|
|
1485
|
-
|
|
1486
|
-
))
|
|
1639
|
+
section.text
|
|
1640
|
+
)))), errorMessage ? /* @__PURE__ */ React19.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React19.createElement(AlertDescription, null, errorMessage)) : null), /* @__PURE__ */ React19.createElement(View11, { style: styles11.footer }, /* @__PURE__ */ React19.createElement(
|
|
1641
|
+
Button,
|
|
1642
|
+
{
|
|
1643
|
+
variant: "outline",
|
|
1644
|
+
size: "lg",
|
|
1645
|
+
onPress: handleContinueAsGuest,
|
|
1646
|
+
loading: loadingType === "guest",
|
|
1647
|
+
disabled: isLoading,
|
|
1648
|
+
style: styles11.button
|
|
1649
|
+
},
|
|
1650
|
+
"Continue"
|
|
1651
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1652
|
+
Text9,
|
|
1653
|
+
{
|
|
1654
|
+
style: [styles11.footerText, { color: theme.colors.textSecondary }]
|
|
1655
|
+
},
|
|
1656
|
+
"By continuing, you agree to Kryptos",
|
|
1657
|
+
" ",
|
|
1658
|
+
/* @__PURE__ */ React19.createElement(
|
|
1659
|
+
Text9,
|
|
1660
|
+
{
|
|
1661
|
+
style: {
|
|
1662
|
+
color: theme.colors.primary,
|
|
1663
|
+
textDecorationLine: "underline"
|
|
1664
|
+
},
|
|
1665
|
+
onPress: () => Linking2.openURL("https://kryptos.io/privacy-policy")
|
|
1666
|
+
},
|
|
1667
|
+
"Privacy Policy"
|
|
1668
|
+
),
|
|
1669
|
+
" ",
|
|
1670
|
+
"and",
|
|
1671
|
+
" ",
|
|
1672
|
+
/* @__PURE__ */ React19.createElement(
|
|
1673
|
+
Text9,
|
|
1674
|
+
{
|
|
1675
|
+
style: {
|
|
1676
|
+
color: theme.colors.primary,
|
|
1677
|
+
textDecorationLine: "underline"
|
|
1678
|
+
},
|
|
1679
|
+
onPress: () => Linking2.openURL("https://kryptos.io/terms-of-services")
|
|
1680
|
+
},
|
|
1681
|
+
"Terms of Service"
|
|
1682
|
+
)
|
|
1683
|
+
)))), /* @__PURE__ */ React19.createElement(ModalFooter, { style: { paddingVertical: 0 } }, /* @__PURE__ */ React19.createElement(Footer, null)));
|
|
1487
1684
|
};
|
|
1488
|
-
var
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1685
|
+
var styles11 = StyleSheet11.create({
|
|
1686
|
+
container: {
|
|
1687
|
+
flex: 1,
|
|
1688
|
+
flexDirection: "column",
|
|
1689
|
+
justifyContent: "space-between"
|
|
1492
1690
|
},
|
|
1493
|
-
|
|
1691
|
+
header: {
|
|
1692
|
+
flex: 1,
|
|
1693
|
+
gap: 8
|
|
1694
|
+
},
|
|
1695
|
+
footer: {
|
|
1696
|
+
flex: 1,
|
|
1697
|
+
justifyContent: "flex-end",
|
|
1698
|
+
gap: 8
|
|
1699
|
+
},
|
|
1700
|
+
title: {
|
|
1701
|
+
fontSize: 18,
|
|
1702
|
+
// theme.fontSize.xl
|
|
1494
1703
|
fontWeight: "500",
|
|
1495
|
-
marginBottom: 12,
|
|
1496
|
-
// theme.spacing.md - consistent label spacing
|
|
1497
1704
|
textAlign: "center"
|
|
1498
1705
|
},
|
|
1499
|
-
|
|
1706
|
+
infoSection: {
|
|
1500
1707
|
flexDirection: "row",
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1708
|
+
alignItems: "flex-start",
|
|
1709
|
+
padding: 8,
|
|
1710
|
+
gap: 12
|
|
1504
1711
|
},
|
|
1505
|
-
|
|
1506
|
-
width:
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1712
|
+
infoIcon: {
|
|
1713
|
+
width: 32,
|
|
1714
|
+
// theme.spacing.xxxl
|
|
1715
|
+
height: 32,
|
|
1716
|
+
// theme.spacing.xxxl
|
|
1717
|
+
borderRadius: 16,
|
|
1718
|
+
// theme.borderRadius.lg
|
|
1719
|
+
alignItems: "center",
|
|
1720
|
+
justifyContent: "center"
|
|
1721
|
+
},
|
|
1722
|
+
infoContent: {
|
|
1723
|
+
flex: 1,
|
|
1724
|
+
gap: 4
|
|
1725
|
+
},
|
|
1726
|
+
infoTitle: {
|
|
1727
|
+
fontSize: 14,
|
|
1728
|
+
// theme.fontSize.md
|
|
1510
1729
|
fontWeight: "600"
|
|
1511
1730
|
},
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
// theme.
|
|
1515
|
-
|
|
1731
|
+
infoDescription: {
|
|
1732
|
+
fontSize: 13,
|
|
1733
|
+
// theme.fontSize.sm + 1
|
|
1734
|
+
lineHeight: 18
|
|
1735
|
+
},
|
|
1736
|
+
button: {
|
|
1737
|
+
width: "100%"
|
|
1738
|
+
},
|
|
1739
|
+
footerText: {
|
|
1740
|
+
fontSize: 12,
|
|
1741
|
+
// theme.fontSize.sm
|
|
1742
|
+
textAlign: "center",
|
|
1743
|
+
padding: 8,
|
|
1744
|
+
maxWidth: "80%",
|
|
1745
|
+
alignSelf: "center"
|
|
1516
1746
|
}
|
|
1517
1747
|
});
|
|
1518
1748
|
|
|
1519
1749
|
// src/molecules/Init.tsx
|
|
1520
|
-
import
|
|
1521
|
-
import { ActivityIndicator as ActivityIndicator2, StyleSheet as
|
|
1750
|
+
import React20 from "react";
|
|
1751
|
+
import { ActivityIndicator as ActivityIndicator2, StyleSheet as StyleSheet12, Text as Text10, View as View12 } from "react-native";
|
|
1522
1752
|
var Init = ({
|
|
1523
1753
|
open,
|
|
1524
1754
|
onSuccess,
|
|
1525
1755
|
onClose,
|
|
1526
1756
|
generateLinkToken
|
|
1527
1757
|
}) => {
|
|
1528
|
-
const {
|
|
1758
|
+
const {
|
|
1759
|
+
setIsInitialized,
|
|
1760
|
+
isInitialized,
|
|
1761
|
+
setLinkToken,
|
|
1762
|
+
setIsAuthorized,
|
|
1763
|
+
setUser
|
|
1764
|
+
} = useKryptosConnect();
|
|
1529
1765
|
const theme = useTheme();
|
|
1530
|
-
const [isFetching, setIsFetching] =
|
|
1531
|
-
const [error, setError] =
|
|
1532
|
-
const fetchLinkToken =
|
|
1766
|
+
const [isFetching, setIsFetching] = React20.useState(false);
|
|
1767
|
+
const [error, setError] = React20.useState(null);
|
|
1768
|
+
const fetchLinkToken = React20.useCallback(async () => {
|
|
1533
1769
|
if (!open) return;
|
|
1534
1770
|
setIsFetching(true);
|
|
1535
1771
|
setError(null);
|
|
@@ -1542,6 +1778,11 @@ var Init = ({
|
|
|
1542
1778
|
}
|
|
1543
1779
|
setLinkToken(linkToken.link_token);
|
|
1544
1780
|
setIsInitialized(true);
|
|
1781
|
+
setIsAuthorized(linkToken.isAuthorized || false);
|
|
1782
|
+
if (linkToken.isAuthorized) {
|
|
1783
|
+
const userInfo = await getUserInfo(linkToken.link_token);
|
|
1784
|
+
setUser(userInfo);
|
|
1785
|
+
}
|
|
1545
1786
|
onSuccess(linkToken.isAuthorized ? { isAuthorized: true } : null);
|
|
1546
1787
|
} catch (err) {
|
|
1547
1788
|
console.error("Failed to fetch link token:", err);
|
|
@@ -1550,29 +1791,29 @@ var Init = ({
|
|
|
1550
1791
|
} finally {
|
|
1551
1792
|
setIsFetching(false);
|
|
1552
1793
|
}
|
|
1553
|
-
}, [
|
|
1554
|
-
|
|
1794
|
+
}, []);
|
|
1795
|
+
React20.useEffect(() => {
|
|
1555
1796
|
fetchLinkToken();
|
|
1556
1797
|
}, [fetchLinkToken]);
|
|
1557
|
-
return /* @__PURE__ */
|
|
1798
|
+
return /* @__PURE__ */ React20.createElement(Modal, { isOpen: open, onClose, size: "xs" }, /* @__PURE__ */ React20.createElement(ModalHeader, { onClose }, "Kryptos Connect"), /* @__PURE__ */ React20.createElement(ModalBody, null, /* @__PURE__ */ React20.createElement(View12, { style: styles12.container }, isFetching && /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(
|
|
1558
1799
|
ActivityIndicator2,
|
|
1559
1800
|
{
|
|
1560
1801
|
size: "large",
|
|
1561
1802
|
color: theme.colors.primary,
|
|
1562
|
-
style:
|
|
1803
|
+
style: styles12.spinner
|
|
1563
1804
|
}
|
|
1564
|
-
), /* @__PURE__ */
|
|
1805
|
+
), /* @__PURE__ */ React20.createElement(Text10, { style: [styles12.message, { color: theme.colors.text }] }, isInitialized ? "Fetching link token..." : "Initializing...")), !isFetching && error && /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React20.createElement(AlertDescription, null, error)), /* @__PURE__ */ React20.createElement(
|
|
1565
1806
|
Button,
|
|
1566
1807
|
{
|
|
1567
1808
|
variant: "primary",
|
|
1568
1809
|
size: "lg",
|
|
1569
1810
|
onPress: fetchLinkToken,
|
|
1570
|
-
style:
|
|
1811
|
+
style: styles12.retryButton
|
|
1571
1812
|
},
|
|
1572
1813
|
"Retry"
|
|
1573
|
-
)))));
|
|
1814
|
+
)))), /* @__PURE__ */ React20.createElement(ModalFooter, { style: { paddingVertical: 0 } }, /* @__PURE__ */ React20.createElement(Footer, null)));
|
|
1574
1815
|
};
|
|
1575
|
-
var
|
|
1816
|
+
var styles12 = StyleSheet12.create({
|
|
1576
1817
|
container: {
|
|
1577
1818
|
flex: 1,
|
|
1578
1819
|
alignItems: "center",
|
|
@@ -1599,25 +1840,25 @@ var styles8 = StyleSheet8.create({
|
|
|
1599
1840
|
});
|
|
1600
1841
|
|
|
1601
1842
|
// src/molecules/Integration.tsx
|
|
1602
|
-
import
|
|
1843
|
+
import React31 from "react";
|
|
1603
1844
|
import {
|
|
1604
1845
|
FlatList,
|
|
1605
1846
|
Image as Image3,
|
|
1606
|
-
StyleSheet as
|
|
1607
|
-
Text as
|
|
1608
|
-
TouchableOpacity as
|
|
1609
|
-
View as
|
|
1847
|
+
StyleSheet as StyleSheet15,
|
|
1848
|
+
Text as Text13,
|
|
1849
|
+
TouchableOpacity as TouchableOpacity6,
|
|
1850
|
+
View as View15
|
|
1610
1851
|
} from "react-native";
|
|
1611
1852
|
|
|
1612
1853
|
// src/assets/ArrowLeftIcon.tsx
|
|
1613
|
-
import
|
|
1614
|
-
import
|
|
1854
|
+
import React21 from "react";
|
|
1855
|
+
import Svg7, { Path as Path7 } from "react-native-svg";
|
|
1615
1856
|
var ArrowLeftIcon = ({
|
|
1616
1857
|
size = 20,
|
|
1617
1858
|
color = "#000"
|
|
1618
1859
|
}) => {
|
|
1619
|
-
return /* @__PURE__ */
|
|
1620
|
-
|
|
1860
|
+
return /* @__PURE__ */ React21.createElement(Svg7, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React21.createElement(
|
|
1861
|
+
Path7,
|
|
1621
1862
|
{
|
|
1622
1863
|
d: "M19 12H5M12 19l-7-7 7-7",
|
|
1623
1864
|
stroke: color,
|
|
@@ -1629,13 +1870,13 @@ var ArrowLeftIcon = ({
|
|
|
1629
1870
|
};
|
|
1630
1871
|
|
|
1631
1872
|
// src/assets/CheckCircleIcon.tsx
|
|
1632
|
-
import
|
|
1633
|
-
import
|
|
1873
|
+
import React22 from "react";
|
|
1874
|
+
import Svg8, { Path as Path8, Circle } from "react-native-svg";
|
|
1634
1875
|
var CheckCircleIcon = ({
|
|
1635
1876
|
size = 20,
|
|
1636
1877
|
color = "#10B981"
|
|
1637
1878
|
}) => {
|
|
1638
|
-
return /* @__PURE__ */
|
|
1879
|
+
return /* @__PURE__ */ React22.createElement(Svg8, { width: size, height: size, viewBox: "0 0 24 24", fill: "none" }, /* @__PURE__ */ React22.createElement(
|
|
1639
1880
|
Circle,
|
|
1640
1881
|
{
|
|
1641
1882
|
cx: 12,
|
|
@@ -1644,8 +1885,8 @@ var CheckCircleIcon = ({
|
|
|
1644
1885
|
stroke: color,
|
|
1645
1886
|
strokeWidth: 2
|
|
1646
1887
|
}
|
|
1647
|
-
), /* @__PURE__ */
|
|
1648
|
-
|
|
1888
|
+
), /* @__PURE__ */ React22.createElement(
|
|
1889
|
+
Path8,
|
|
1649
1890
|
{
|
|
1650
1891
|
d: "m9 12 2 2 4-4",
|
|
1651
1892
|
stroke: color,
|
|
@@ -1657,18 +1898,18 @@ var CheckCircleIcon = ({
|
|
|
1657
1898
|
};
|
|
1658
1899
|
|
|
1659
1900
|
// src/assets/LoaderIcon.tsx
|
|
1660
|
-
import
|
|
1661
|
-
import { Animated, Easing } from "react-native";
|
|
1662
|
-
import
|
|
1663
|
-
var AnimatedSvg =
|
|
1901
|
+
import React23 from "react";
|
|
1902
|
+
import { Animated as Animated2, Easing } from "react-native";
|
|
1903
|
+
import Svg9, { Path as Path9 } from "react-native-svg";
|
|
1904
|
+
var AnimatedSvg = Animated2.createAnimatedComponent(Svg9);
|
|
1664
1905
|
var LoaderIcon = ({
|
|
1665
1906
|
size = 20,
|
|
1666
1907
|
color = "#00C693"
|
|
1667
1908
|
}) => {
|
|
1668
|
-
const rotateAnim =
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1909
|
+
const rotateAnim = React23.useRef(new Animated2.Value(0)).current;
|
|
1910
|
+
React23.useEffect(() => {
|
|
1911
|
+
Animated2.loop(
|
|
1912
|
+
Animated2.timing(rotateAnim, {
|
|
1672
1913
|
toValue: 1,
|
|
1673
1914
|
duration: 1e3,
|
|
1674
1915
|
easing: Easing.linear,
|
|
@@ -1680,7 +1921,7 @@ var LoaderIcon = ({
|
|
|
1680
1921
|
inputRange: [0, 1],
|
|
1681
1922
|
outputRange: ["0deg", "360deg"]
|
|
1682
1923
|
});
|
|
1683
|
-
return /* @__PURE__ */
|
|
1924
|
+
return /* @__PURE__ */ React23.createElement(
|
|
1684
1925
|
AnimatedSvg,
|
|
1685
1926
|
{
|
|
1686
1927
|
width: size,
|
|
@@ -1689,8 +1930,8 @@ var LoaderIcon = ({
|
|
|
1689
1930
|
fill: "none",
|
|
1690
1931
|
style: { transform: [{ rotate: spin }] }
|
|
1691
1932
|
},
|
|
1692
|
-
/* @__PURE__ */
|
|
1693
|
-
|
|
1933
|
+
/* @__PURE__ */ React23.createElement(
|
|
1934
|
+
Path9,
|
|
1694
1935
|
{
|
|
1695
1936
|
d: "M21 12a9 9 0 1 1-6.219-8.56",
|
|
1696
1937
|
stroke: color,
|
|
@@ -1703,10 +1944,10 @@ var LoaderIcon = ({
|
|
|
1703
1944
|
};
|
|
1704
1945
|
|
|
1705
1946
|
// src/assets/SuccessIcon.tsx
|
|
1706
|
-
import
|
|
1707
|
-
import
|
|
1947
|
+
import React24 from "react";
|
|
1948
|
+
import Svg10, { Circle as Circle2, Path as Path10 } from "react-native-svg";
|
|
1708
1949
|
var SuccessIcon = ({ size = 64 }) => {
|
|
1709
|
-
return /* @__PURE__ */
|
|
1950
|
+
return /* @__PURE__ */ React24.createElement(Svg10, { width: size, height: size, viewBox: "0 0 64 64", fill: "none" }, /* @__PURE__ */ React24.createElement(
|
|
1710
1951
|
Circle2,
|
|
1711
1952
|
{
|
|
1712
1953
|
cx: 32,
|
|
@@ -1715,7 +1956,7 @@ var SuccessIcon = ({ size = 64 }) => {
|
|
|
1715
1956
|
fill: "#00C693",
|
|
1716
1957
|
opacity: 0.1
|
|
1717
1958
|
}
|
|
1718
|
-
), /* @__PURE__ */
|
|
1959
|
+
), /* @__PURE__ */ React24.createElement(
|
|
1719
1960
|
Circle2,
|
|
1720
1961
|
{
|
|
1721
1962
|
cx: 32,
|
|
@@ -1723,8 +1964,8 @@ var SuccessIcon = ({ size = 64 }) => {
|
|
|
1723
1964
|
r: 24,
|
|
1724
1965
|
fill: "#00C693"
|
|
1725
1966
|
}
|
|
1726
|
-
), /* @__PURE__ */
|
|
1727
|
-
|
|
1967
|
+
), /* @__PURE__ */ React24.createElement(
|
|
1968
|
+
Path10,
|
|
1728
1969
|
{
|
|
1729
1970
|
d: "M24 32l6 6 12-12",
|
|
1730
1971
|
stroke: "white",
|
|
@@ -1736,10 +1977,10 @@ var SuccessIcon = ({ size = 64 }) => {
|
|
|
1736
1977
|
};
|
|
1737
1978
|
|
|
1738
1979
|
// src/assets/ErrorIcon.tsx
|
|
1739
|
-
import
|
|
1740
|
-
import
|
|
1980
|
+
import React25 from "react";
|
|
1981
|
+
import Svg11, { Circle as Circle3, Path as Path11 } from "react-native-svg";
|
|
1741
1982
|
var ErrorIcon = ({ size = 64 }) => {
|
|
1742
|
-
return /* @__PURE__ */
|
|
1983
|
+
return /* @__PURE__ */ React25.createElement(Svg11, { width: size, height: size, viewBox: "0 0 64 64", fill: "none" }, /* @__PURE__ */ React25.createElement(
|
|
1743
1984
|
Circle3,
|
|
1744
1985
|
{
|
|
1745
1986
|
cx: 32,
|
|
@@ -1748,7 +1989,7 @@ var ErrorIcon = ({ size = 64 }) => {
|
|
|
1748
1989
|
fill: "#EF4444",
|
|
1749
1990
|
opacity: 0.1
|
|
1750
1991
|
}
|
|
1751
|
-
), /* @__PURE__ */
|
|
1992
|
+
), /* @__PURE__ */ React25.createElement(
|
|
1752
1993
|
Circle3,
|
|
1753
1994
|
{
|
|
1754
1995
|
cx: 32,
|
|
@@ -1756,8 +1997,8 @@ var ErrorIcon = ({ size = 64 }) => {
|
|
|
1756
1997
|
r: 24,
|
|
1757
1998
|
fill: "#EF4444"
|
|
1758
1999
|
}
|
|
1759
|
-
), /* @__PURE__ */
|
|
1760
|
-
|
|
2000
|
+
), /* @__PURE__ */ React25.createElement(
|
|
2001
|
+
Path11,
|
|
1761
2002
|
{
|
|
1762
2003
|
d: "M24 24l16 16M40 24l-16 16",
|
|
1763
2004
|
stroke: "white",
|
|
@@ -1769,18 +2010,18 @@ var ErrorIcon = ({ size = 64 }) => {
|
|
|
1769
2010
|
};
|
|
1770
2011
|
|
|
1771
2012
|
// src/assets/SearchIcon.tsx
|
|
1772
|
-
import
|
|
1773
|
-
import
|
|
2013
|
+
import React26 from "react";
|
|
2014
|
+
import Svg12, { Circle as Circle4, Path as Path12 } from "react-native-svg";
|
|
1774
2015
|
|
|
1775
2016
|
// src/assets/PlusIcon.tsx
|
|
1776
|
-
import
|
|
1777
|
-
import
|
|
2017
|
+
import React27 from "react";
|
|
2018
|
+
import Svg13, { Path as Path13 } from "react-native-svg";
|
|
1778
2019
|
var PlusIcon = ({
|
|
1779
2020
|
size = 14,
|
|
1780
2021
|
color = "#6B7280"
|
|
1781
2022
|
}) => {
|
|
1782
|
-
return /* @__PURE__ */
|
|
1783
|
-
|
|
2023
|
+
return /* @__PURE__ */ React27.createElement(Svg13, { width: size, height: size, viewBox: "0 0 14 14", fill: "none" }, /* @__PURE__ */ React27.createElement(
|
|
2024
|
+
Path13,
|
|
1784
2025
|
{
|
|
1785
2026
|
d: "M7 3.5v7M3.5 7h7",
|
|
1786
2027
|
stroke: color,
|
|
@@ -1792,13 +2033,13 @@ var PlusIcon = ({
|
|
|
1792
2033
|
|
|
1793
2034
|
// src/wallet-connect/index.tsx
|
|
1794
2035
|
import { useAccount, useAppKit } from "@reown/appkit-react-native";
|
|
1795
|
-
import
|
|
2036
|
+
import React29, { useEffect as useEffect2, useMemo, useState } from "react";
|
|
1796
2037
|
import {
|
|
1797
2038
|
ScrollView as ScrollView2,
|
|
1798
|
-
StyleSheet as
|
|
1799
|
-
Text as
|
|
1800
|
-
TouchableOpacity as
|
|
1801
|
-
View as
|
|
2039
|
+
StyleSheet as StyleSheet13,
|
|
2040
|
+
Text as Text11,
|
|
2041
|
+
TouchableOpacity as TouchableOpacity4,
|
|
2042
|
+
View as View13
|
|
1802
2043
|
} from "react-native";
|
|
1803
2044
|
|
|
1804
2045
|
// src/utils/uuid.ts
|
|
@@ -1811,7 +2052,7 @@ function generateUUID() {
|
|
|
1811
2052
|
}
|
|
1812
2053
|
|
|
1813
2054
|
// src/wallet-connect/wallet-connect.tsx
|
|
1814
|
-
import
|
|
2055
|
+
import React28 from "react";
|
|
1815
2056
|
import { AppKit, AppKitProvider } from "@reown/appkit-react-native";
|
|
1816
2057
|
|
|
1817
2058
|
// src/wallet-connect/AppKitConfig.ts
|
|
@@ -1920,7 +2161,7 @@ var createAppKitInstance = (projectId) => {
|
|
|
1920
2161
|
// src/wallet-connect/wallet-connect.tsx
|
|
1921
2162
|
var WalletConnectWrapper = ({ children }) => {
|
|
1922
2163
|
const { walletConnectProjectId } = useKryptosConnect();
|
|
1923
|
-
const appKit =
|
|
2164
|
+
const appKit = React28.useMemo(() => {
|
|
1924
2165
|
if (!walletConnectProjectId) {
|
|
1925
2166
|
console.warn(
|
|
1926
2167
|
"walletConnectProjectId is missing in KryptosConnectProvider config"
|
|
@@ -1930,9 +2171,9 @@ var WalletConnectWrapper = ({ children }) => {
|
|
|
1930
2171
|
return createAppKitInstance(walletConnectProjectId);
|
|
1931
2172
|
}, [walletConnectProjectId]);
|
|
1932
2173
|
if (!appKit) {
|
|
1933
|
-
return /* @__PURE__ */
|
|
2174
|
+
return /* @__PURE__ */ React28.createElement(React28.Fragment, null, children);
|
|
1934
2175
|
}
|
|
1935
|
-
return /* @__PURE__ */
|
|
2176
|
+
return /* @__PURE__ */ React28.createElement(AppKitProvider, { instance: appKit }, /* @__PURE__ */ React28.createElement(AppKit, null), children);
|
|
1936
2177
|
};
|
|
1937
2178
|
var wallet_connect_default = WalletConnectWrapper;
|
|
1938
2179
|
|
|
@@ -1943,47 +2184,48 @@ var WalletConnectComponent = ({
|
|
|
1943
2184
|
onAddHandle,
|
|
1944
2185
|
handleClose,
|
|
1945
2186
|
modalOpen,
|
|
1946
|
-
setAddIntegrationMode
|
|
2187
|
+
setAddIntegrationMode,
|
|
2188
|
+
providersList
|
|
1947
2189
|
}) => {
|
|
1948
2190
|
const { walletConnectProjectId } = useKryptosConnect();
|
|
1949
2191
|
const theme = useTheme();
|
|
1950
2192
|
if (!walletConnectProjectId) {
|
|
1951
|
-
return /* @__PURE__ */
|
|
1952
|
-
|
|
2193
|
+
return /* @__PURE__ */ React29.createElement(Modal, { isOpen: modalOpen, onClose: handleClose, size: "full" }, /* @__PURE__ */ React29.createElement(ModalHeader, { onClose: handleClose }, /* @__PURE__ */ React29.createElement(View13, { style: styles13.headerContent }, /* @__PURE__ */ React29.createElement(
|
|
2194
|
+
TouchableOpacity4,
|
|
1953
2195
|
{
|
|
1954
2196
|
onPress: () => {
|
|
1955
2197
|
setAddIntegrationMode(null);
|
|
1956
2198
|
},
|
|
1957
|
-
style:
|
|
2199
|
+
style: styles13.backButton
|
|
1958
2200
|
},
|
|
1959
|
-
/* @__PURE__ */
|
|
1960
|
-
), /* @__PURE__ */
|
|
1961
|
-
|
|
2201
|
+
/* @__PURE__ */ React29.createElement(ArrowLeftIcon, { size: 20, color: theme.colors.text })
|
|
2202
|
+
), /* @__PURE__ */ React29.createElement(Text11, { style: [styles13.headerTitle, { color: theme.colors.text }] }, "Integration"))), /* @__PURE__ */ React29.createElement(ModalBody, { scrollable: false, style: styles13.contentContainer }, /* @__PURE__ */ React29.createElement(View13, { style: styles13.emptyState }, /* @__PURE__ */ React29.createElement(
|
|
2203
|
+
Text11,
|
|
1962
2204
|
{
|
|
1963
|
-
style: [
|
|
2205
|
+
style: [styles13.emptyStateTitle, { color: theme.colors.text }]
|
|
1964
2206
|
},
|
|
1965
2207
|
"WalletConnect is not configured"
|
|
1966
|
-
), /* @__PURE__ */
|
|
1967
|
-
|
|
2208
|
+
), /* @__PURE__ */ React29.createElement(
|
|
2209
|
+
Text11,
|
|
1968
2210
|
{
|
|
1969
2211
|
style: [
|
|
1970
|
-
|
|
2212
|
+
styles13.infoText,
|
|
1971
2213
|
{ color: theme.colors.textSecondary, textAlign: "center" }
|
|
1972
2214
|
]
|
|
1973
2215
|
},
|
|
1974
2216
|
"Please add a walletConnectProjectId to KryptosConnectProvider to enable wallet connections."
|
|
1975
|
-
), /* @__PURE__ */
|
|
2217
|
+
), /* @__PURE__ */ React29.createElement(
|
|
1976
2218
|
Button,
|
|
1977
2219
|
{
|
|
1978
2220
|
variant: "outline",
|
|
1979
2221
|
size: "sm",
|
|
1980
2222
|
onPress: () => setAddIntegrationMode(null),
|
|
1981
|
-
style:
|
|
2223
|
+
style: styles13.emptyStateButton
|
|
1982
2224
|
},
|
|
1983
2225
|
"Go back"
|
|
1984
2226
|
))));
|
|
1985
2227
|
}
|
|
1986
|
-
return /* @__PURE__ */
|
|
2228
|
+
return /* @__PURE__ */ React29.createElement(wallet_connect_default, null, /* @__PURE__ */ React29.createElement(
|
|
1987
2229
|
ConnectButton,
|
|
1988
2230
|
{
|
|
1989
2231
|
integration,
|
|
@@ -1991,7 +2233,8 @@ var WalletConnectComponent = ({
|
|
|
1991
2233
|
onClose,
|
|
1992
2234
|
handleClose,
|
|
1993
2235
|
modalOpen,
|
|
1994
|
-
setAddIntegrationMode
|
|
2236
|
+
setAddIntegrationMode,
|
|
2237
|
+
providersList
|
|
1995
2238
|
}
|
|
1996
2239
|
));
|
|
1997
2240
|
};
|
|
@@ -2000,17 +2243,85 @@ function ConnectButton({
|
|
|
2000
2243
|
onAddHandle,
|
|
2001
2244
|
handleClose,
|
|
2002
2245
|
modalOpen,
|
|
2003
|
-
setAddIntegrationMode
|
|
2246
|
+
setAddIntegrationMode,
|
|
2247
|
+
providersList
|
|
2004
2248
|
}) {
|
|
2005
2249
|
const theme = useTheme();
|
|
2006
2250
|
const { open, disconnect } = useAppKit();
|
|
2007
|
-
const { address, isConnected
|
|
2251
|
+
const { address, isConnected } = useAccount();
|
|
2008
2252
|
const { linkToken, user, clientId } = useKryptosConnect();
|
|
2009
2253
|
const [selectedChains, setSelectedChains] = useState(/* @__PURE__ */ new Set());
|
|
2010
2254
|
const [errorMessage, setErrorMessage] = useState("");
|
|
2011
2255
|
const [chainErrors, setChainErrors] = useState({});
|
|
2012
2256
|
const [isLoading, setIsLoading] = useState(false);
|
|
2013
|
-
const userUsedChains =
|
|
2257
|
+
const [userUsedChains, setUserUsedChains] = useState([]);
|
|
2258
|
+
const [isFetchingChains, setIsFetchingChains] = useState(false);
|
|
2259
|
+
const availableChains = useMemo(() => {
|
|
2260
|
+
if (userUsedChains.length > 0) {
|
|
2261
|
+
return userUsedChains;
|
|
2262
|
+
}
|
|
2263
|
+
if (integration.walletSupportedChains && integration.walletSupportedChains.length > 0) {
|
|
2264
|
+
return integration.walletSupportedChains;
|
|
2265
|
+
}
|
|
2266
|
+
return [];
|
|
2267
|
+
}, [userUsedChains, integration.walletSupportedChains]);
|
|
2268
|
+
useEffect2(() => {
|
|
2269
|
+
if (!isConnected || !address || !address.trim()) {
|
|
2270
|
+
setUserUsedChains([]);
|
|
2271
|
+
setSelectedChains(/* @__PURE__ */ new Set());
|
|
2272
|
+
setIsFetchingChains(false);
|
|
2273
|
+
return;
|
|
2274
|
+
}
|
|
2275
|
+
const debounceTimer = setTimeout(async () => {
|
|
2276
|
+
if (linkToken && address && address.trim() && isConnected) {
|
|
2277
|
+
try {
|
|
2278
|
+
setIsFetchingChains(true);
|
|
2279
|
+
let chains = [];
|
|
2280
|
+
if (integration.isEvmWallet) {
|
|
2281
|
+
const res = await getUserUsedChains(linkToken, address.trim());
|
|
2282
|
+
if (res && Array.isArray(res) && res.length > 0) {
|
|
2283
|
+
chains = res;
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
if (chains.length === 0 && integration.walletSupportedChains && integration.walletSupportedChains.length > 0) {
|
|
2287
|
+
chains = integration.walletSupportedChains;
|
|
2288
|
+
}
|
|
2289
|
+
if (chains.length > 0) {
|
|
2290
|
+
setUserUsedChains(chains);
|
|
2291
|
+
setSelectedChains(new Set(chains.map((chain) => chain.id)));
|
|
2292
|
+
} else {
|
|
2293
|
+
setUserUsedChains([]);
|
|
2294
|
+
setSelectedChains(/* @__PURE__ */ new Set());
|
|
2295
|
+
}
|
|
2296
|
+
} catch (error) {
|
|
2297
|
+
console.error("Failed to fetch user chains:", error);
|
|
2298
|
+
if (integration.walletSupportedChains && integration.walletSupportedChains.length > 0) {
|
|
2299
|
+
setUserUsedChains(integration.walletSupportedChains);
|
|
2300
|
+
setSelectedChains(
|
|
2301
|
+
new Set(
|
|
2302
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2303
|
+
integration.walletSupportedChains.map((chain) => chain.id)
|
|
2304
|
+
)
|
|
2305
|
+
);
|
|
2306
|
+
} else {
|
|
2307
|
+
setUserUsedChains([]);
|
|
2308
|
+
setSelectedChains(/* @__PURE__ */ new Set());
|
|
2309
|
+
}
|
|
2310
|
+
} finally {
|
|
2311
|
+
setIsFetchingChains(false);
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
}, 500);
|
|
2315
|
+
return () => {
|
|
2316
|
+
clearTimeout(debounceTimer);
|
|
2317
|
+
};
|
|
2318
|
+
}, [
|
|
2319
|
+
linkToken,
|
|
2320
|
+
address,
|
|
2321
|
+
isConnected,
|
|
2322
|
+
integration.isEvmWallet,
|
|
2323
|
+
integration.walletSupportedChains
|
|
2324
|
+
]);
|
|
2014
2325
|
const validateForm = () => {
|
|
2015
2326
|
if (!address) {
|
|
2016
2327
|
setErrorMessage("Please connect a wallet");
|
|
@@ -2028,7 +2339,7 @@ function ConnectButton({
|
|
|
2028
2339
|
setIsLoading(true);
|
|
2029
2340
|
setErrorMessage("");
|
|
2030
2341
|
setChainErrors({});
|
|
2031
|
-
const chainsToProcess =
|
|
2342
|
+
const chainsToProcess = availableChains.filter(
|
|
2032
2343
|
(c) => selectedChains.has(c.id)
|
|
2033
2344
|
);
|
|
2034
2345
|
const integrationsToAdd = [];
|
|
@@ -2036,46 +2347,49 @@ function ConnectButton({
|
|
|
2036
2347
|
const walletTestsPayload = chainsToProcess.map((chain) => {
|
|
2037
2348
|
const walletId = generateUUID();
|
|
2038
2349
|
const displaySuffix = address ? address?.length > 8 ? `${address.slice(0, 4)}...${address.slice(-4)}` : address : "";
|
|
2039
|
-
const alias = `${
|
|
2350
|
+
const alias = `${chain.id} (${displaySuffix})`;
|
|
2351
|
+
const provider = providersList.find((p) => p.id === chain.id);
|
|
2040
2352
|
return {
|
|
2041
2353
|
chain,
|
|
2042
2354
|
walletId,
|
|
2043
2355
|
alias,
|
|
2044
2356
|
credential: {
|
|
2045
|
-
source:
|
|
2357
|
+
source: provider?.id,
|
|
2046
2358
|
credential: {
|
|
2047
2359
|
address,
|
|
2048
|
-
userId: user?.
|
|
2049
|
-
projectId:
|
|
2360
|
+
userId: user?.user_id || "0",
|
|
2361
|
+
projectId: provider?.projectId,
|
|
2050
2362
|
apiKey: "0",
|
|
2051
2363
|
secret: "0",
|
|
2052
2364
|
privateKey: "0",
|
|
2053
2365
|
alias,
|
|
2054
2366
|
walletId,
|
|
2055
|
-
exchange:
|
|
2367
|
+
exchange: provider?.id
|
|
2056
2368
|
}
|
|
2057
2369
|
}
|
|
2058
2370
|
};
|
|
2059
2371
|
});
|
|
2060
2372
|
const results = await Promise.allSettled(
|
|
2373
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2061
2374
|
walletTestsPayload.map(
|
|
2062
|
-
(
|
|
2375
|
+
(testData) => testCredentials(linkToken, { ...testData.credential })
|
|
2063
2376
|
)
|
|
2064
2377
|
);
|
|
2065
2378
|
results.forEach((result, index) => {
|
|
2066
2379
|
const { chain, walletId, alias } = walletTestsPayload[index];
|
|
2067
|
-
|
|
2380
|
+
const provider = providersList.find((p) => p.id === chain.id);
|
|
2381
|
+
if (result.status === "fulfilled" && result.value?.valid && provider) {
|
|
2068
2382
|
const data = {
|
|
2069
2383
|
alias,
|
|
2070
|
-
exchange:
|
|
2071
|
-
id:
|
|
2072
|
-
public_name:
|
|
2384
|
+
exchange: provider.id.toLowerCase(),
|
|
2385
|
+
id: provider.id,
|
|
2386
|
+
public_name: provider.public_name,
|
|
2073
2387
|
sync_time: (/* @__PURE__ */ new Date()).getTime(),
|
|
2074
2388
|
fetchAll: true,
|
|
2075
|
-
logo:
|
|
2389
|
+
logo: provider.logo || null,
|
|
2076
2390
|
startTime: null,
|
|
2077
2391
|
endTime: null,
|
|
2078
|
-
uid: user?.
|
|
2392
|
+
uid: user?.user_id || "",
|
|
2079
2393
|
walletId,
|
|
2080
2394
|
clientMetadata: {
|
|
2081
2395
|
clientId,
|
|
@@ -2085,18 +2399,27 @@ function ConnectButton({
|
|
|
2085
2399
|
environment: "sandbox"
|
|
2086
2400
|
},
|
|
2087
2401
|
addedOn: (/* @__PURE__ */ new Date()).getTime(),
|
|
2088
|
-
default_chain:
|
|
2089
|
-
default_chain_logo:
|
|
2090
|
-
type:
|
|
2091
|
-
isNftSupported:
|
|
2092
|
-
chainId: chain.chainId || chain.id,
|
|
2093
|
-
address
|
|
2402
|
+
default_chain: provider.id,
|
|
2403
|
+
default_chain_logo: null,
|
|
2404
|
+
type: provider.type,
|
|
2405
|
+
isNftSupported: provider.isEvmWallet || provider.nftSupport || false
|
|
2094
2406
|
};
|
|
2095
2407
|
integrationsToAdd.push(data);
|
|
2096
2408
|
} else {
|
|
2097
|
-
|
|
2409
|
+
if (result.status === "rejected") {
|
|
2410
|
+
errors[chain.id] = result.reason?.response?.data?.message || "Failed to process chain";
|
|
2411
|
+
} else if (result.status === "fulfilled") {
|
|
2412
|
+
errors[chain.id] = result.value?.message || "Failed to verify chain";
|
|
2413
|
+
}
|
|
2098
2414
|
}
|
|
2099
2415
|
});
|
|
2416
|
+
setChainErrors(errors);
|
|
2417
|
+
if (Object.keys(errors).length > 0) {
|
|
2418
|
+
setErrorMessage(
|
|
2419
|
+
`Cannot add integrations. ${Object.keys(errors).length} chain${Object.keys(errors).length > 1 ? "s" : ""} failed verification. Please fix the errors and try again.`
|
|
2420
|
+
);
|
|
2421
|
+
return;
|
|
2422
|
+
}
|
|
2100
2423
|
if (integrationsToAdd.length > 0) {
|
|
2101
2424
|
onAddHandle(integrationsToAdd);
|
|
2102
2425
|
setChainErrors({});
|
|
@@ -2114,138 +2437,180 @@ function ConnectButton({
|
|
|
2114
2437
|
setIsLoading(false);
|
|
2115
2438
|
}
|
|
2116
2439
|
};
|
|
2117
|
-
const toggleChainSelection = (
|
|
2440
|
+
const toggleChainSelection = (chainId) => {
|
|
2118
2441
|
const newSelected = new Set(selectedChains);
|
|
2119
|
-
if (newSelected.has(
|
|
2120
|
-
newSelected.delete(
|
|
2442
|
+
if (newSelected.has(chainId)) {
|
|
2443
|
+
newSelected.delete(chainId);
|
|
2121
2444
|
} else {
|
|
2122
|
-
newSelected.add(
|
|
2445
|
+
newSelected.add(chainId);
|
|
2123
2446
|
}
|
|
2124
2447
|
setSelectedChains(newSelected);
|
|
2125
|
-
if (chainErrors[
|
|
2448
|
+
if (chainErrors[chainId]) {
|
|
2126
2449
|
const newErrors = { ...chainErrors };
|
|
2127
|
-
delete newErrors[
|
|
2450
|
+
delete newErrors[chainId];
|
|
2128
2451
|
setChainErrors(newErrors);
|
|
2129
2452
|
}
|
|
2130
2453
|
};
|
|
2131
|
-
return /* @__PURE__ */
|
|
2132
|
-
|
|
2454
|
+
return /* @__PURE__ */ React29.createElement(Modal, { isOpen: modalOpen, onClose: handleClose, size: "full" }, /* @__PURE__ */ React29.createElement(ModalHeader, { onClose: handleClose }, /* @__PURE__ */ React29.createElement(View13, { style: styles13.headerContent }, /* @__PURE__ */ React29.createElement(
|
|
2455
|
+
TouchableOpacity4,
|
|
2133
2456
|
{
|
|
2134
2457
|
onPress: () => {
|
|
2135
2458
|
setAddIntegrationMode(null);
|
|
2136
2459
|
},
|
|
2137
|
-
style:
|
|
2460
|
+
style: styles13.backButton
|
|
2461
|
+
},
|
|
2462
|
+
/* @__PURE__ */ React29.createElement(ArrowLeftIcon, { size: 20, color: theme.colors.text })
|
|
2463
|
+
), /* @__PURE__ */ React29.createElement(Text11, { style: [styles13.headerTitle, { color: theme.colors.text }] }, "Integration"))), /* @__PURE__ */ React29.createElement(ModalBody, { scrollable: false, style: styles13.contentContainer }, !isConnected ? /* @__PURE__ */ React29.createElement(View13, null, /* @__PURE__ */ React29.createElement(Text11, { style: [styles13.infoText, { color: theme.colors.text }] }, "Connect your wallet to continue"), /* @__PURE__ */ React29.createElement(
|
|
2464
|
+
Button,
|
|
2465
|
+
{
|
|
2466
|
+
variant: "primary",
|
|
2467
|
+
size: "sm",
|
|
2468
|
+
onPress: () => open({ view: "Connect" })
|
|
2469
|
+
},
|
|
2470
|
+
"Connect Wallet"
|
|
2471
|
+
)) : /* @__PURE__ */ React29.createElement(View13, { style: styles13.connectedContainer }, /* @__PURE__ */ React29.createElement(View13, { style: styles13.connectedHeader }, /* @__PURE__ */ React29.createElement(
|
|
2472
|
+
Text11,
|
|
2473
|
+
{
|
|
2474
|
+
style: [styles13.connectedTitle, { color: theme.colors.text }]
|
|
2475
|
+
},
|
|
2476
|
+
"Wallet Connected"
|
|
2477
|
+
), /* @__PURE__ */ React29.createElement(
|
|
2478
|
+
Text11,
|
|
2479
|
+
{
|
|
2480
|
+
style: [styles13.connectedText, { color: theme.colors.text }]
|
|
2481
|
+
},
|
|
2482
|
+
"Address: ",
|
|
2483
|
+
address
|
|
2484
|
+
), /* @__PURE__ */ React29.createElement(Button, { variant: "ghost", size: "sm", onPress: () => disconnect() }, "Disconnect Wallet"), isFetchingChains ? /* @__PURE__ */ React29.createElement(
|
|
2485
|
+
Text11,
|
|
2486
|
+
{
|
|
2487
|
+
style: [styles13.fetchingText, { color: theme.colors.text }]
|
|
2138
2488
|
},
|
|
2139
|
-
|
|
2140
|
-
)
|
|
2141
|
-
|
|
2489
|
+
"Fetching chains..."
|
|
2490
|
+
) : null), availableChains.length > 0 && address && /* @__PURE__ */ React29.createElement(
|
|
2491
|
+
ScrollView2,
|
|
2142
2492
|
{
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2493
|
+
style: styles13.scrollView,
|
|
2494
|
+
contentContainerStyle: styles13.scrollViewContent,
|
|
2495
|
+
showsVerticalScrollIndicator: true,
|
|
2496
|
+
nestedScrollEnabled: true
|
|
2146
2497
|
},
|
|
2147
|
-
"
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
{
|
|
2154
|
-
onPress: () => toggleChainSelection(chain.id),
|
|
2155
|
-
style: styles9.chainButton,
|
|
2156
|
-
key: chain.id
|
|
2157
|
-
},
|
|
2158
|
-
/* @__PURE__ */ React24.createElement(
|
|
2159
|
-
View9,
|
|
2498
|
+
/* @__PURE__ */ React29.createElement(Text11, { style: [styles13.chainTitle, { color: theme.colors.text }] }, "Select Chains to Add:"),
|
|
2499
|
+
/* @__PURE__ */ React29.createElement(View13, null, /* @__PURE__ */ React29.createElement(View13, { style: styles13.chainChips }, availableChains.map((chain) => {
|
|
2500
|
+
const isSelected = selectedChains.has(chain.id);
|
|
2501
|
+
const hasError = chainErrors[chain.id];
|
|
2502
|
+
return /* @__PURE__ */ React29.createElement(
|
|
2503
|
+
TouchableOpacity4,
|
|
2160
2504
|
{
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
backgroundColor: hasError ? theme.colors.errorLight : isSelected ? theme.colors.primary + "20" : theme.colors.surface,
|
|
2165
|
-
borderColor: hasError ? theme.colors.error : isSelected ? theme.colors.primary : theme.colors.border
|
|
2166
|
-
}
|
|
2167
|
-
]
|
|
2505
|
+
onPress: () => toggleChainSelection(chain.id),
|
|
2506
|
+
style: styles13.chainButton,
|
|
2507
|
+
key: chain.id
|
|
2168
2508
|
},
|
|
2169
|
-
/* @__PURE__ */
|
|
2170
|
-
|
|
2509
|
+
/* @__PURE__ */ React29.createElement(
|
|
2510
|
+
View13,
|
|
2171
2511
|
{
|
|
2172
2512
|
style: [
|
|
2173
|
-
|
|
2513
|
+
styles13.chainChip,
|
|
2174
2514
|
{
|
|
2175
|
-
|
|
2515
|
+
backgroundColor: hasError ? theme.colors.errorLight : isSelected ? theme.colors.primary + "20" : theme.colors.surface,
|
|
2516
|
+
borderColor: hasError ? theme.colors.error : isSelected ? theme.colors.primary : theme.colors.border
|
|
2176
2517
|
}
|
|
2177
2518
|
]
|
|
2178
2519
|
},
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2520
|
+
/* @__PURE__ */ React29.createElement(
|
|
2521
|
+
Text11,
|
|
2522
|
+
{
|
|
2523
|
+
style: [
|
|
2524
|
+
styles13.chainName,
|
|
2525
|
+
{
|
|
2526
|
+
color: hasError ? theme.colors.error : isSelected ? theme.colors.primary : theme.colors.text
|
|
2527
|
+
}
|
|
2528
|
+
]
|
|
2529
|
+
},
|
|
2530
|
+
chain.id
|
|
2531
|
+
),
|
|
2532
|
+
isSelected ? /* @__PURE__ */ React29.createElement(
|
|
2533
|
+
CloseIcon,
|
|
2534
|
+
{
|
|
2535
|
+
size: 12,
|
|
2536
|
+
color: hasError ? theme.colors.error : theme.colors.primary
|
|
2537
|
+
}
|
|
2538
|
+
) : /* @__PURE__ */ React29.createElement(
|
|
2539
|
+
PlusIcon,
|
|
2540
|
+
{
|
|
2541
|
+
size: 12,
|
|
2542
|
+
color: theme.colors.textSecondary
|
|
2543
|
+
}
|
|
2544
|
+
)
|
|
2193
2545
|
)
|
|
2194
|
-
)
|
|
2195
|
-
)
|
|
2196
|
-
|
|
2197
|
-
Text9,
|
|
2198
|
-
{
|
|
2199
|
-
style: [
|
|
2200
|
-
styles9.chainErrorsTitle,
|
|
2201
|
-
{ color: theme.colors.error }
|
|
2202
|
-
]
|
|
2203
|
-
},
|
|
2204
|
-
"Errors:"
|
|
2205
|
-
), Object.entries(chainErrors).map(([chainId2, error]) => {
|
|
2206
|
-
const chain = userUsedChains.find(
|
|
2207
|
-
(c) => c.id === chainId2
|
|
2208
|
-
);
|
|
2209
|
-
return /* @__PURE__ */ React24.createElement(
|
|
2210
|
-
Text9,
|
|
2546
|
+
);
|
|
2547
|
+
})), errorMessage ? /* @__PURE__ */ React29.createElement(View13, { style: styles13.errorMessageContainer }, /* @__PURE__ */ React29.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React29.createElement(AlertDescription, null, errorMessage))) : null, Object.keys(chainErrors || {}).length > 0 && /* @__PURE__ */ React29.createElement(View13, { style: styles13.chainErrorsContainer }, /* @__PURE__ */ React29.createElement(
|
|
2548
|
+
Text11,
|
|
2211
2549
|
{
|
|
2212
|
-
key: chainId2,
|
|
2213
2550
|
style: [
|
|
2214
|
-
|
|
2551
|
+
styles13.chainErrorsTitle,
|
|
2215
2552
|
{ color: theme.colors.error }
|
|
2216
2553
|
]
|
|
2217
2554
|
},
|
|
2218
|
-
"
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2555
|
+
"Errors:"
|
|
2556
|
+
), Object.entries(chainErrors).map(([chainId, error]) => {
|
|
2557
|
+
const chain = availableChains.find(
|
|
2558
|
+
(c) => c.id === chainId
|
|
2559
|
+
);
|
|
2560
|
+
return /* @__PURE__ */ React29.createElement(
|
|
2561
|
+
Text11,
|
|
2562
|
+
{
|
|
2563
|
+
key: chainId,
|
|
2564
|
+
style: [
|
|
2565
|
+
styles13.chainErrorItem,
|
|
2566
|
+
{ color: theme.colors.error }
|
|
2567
|
+
]
|
|
2568
|
+
},
|
|
2569
|
+
"\u2022 ",
|
|
2570
|
+
chain?.name ?? chainId,
|
|
2571
|
+
": ",
|
|
2572
|
+
String(error)
|
|
2573
|
+
);
|
|
2574
|
+
})))
|
|
2575
|
+
))), availableChains.length > 0 && address && /* @__PURE__ */ React29.createElement(ModalFooter, { style: { paddingVertical: 8 } }, /* @__PURE__ */ React29.createElement(
|
|
2224
2576
|
Button,
|
|
2225
2577
|
{
|
|
2226
2578
|
variant: "outline",
|
|
2227
2579
|
size: "lg",
|
|
2228
2580
|
onPress: onSubmitWalletConnect,
|
|
2229
2581
|
loading: isLoading,
|
|
2230
|
-
disabled: isLoading || !!address &&
|
|
2231
|
-
style:
|
|
2582
|
+
disabled: isLoading || !!address && availableChains.length > 0 && selectedChains.size === 0,
|
|
2583
|
+
style: styles13.button
|
|
2232
2584
|
},
|
|
2233
2585
|
selectedChains.size > 0 ? `Add ${selectedChains.size} Chain${selectedChains.size > 1 ? "s" : ""}` : "Add Integration"
|
|
2234
|
-
)));
|
|
2586
|
+
), /* @__PURE__ */ React29.createElement(Footer, null)));
|
|
2235
2587
|
}
|
|
2236
|
-
var
|
|
2237
|
-
|
|
2588
|
+
var styles13 = StyleSheet13.create({
|
|
2589
|
+
connectedContainer: {
|
|
2590
|
+
flex: 1
|
|
2591
|
+
},
|
|
2592
|
+
connectedHeader: {
|
|
2593
|
+
marginBottom: 8
|
|
2594
|
+
},
|
|
2595
|
+
connectedTitle: { fontSize: 12, fontWeight: "600", marginBottom: 4 },
|
|
2238
2596
|
connectedText: { fontSize: 14, marginBottom: 4 },
|
|
2597
|
+
fetchingText: { fontSize: 12, marginBottom: 4, textAlign: "center" },
|
|
2239
2598
|
infoText: {
|
|
2240
2599
|
fontSize: 16,
|
|
2241
2600
|
fontWeight: "600",
|
|
2242
2601
|
marginBottom: 8,
|
|
2243
2602
|
textAlign: "center"
|
|
2244
2603
|
},
|
|
2604
|
+
scrollView: {
|
|
2605
|
+
flex: 1
|
|
2606
|
+
},
|
|
2245
2607
|
scrollViewContent: {
|
|
2246
|
-
paddingBottom:
|
|
2608
|
+
paddingBottom: 40,
|
|
2247
2609
|
flexGrow: 1
|
|
2248
2610
|
},
|
|
2611
|
+
errorMessageContainer: {
|
|
2612
|
+
marginTop: 16
|
|
2613
|
+
},
|
|
2249
2614
|
headerContent: {
|
|
2250
2615
|
flexDirection: "row",
|
|
2251
2616
|
alignItems: "center"
|
|
@@ -2264,17 +2629,13 @@ var styles9 = StyleSheet9.create({
|
|
|
2264
2629
|
contentContainer: {
|
|
2265
2630
|
padding: 20,
|
|
2266
2631
|
// theme.spacing.xl
|
|
2267
|
-
paddingBottom:
|
|
2632
|
+
paddingBottom: 20,
|
|
2268
2633
|
width: "100%",
|
|
2269
2634
|
overflow: "hidden",
|
|
2270
2635
|
alignSelf: "center",
|
|
2271
2636
|
flexDirection: "column",
|
|
2272
2637
|
flex: 1
|
|
2273
2638
|
},
|
|
2274
|
-
chainSelection: {
|
|
2275
|
-
marginBottom: 16
|
|
2276
|
-
// theme.spacing.lg
|
|
2277
|
-
},
|
|
2278
2639
|
chainTitle: {
|
|
2279
2640
|
fontSize: 14,
|
|
2280
2641
|
// theme.fontSize.md
|
|
@@ -2326,9 +2687,7 @@ var styles9 = StyleSheet9.create({
|
|
|
2326
2687
|
// theme.spacing.xs
|
|
2327
2688
|
},
|
|
2328
2689
|
button: {
|
|
2329
|
-
width: "100%"
|
|
2330
|
-
marginTop: 16
|
|
2331
|
-
// theme.spacing.lg - consistent button spacing
|
|
2690
|
+
width: "100%"
|
|
2332
2691
|
},
|
|
2333
2692
|
emptyState: {
|
|
2334
2693
|
flex: 1,
|
|
@@ -2346,45 +2705,54 @@ var styles9 = StyleSheet9.create({
|
|
|
2346
2705
|
});
|
|
2347
2706
|
|
|
2348
2707
|
// src/molecules/IntegrationForm.tsx
|
|
2349
|
-
import
|
|
2708
|
+
import React30 from "react";
|
|
2350
2709
|
import {
|
|
2351
2710
|
Image as Image2,
|
|
2352
2711
|
ScrollView as ScrollView3,
|
|
2353
|
-
StyleSheet as
|
|
2354
|
-
Text as
|
|
2355
|
-
TouchableOpacity as
|
|
2356
|
-
View as
|
|
2712
|
+
StyleSheet as StyleSheet14,
|
|
2713
|
+
Text as Text12,
|
|
2714
|
+
TouchableOpacity as TouchableOpacity5,
|
|
2715
|
+
View as View14
|
|
2357
2716
|
} from "react-native";
|
|
2358
2717
|
var IntegrationForm = ({
|
|
2359
2718
|
metadata,
|
|
2360
2719
|
onAddHandle,
|
|
2361
2720
|
open,
|
|
2362
2721
|
setAddIntegrationMode,
|
|
2363
|
-
handleClose
|
|
2722
|
+
handleClose,
|
|
2723
|
+
providersList
|
|
2364
2724
|
}) => {
|
|
2365
2725
|
const { clientId, linkToken, user } = useKryptosConnect();
|
|
2366
2726
|
const theme = useTheme();
|
|
2367
|
-
const [isLoading, setIsLoading] =
|
|
2368
|
-
const [
|
|
2369
|
-
const [
|
|
2727
|
+
const [isLoading, setIsLoading] = React30.useState(false);
|
|
2728
|
+
const [isFetchingChains, setIsFetchingChains] = React30.useState(false);
|
|
2729
|
+
const [userUsedChains, setUserUsedChains] = React30.useState([]);
|
|
2730
|
+
const [selectedChains, setSelectedChains] = React30.useState(
|
|
2370
2731
|
/* @__PURE__ */ new Set()
|
|
2371
2732
|
);
|
|
2372
|
-
const [chainErrors, setChainErrors] =
|
|
2733
|
+
const [chainErrors, setChainErrors] = React30.useState(
|
|
2373
2734
|
{}
|
|
2374
2735
|
);
|
|
2375
|
-
const [errorMessage, setErrorMessage] =
|
|
2376
|
-
const [formValues, setFormValues] =
|
|
2736
|
+
const [errorMessage, setErrorMessage] = React30.useState("");
|
|
2737
|
+
const [formValues, setFormValues] = React30.useState({
|
|
2377
2738
|
address: "",
|
|
2378
2739
|
account_name: "",
|
|
2379
2740
|
api_key: "",
|
|
2380
2741
|
secret_key: "",
|
|
2381
2742
|
password: ""
|
|
2382
2743
|
});
|
|
2383
|
-
const [formErrors, setFormErrors] =
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2744
|
+
const [formErrors, setFormErrors] = React30.useState({});
|
|
2745
|
+
React30.useEffect(() => {
|
|
2746
|
+
if (!formValues.address || !formValues.address.trim()) {
|
|
2747
|
+
setUserUsedChains([]);
|
|
2748
|
+
setSelectedChains(/* @__PURE__ */ new Set());
|
|
2749
|
+
setIsFetchingChains(false);
|
|
2750
|
+
return;
|
|
2751
|
+
}
|
|
2752
|
+
const debounceTimer = setTimeout(async () => {
|
|
2753
|
+
if (linkToken && formValues.address && formValues.address.trim() && metadata.isEvmWallet) {
|
|
2387
2754
|
try {
|
|
2755
|
+
setIsFetchingChains(true);
|
|
2388
2756
|
const res = await getUserUsedChains(
|
|
2389
2757
|
linkToken,
|
|
2390
2758
|
formValues.address.trim()
|
|
@@ -2392,18 +2760,22 @@ var IntegrationForm = ({
|
|
|
2392
2760
|
if (res && Array.isArray(res)) {
|
|
2393
2761
|
setUserUsedChains(res);
|
|
2394
2762
|
setSelectedChains(new Set(res.map((chain) => chain.id)));
|
|
2763
|
+
} else {
|
|
2764
|
+
setUserUsedChains([]);
|
|
2765
|
+
setSelectedChains(/* @__PURE__ */ new Set());
|
|
2395
2766
|
}
|
|
2396
2767
|
} catch (error) {
|
|
2397
2768
|
console.error("Failed to fetch user chains:", error);
|
|
2398
2769
|
setUserUsedChains([]);
|
|
2399
2770
|
setSelectedChains(/* @__PURE__ */ new Set());
|
|
2771
|
+
} finally {
|
|
2772
|
+
setIsFetchingChains(false);
|
|
2400
2773
|
}
|
|
2401
|
-
} else {
|
|
2402
|
-
setUserUsedChains([]);
|
|
2403
|
-
setSelectedChains(/* @__PURE__ */ new Set());
|
|
2404
2774
|
}
|
|
2775
|
+
}, 500);
|
|
2776
|
+
return () => {
|
|
2777
|
+
clearTimeout(debounceTimer);
|
|
2405
2778
|
};
|
|
2406
|
-
fetchUserUsedChains();
|
|
2407
2779
|
}, [linkToken, formValues.address]);
|
|
2408
2780
|
const toggleChainSelection = (chainId) => {
|
|
2409
2781
|
const newSelected = new Set(selectedChains);
|
|
@@ -2462,7 +2834,7 @@ var IntegrationForm = ({
|
|
|
2462
2834
|
accountName: formValues.account_name?.trim() || "0",
|
|
2463
2835
|
address: formValues.address?.trim() || "0",
|
|
2464
2836
|
password: formValues.password?.trim() || "0",
|
|
2465
|
-
userId: user?.
|
|
2837
|
+
userId: user?.user_id || "0",
|
|
2466
2838
|
projectId: metadata?.projectId || "0",
|
|
2467
2839
|
privateKey: "0",
|
|
2468
2840
|
alias,
|
|
@@ -2490,7 +2862,7 @@ var IntegrationForm = ({
|
|
|
2490
2862
|
logo: metadata.logo || null,
|
|
2491
2863
|
startTime: null,
|
|
2492
2864
|
endTime: null,
|
|
2493
|
-
uid: user?.
|
|
2865
|
+
uid: user?.user_id || "",
|
|
2494
2866
|
walletId,
|
|
2495
2867
|
clientMetadata: {
|
|
2496
2868
|
clientId,
|
|
@@ -2504,7 +2876,7 @@ var IntegrationForm = ({
|
|
|
2504
2876
|
default_chain_logo: chain.logo || null,
|
|
2505
2877
|
type: metadata.type,
|
|
2506
2878
|
isNftSupported: metadata.isEvmWallet || metadata.nftSupport || false,
|
|
2507
|
-
chainId: chain
|
|
2879
|
+
chainId: chain?.community_id || "",
|
|
2508
2880
|
address: formValues.address
|
|
2509
2881
|
};
|
|
2510
2882
|
if (formValues.account_name)
|
|
@@ -2541,7 +2913,7 @@ var IntegrationForm = ({
|
|
|
2541
2913
|
accountName: formValues.account_name?.trim() || "0",
|
|
2542
2914
|
address: formValues.address?.trim() || "0",
|
|
2543
2915
|
password: formValues.password?.trim() || "0",
|
|
2544
|
-
userId: user?.
|
|
2916
|
+
userId: user?.user_id || "0",
|
|
2545
2917
|
projectId: metadata?.projectId || "0",
|
|
2546
2918
|
privateKey: "0",
|
|
2547
2919
|
alias,
|
|
@@ -2550,7 +2922,7 @@ var IntegrationForm = ({
|
|
|
2550
2922
|
}
|
|
2551
2923
|
};
|
|
2552
2924
|
const testResult = await testCredentials(linkToken, { ...credential });
|
|
2553
|
-
if (!testResult?.
|
|
2925
|
+
if (!testResult?.valid) {
|
|
2554
2926
|
setErrorMessage(
|
|
2555
2927
|
testResult?.value?.message || "Credentials are invalid"
|
|
2556
2928
|
);
|
|
@@ -2566,7 +2938,7 @@ var IntegrationForm = ({
|
|
|
2566
2938
|
logo: metadata.logo || null,
|
|
2567
2939
|
startTime: null,
|
|
2568
2940
|
endTime: null,
|
|
2569
|
-
uid: user?.
|
|
2941
|
+
uid: user?.user_id || "",
|
|
2570
2942
|
walletId,
|
|
2571
2943
|
clientMetadata: {
|
|
2572
2944
|
clientId,
|
|
@@ -2582,7 +2954,7 @@ var IntegrationForm = ({
|
|
|
2582
2954
|
isNftSupported: metadata.isEvmWallet || metadata.nftSupport || false
|
|
2583
2955
|
};
|
|
2584
2956
|
if (metadata.community_id) {
|
|
2585
|
-
data.chainId =
|
|
2957
|
+
data.chainId = metadata.community_id;
|
|
2586
2958
|
}
|
|
2587
2959
|
if (formValues.address) data.address = formValues.address;
|
|
2588
2960
|
if (formValues.account_name) data.accountName = formValues.account_name;
|
|
@@ -2617,24 +2989,24 @@ var IntegrationForm = ({
|
|
|
2617
2989
|
};
|
|
2618
2990
|
const hasNoFields = !metadata.password && !metadata.secret_key && !metadata.api_key && !metadata.address && !metadata.account_name;
|
|
2619
2991
|
const shouldShowFormFields = metadata.password || metadata.secret_key || metadata.api_key || metadata.address || metadata.account_name;
|
|
2620
|
-
const renderLogo = () => metadata.logo ? /* @__PURE__ */
|
|
2992
|
+
const renderLogo = () => metadata.logo ? /* @__PURE__ */ React30.createElement(
|
|
2621
2993
|
Image2,
|
|
2622
2994
|
{
|
|
2623
2995
|
source: { uri: metadata.logo },
|
|
2624
|
-
style:
|
|
2996
|
+
style: styles14.logo,
|
|
2625
2997
|
resizeMode: "contain"
|
|
2626
2998
|
}
|
|
2627
|
-
) : /* @__PURE__ */
|
|
2628
|
-
|
|
2999
|
+
) : /* @__PURE__ */ React30.createElement(
|
|
3000
|
+
View14,
|
|
2629
3001
|
{
|
|
2630
3002
|
style: [
|
|
2631
|
-
|
|
3003
|
+
styles14.logoPlaceholder,
|
|
2632
3004
|
{ backgroundColor: theme.colors.surface }
|
|
2633
3005
|
]
|
|
2634
3006
|
},
|
|
2635
|
-
/* @__PURE__ */
|
|
3007
|
+
/* @__PURE__ */ React30.createElement(Text12, { style: { color: theme.colors.text } }, metadata.name?.charAt(0) || "?")
|
|
2636
3008
|
);
|
|
2637
|
-
const renderInput = (key, props) => /* @__PURE__ */
|
|
3009
|
+
const renderInput = (key, props) => /* @__PURE__ */ React30.createElement(
|
|
2638
3010
|
Input,
|
|
2639
3011
|
{
|
|
2640
3012
|
placeholder: props.placeholder,
|
|
@@ -2646,33 +3018,33 @@ var IntegrationForm = ({
|
|
|
2646
3018
|
secureTextEntry: props.secureTextEntry
|
|
2647
3019
|
}
|
|
2648
3020
|
);
|
|
2649
|
-
const renderErrorAlert = () => errorMessage ? /* @__PURE__ */
|
|
2650
|
-
const renderChainSelection = () => userUsedChains.length > 0 && formValues.address && /* @__PURE__ */
|
|
3021
|
+
const renderErrorAlert = () => errorMessage ? /* @__PURE__ */ React30.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React30.createElement(AlertDescription, null, errorMessage)) : null;
|
|
3022
|
+
const renderChainSelection = () => userUsedChains.length > 0 && formValues.address && /* @__PURE__ */ React30.createElement(View14, { style: styles14.chainSelection }, /* @__PURE__ */ React30.createElement(Text12, { style: [styles14.chainTitle, { color: theme.colors.text }] }, "Select Chains to Add:"), /* @__PURE__ */ React30.createElement(ScrollView3, { contentContainerStyle: styles14.scrollViewContent }, /* @__PURE__ */ React30.createElement(View14, { style: styles14.chainChips }, userUsedChains.map((chain) => {
|
|
2651
3023
|
const isSelected = selectedChains.has(chain.id);
|
|
2652
3024
|
const hasError = chainErrors[chain.id];
|
|
2653
|
-
return /* @__PURE__ */
|
|
2654
|
-
|
|
3025
|
+
return /* @__PURE__ */ React30.createElement(
|
|
3026
|
+
TouchableOpacity5,
|
|
2655
3027
|
{
|
|
2656
3028
|
onPress: () => toggleChainSelection(chain.id),
|
|
2657
|
-
style:
|
|
3029
|
+
style: styles14.chainButton,
|
|
2658
3030
|
key: chain.id
|
|
2659
3031
|
},
|
|
2660
|
-
/* @__PURE__ */
|
|
2661
|
-
|
|
3032
|
+
/* @__PURE__ */ React30.createElement(
|
|
3033
|
+
View14,
|
|
2662
3034
|
{
|
|
2663
3035
|
style: [
|
|
2664
|
-
|
|
3036
|
+
styles14.chainChip,
|
|
2665
3037
|
{
|
|
2666
3038
|
backgroundColor: hasError ? theme.colors.errorLight : isSelected ? theme.colors.primary + "20" : theme.colors.surface,
|
|
2667
3039
|
borderColor: hasError ? theme.colors.error : isSelected ? theme.colors.primary : theme.colors.border
|
|
2668
3040
|
}
|
|
2669
3041
|
]
|
|
2670
3042
|
},
|
|
2671
|
-
/* @__PURE__ */
|
|
2672
|
-
|
|
3043
|
+
/* @__PURE__ */ React30.createElement(
|
|
3044
|
+
Text12,
|
|
2673
3045
|
{
|
|
2674
3046
|
style: [
|
|
2675
|
-
|
|
3047
|
+
styles14.chainName,
|
|
2676
3048
|
{
|
|
2677
3049
|
color: hasError ? theme.colors.error : isSelected ? theme.colors.primary : theme.colors.text
|
|
2678
3050
|
}
|
|
@@ -2680,28 +3052,28 @@ var IntegrationForm = ({
|
|
|
2680
3052
|
},
|
|
2681
3053
|
chain.name
|
|
2682
3054
|
),
|
|
2683
|
-
isSelected ? /* @__PURE__ */
|
|
3055
|
+
isSelected ? /* @__PURE__ */ React30.createElement(
|
|
2684
3056
|
CloseIcon,
|
|
2685
3057
|
{
|
|
2686
3058
|
size: 12,
|
|
2687
3059
|
color: hasError ? theme.colors.error : theme.colors.primary
|
|
2688
3060
|
}
|
|
2689
|
-
) : /* @__PURE__ */
|
|
3061
|
+
) : /* @__PURE__ */ React30.createElement(PlusIcon, { size: 12, color: theme.colors.textSecondary })
|
|
2690
3062
|
)
|
|
2691
3063
|
);
|
|
2692
|
-
}))), Object.keys(chainErrors).length > 0 && /* @__PURE__ */
|
|
2693
|
-
|
|
3064
|
+
}))), Object.keys(chainErrors).length > 0 && /* @__PURE__ */ React30.createElement(View14, { style: styles14.chainErrorsContainer }, /* @__PURE__ */ React30.createElement(
|
|
3065
|
+
Text12,
|
|
2694
3066
|
{
|
|
2695
|
-
style: [
|
|
3067
|
+
style: [styles14.chainErrorsTitle, { color: theme.colors.error }]
|
|
2696
3068
|
},
|
|
2697
3069
|
"Errors:"
|
|
2698
3070
|
), Object.entries(chainErrors).map(([chainId, error]) => {
|
|
2699
3071
|
const chain = userUsedChains.find((c) => c.id === chainId);
|
|
2700
|
-
return /* @__PURE__ */
|
|
2701
|
-
|
|
3072
|
+
return /* @__PURE__ */ React30.createElement(
|
|
3073
|
+
Text12,
|
|
2702
3074
|
{
|
|
2703
3075
|
key: chainId,
|
|
2704
|
-
style: [
|
|
3076
|
+
style: [styles14.chainErrorItem, { color: theme.colors.error }]
|
|
2705
3077
|
},
|
|
2706
3078
|
"\u2022 ",
|
|
2707
3079
|
chain?.name,
|
|
@@ -2709,7 +3081,7 @@ var IntegrationForm = ({
|
|
|
2709
3081
|
error
|
|
2710
3082
|
);
|
|
2711
3083
|
})));
|
|
2712
|
-
const renderFormBlock = () => /* @__PURE__ */
|
|
3084
|
+
const renderFormBlock = () => /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement(View14, { style: styles14.header }, renderLogo(), /* @__PURE__ */ React30.createElement(Text12, { style: [styles14.name, { color: theme.colors.text }] }, metadata.name)), renderErrorAlert(), shouldShowFormFields && /* @__PURE__ */ React30.createElement(React30.Fragment, null, metadata.address && /* @__PURE__ */ React30.createElement(React30.Fragment, null, renderInput("address", {
|
|
2713
3085
|
placeholder: "Enter address",
|
|
2714
3086
|
autoCapitalize: "none",
|
|
2715
3087
|
autoCorrect: false
|
|
@@ -2725,27 +3097,27 @@ var IntegrationForm = ({
|
|
|
2725
3097
|
}), metadata.password && renderInput("password", {
|
|
2726
3098
|
placeholder: "Enter Password",
|
|
2727
3099
|
secureTextEntry: true
|
|
2728
|
-
})), hasNoFields && !metadata?.isWalletConnectSupported && /* @__PURE__ */
|
|
3100
|
+
})), hasNoFields && !metadata?.isWalletConnectSupported && /* @__PURE__ */ React30.createElement(Alert, { variant: "default", style: { marginTop: 12 } }, /* @__PURE__ */ React30.createElement(AlertDescription, null, "This integration is not supported here yet \u2014 try using it through our Kryptos Platform.")));
|
|
2729
3101
|
const addIntegrationLabel = formValues.address && userUsedChains.length > 0 && selectedChains.size > 0 ? `Add ${selectedChains.size} Chain${selectedChains.size !== 1 ? "s" : ""}` : "Add Integration";
|
|
2730
|
-
return /* @__PURE__ */
|
|
2731
|
-
|
|
3102
|
+
return /* @__PURE__ */ React30.createElement(React30.Fragment, null, !metadata?.isWalletConnectSupported ? /* @__PURE__ */ React30.createElement(Modal, { isOpen: open, onClose: handleClose, size: "full" }, /* @__PURE__ */ React30.createElement(ModalHeader, { onClose: handleClose }, /* @__PURE__ */ React30.createElement(View14, { style: styles14.headerContent }, /* @__PURE__ */ React30.createElement(
|
|
3103
|
+
TouchableOpacity5,
|
|
2732
3104
|
{
|
|
2733
3105
|
onPress: () => setAddIntegrationMode(null),
|
|
2734
|
-
style:
|
|
3106
|
+
style: styles14.backButton
|
|
2735
3107
|
},
|
|
2736
|
-
/* @__PURE__ */
|
|
2737
|
-
), /* @__PURE__ */
|
|
3108
|
+
/* @__PURE__ */ React30.createElement(ArrowLeftIcon, { size: 20, color: theme.colors.text })
|
|
3109
|
+
), /* @__PURE__ */ React30.createElement(Text12, { style: [styles14.headerTitle, { color: theme.colors.text }] }, "Integration"))), /* @__PURE__ */ React30.createElement(ModalBody, { scrollable: false, style: styles14.contentContainer }, renderFormBlock()), !hasNoFields && /* @__PURE__ */ React30.createElement(ModalFooter, { style: { paddingVertical: 8 } }, /* @__PURE__ */ React30.createElement(
|
|
2738
3110
|
Button,
|
|
2739
3111
|
{
|
|
2740
3112
|
variant: "outline",
|
|
2741
3113
|
size: "lg",
|
|
2742
3114
|
onPress: handleSubmit,
|
|
2743
3115
|
loading: isLoading,
|
|
2744
|
-
disabled: isLoading || !!formValues.address && userUsedChains.length > 0 && selectedChains.size === 0,
|
|
2745
|
-
style:
|
|
3116
|
+
disabled: isLoading || isFetchingChains || !!formValues.address && userUsedChains.length > 0 && selectedChains.size === 0,
|
|
3117
|
+
style: styles14.button
|
|
2746
3118
|
},
|
|
2747
3119
|
addIntegrationLabel
|
|
2748
|
-
))) : /* @__PURE__ */
|
|
3120
|
+
), /* @__PURE__ */ React30.createElement(Footer, null))) : /* @__PURE__ */ React30.createElement(
|
|
2749
3121
|
WalletConnectComponent,
|
|
2750
3122
|
{
|
|
2751
3123
|
integration: metadata,
|
|
@@ -2753,11 +3125,12 @@ var IntegrationForm = ({
|
|
|
2753
3125
|
onAddHandle,
|
|
2754
3126
|
modalOpen: open,
|
|
2755
3127
|
setAddIntegrationMode,
|
|
2756
|
-
handleClose
|
|
3128
|
+
handleClose,
|
|
3129
|
+
providersList
|
|
2757
3130
|
}
|
|
2758
3131
|
));
|
|
2759
3132
|
};
|
|
2760
|
-
var
|
|
3133
|
+
var styles14 = StyleSheet14.create({
|
|
2761
3134
|
scrollViewContent: {
|
|
2762
3135
|
flexGrow: 1,
|
|
2763
3136
|
paddingBottom: 100
|
|
@@ -2874,66 +3247,9 @@ var styles10 = StyleSheet10.create({
|
|
|
2874
3247
|
// theme.spacing.xs
|
|
2875
3248
|
},
|
|
2876
3249
|
button: {
|
|
2877
|
-
width: "100%"
|
|
2878
|
-
marginTop: 16
|
|
2879
|
-
// theme.spacing.lg - consistent button spacing
|
|
2880
|
-
}
|
|
2881
|
-
});
|
|
2882
|
-
|
|
2883
|
-
// src/components/SkeletonItem.tsx
|
|
2884
|
-
import React26, { useEffect, useRef } from "react";
|
|
2885
|
-
import { Animated as Animated2, View as View11, StyleSheet as StyleSheet11 } from "react-native";
|
|
2886
|
-
var SkeletonItem = () => {
|
|
2887
|
-
const opacity = useRef(new Animated2.Value(0.3)).current;
|
|
2888
|
-
useEffect(() => {
|
|
2889
|
-
Animated2.loop(
|
|
2890
|
-
Animated2.sequence([
|
|
2891
|
-
Animated2.timing(opacity, {
|
|
2892
|
-
toValue: 1,
|
|
2893
|
-
duration: 600,
|
|
2894
|
-
useNativeDriver: true
|
|
2895
|
-
}),
|
|
2896
|
-
Animated2.timing(opacity, {
|
|
2897
|
-
toValue: 0.3,
|
|
2898
|
-
duration: 600,
|
|
2899
|
-
useNativeDriver: true
|
|
2900
|
-
})
|
|
2901
|
-
])
|
|
2902
|
-
).start();
|
|
2903
|
-
}, []);
|
|
2904
|
-
return /* @__PURE__ */ React26.createElement(Animated2.View, { style: [styles11.row, { opacity }] }, /* @__PURE__ */ React26.createElement(View11, { style: styles11.iconCircle }), /* @__PURE__ */ React26.createElement(View11, { style: styles11.textBlock }, /* @__PURE__ */ React26.createElement(View11, { style: styles11.lineLong }), /* @__PURE__ */ React26.createElement(View11, { style: styles11.lineShort })));
|
|
2905
|
-
};
|
|
2906
|
-
var styles11 = StyleSheet11.create({
|
|
2907
|
-
row: {
|
|
2908
|
-
flexDirection: "row",
|
|
2909
|
-
alignItems: "center",
|
|
2910
|
-
paddingVertical: 16
|
|
2911
|
-
},
|
|
2912
|
-
iconCircle: {
|
|
2913
|
-
width: 45,
|
|
2914
|
-
height: 45,
|
|
2915
|
-
borderRadius: 22.5,
|
|
2916
|
-
backgroundColor: "#E5E5E5"
|
|
2917
|
-
},
|
|
2918
|
-
textBlock: {
|
|
2919
|
-
marginLeft: 12,
|
|
2920
|
-
flex: 1
|
|
2921
|
-
},
|
|
2922
|
-
lineShort: {
|
|
2923
|
-
width: "50%",
|
|
2924
|
-
height: 14,
|
|
2925
|
-
borderRadius: 6,
|
|
2926
|
-
backgroundColor: "#E5E5E5"
|
|
2927
|
-
},
|
|
2928
|
-
lineLong: {
|
|
2929
|
-
marginBottom: 6,
|
|
2930
|
-
width: "100%",
|
|
2931
|
-
height: 14,
|
|
2932
|
-
borderRadius: 6,
|
|
2933
|
-
backgroundColor: "#E5E5E5"
|
|
3250
|
+
width: "100%"
|
|
2934
3251
|
}
|
|
2935
3252
|
});
|
|
2936
|
-
var SkeletonItem_default = SkeletonItem;
|
|
2937
3253
|
|
|
2938
3254
|
// src/molecules/Integration.tsx
|
|
2939
3255
|
var Integration = ({
|
|
@@ -2943,13 +3259,14 @@ var Integration = ({
|
|
|
2943
3259
|
}) => {
|
|
2944
3260
|
const { appName, linkToken } = useKryptosConnect();
|
|
2945
3261
|
const theme = useTheme();
|
|
2946
|
-
const [addIntegrationMode, setAddIntegrationMode] =
|
|
2947
|
-
const [query, setQuery] =
|
|
2948
|
-
const [
|
|
2949
|
-
const [
|
|
2950
|
-
const [
|
|
2951
|
-
const [
|
|
2952
|
-
const [
|
|
3262
|
+
const [addIntegrationMode, setAddIntegrationMode] = React31.useState(null);
|
|
3263
|
+
const [query, setQuery] = React31.useState("");
|
|
3264
|
+
const [activeTab, setActiveTab] = React31.useState("all");
|
|
3265
|
+
const [supportedProviders, setSupportedProviders] = React31.useState([]);
|
|
3266
|
+
const [addedIntegrations, setAddedIntegrations] = React31.useState([]);
|
|
3267
|
+
const [existingIntegrations, setExistingIntegrations] = React31.useState([]);
|
|
3268
|
+
const [isLoading, setIsLoading] = React31.useState(false);
|
|
3269
|
+
const [errorMessage, setErrorMessage] = React31.useState("");
|
|
2953
3270
|
const handleClose = () => {
|
|
2954
3271
|
onClose();
|
|
2955
3272
|
};
|
|
@@ -2980,13 +3297,13 @@ var Integration = ({
|
|
|
2980
3297
|
setIsLoading(false);
|
|
2981
3298
|
}
|
|
2982
3299
|
};
|
|
2983
|
-
|
|
3300
|
+
React31.useEffect(() => {
|
|
2984
3301
|
if (linkToken) {
|
|
2985
3302
|
fetchSupportedProviders();
|
|
2986
3303
|
fetchExistingIntegrations();
|
|
2987
3304
|
}
|
|
2988
3305
|
}, [linkToken]);
|
|
2989
|
-
const isIntegrationAdded =
|
|
3306
|
+
const isIntegrationAdded = React31.useCallback(
|
|
2990
3307
|
(publicName) => {
|
|
2991
3308
|
const integrations = [...addedIntegrations, ...existingIntegrations];
|
|
2992
3309
|
return integrations.some(
|
|
@@ -2995,7 +3312,7 @@ var Integration = ({
|
|
|
2995
3312
|
},
|
|
2996
3313
|
[addedIntegrations, existingIntegrations]
|
|
2997
3314
|
);
|
|
2998
|
-
const getIntegrationCount =
|
|
3315
|
+
const getIntegrationCount = React31.useCallback(
|
|
2999
3316
|
(publicName) => {
|
|
3000
3317
|
const integrations = [...addedIntegrations, ...existingIntegrations];
|
|
3001
3318
|
return integrations.filter(
|
|
@@ -3004,22 +3321,24 @@ var Integration = ({
|
|
|
3004
3321
|
},
|
|
3005
3322
|
[addedIntegrations, existingIntegrations]
|
|
3006
3323
|
);
|
|
3007
|
-
const filteredResults =
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3324
|
+
const filteredResults = React31.useMemo(() => {
|
|
3325
|
+
let filtered = supportedProviders;
|
|
3326
|
+
if (activeTab !== "all") {
|
|
3327
|
+
filtered = filtered.filter((provider) => provider.type === activeTab);
|
|
3328
|
+
}
|
|
3329
|
+
if (query?.trim()) {
|
|
3330
|
+
const lowerQuery = query.trim().toLowerCase();
|
|
3331
|
+
filtered = filtered.filter((provider) => {
|
|
3332
|
+
return provider.name?.toLowerCase().includes(lowerQuery) || provider.public_name?.toLowerCase().includes(lowerQuery) || provider.id?.toLowerCase().includes(lowerQuery);
|
|
3333
|
+
});
|
|
3013
3334
|
}
|
|
3014
|
-
return [...
|
|
3335
|
+
return [...filtered].sort((a, b) => {
|
|
3015
3336
|
const countA = getIntegrationCount(a.public_name);
|
|
3016
3337
|
const countB = getIntegrationCount(b.public_name);
|
|
3017
|
-
if (countB !== countA)
|
|
3018
|
-
|
|
3019
|
-
}
|
|
3020
|
-
return a.name.localeCompare(b.name);
|
|
3338
|
+
if (countB !== countA) return countB - countA;
|
|
3339
|
+
return (a.name ?? "").localeCompare(b.name ?? "");
|
|
3021
3340
|
});
|
|
3022
|
-
}, [query, supportedProviders, getIntegrationCount]);
|
|
3341
|
+
}, [query, supportedProviders, getIntegrationCount, activeTab]);
|
|
3023
3342
|
const handleAddIntegration = async () => {
|
|
3024
3343
|
try {
|
|
3025
3344
|
setIsLoading(true);
|
|
@@ -3042,11 +3361,11 @@ var Integration = ({
|
|
|
3042
3361
|
setIsLoading(false);
|
|
3043
3362
|
}
|
|
3044
3363
|
};
|
|
3045
|
-
const renderProviderItem = ({ item }) => /* @__PURE__ */
|
|
3046
|
-
|
|
3364
|
+
const renderProviderItem = ({ item }) => /* @__PURE__ */ React31.createElement(
|
|
3365
|
+
TouchableOpacity6,
|
|
3047
3366
|
{
|
|
3048
3367
|
style: [
|
|
3049
|
-
|
|
3368
|
+
styles15.providerItem,
|
|
3050
3369
|
{
|
|
3051
3370
|
backgroundColor: theme.colors.surface,
|
|
3052
3371
|
borderColor: theme.colors.border
|
|
@@ -3055,43 +3374,43 @@ var Integration = ({
|
|
|
3055
3374
|
onPress: () => setAddIntegrationMode(item),
|
|
3056
3375
|
activeOpacity: 0.7
|
|
3057
3376
|
},
|
|
3058
|
-
/* @__PURE__ */
|
|
3377
|
+
/* @__PURE__ */ React31.createElement(View15, { style: styles15.providerInfo }, item?.logo ? /* @__PURE__ */ React31.createElement(
|
|
3059
3378
|
Image3,
|
|
3060
3379
|
{
|
|
3061
3380
|
source: { uri: item?.logo },
|
|
3062
|
-
style:
|
|
3381
|
+
style: styles15.providerLogo,
|
|
3063
3382
|
resizeMode: "contain"
|
|
3064
3383
|
}
|
|
3065
|
-
) : /* @__PURE__ */
|
|
3066
|
-
|
|
3384
|
+
) : /* @__PURE__ */ React31.createElement(
|
|
3385
|
+
View15,
|
|
3067
3386
|
{
|
|
3068
3387
|
style: [
|
|
3069
|
-
|
|
3388
|
+
styles15.providerLogoPlaceholder,
|
|
3070
3389
|
{ backgroundColor: theme.colors.surfaceSecondary }
|
|
3071
3390
|
]
|
|
3072
3391
|
},
|
|
3073
|
-
/* @__PURE__ */
|
|
3074
|
-
), /* @__PURE__ */
|
|
3075
|
-
isIntegrationAdded(item?.public_name) && /* @__PURE__ */
|
|
3076
|
-
|
|
3392
|
+
/* @__PURE__ */ React31.createElement(Text13, { style: { color: theme.colors.text } }, item?.name?.charAt(0) || "?")
|
|
3393
|
+
), /* @__PURE__ */ React31.createElement(Text13, { style: [styles15.providerName, { color: theme.colors.text }] }, item?.name + "\u200B")),
|
|
3394
|
+
isIntegrationAdded(item?.public_name) && /* @__PURE__ */ React31.createElement(View15, { style: styles15.providerStatus }, /* @__PURE__ */ React31.createElement(CheckCircleIcon, { size: 18, color: theme.colors.success }), /* @__PURE__ */ React31.createElement(
|
|
3395
|
+
Text13,
|
|
3077
3396
|
{
|
|
3078
3397
|
style: [
|
|
3079
|
-
|
|
3398
|
+
styles15.providerCount,
|
|
3080
3399
|
{ color: theme.colors.textSecondary }
|
|
3081
3400
|
]
|
|
3082
3401
|
},
|
|
3083
3402
|
getIntegrationCount(item?.public_name)
|
|
3084
3403
|
))
|
|
3085
3404
|
);
|
|
3086
|
-
const renderSkeletonItem = () => /* @__PURE__ */
|
|
3087
|
-
return /* @__PURE__ */
|
|
3088
|
-
|
|
3405
|
+
const renderSkeletonItem = () => /* @__PURE__ */ React31.createElement(SkeletonItem_default, null);
|
|
3406
|
+
return /* @__PURE__ */ React31.createElement(React31.Fragment, null, !addIntegrationMode ? /* @__PURE__ */ React31.createElement(Modal, { isOpen: open, onClose: handleClose, size: "full" }, /* @__PURE__ */ React31.createElement(ModalHeader, { onClose: handleClose }, /* @__PURE__ */ React31.createElement(View15, { style: styles15.headerContent }, addIntegrationMode && /* @__PURE__ */ React31.createElement(
|
|
3407
|
+
TouchableOpacity6,
|
|
3089
3408
|
{
|
|
3090
3409
|
onPress: () => setAddIntegrationMode(null),
|
|
3091
|
-
style:
|
|
3410
|
+
style: styles15.backButton
|
|
3092
3411
|
},
|
|
3093
|
-
/* @__PURE__ */
|
|
3094
|
-
), /* @__PURE__ */
|
|
3412
|
+
/* @__PURE__ */ React31.createElement(ArrowLeftIcon, { size: 20, color: theme.colors.text })
|
|
3413
|
+
), /* @__PURE__ */ React31.createElement(Text13, { style: [styles15.headerTitle, { color: theme.colors.text }] }, "Integration"))), /* @__PURE__ */ React31.createElement(ModalBody, { scrollable: false, style: styles15.noPadding }, /* @__PURE__ */ React31.createElement(View15, { style: styles15.container }, /* @__PURE__ */ React31.createElement(View15, { style: styles15.headerSection }, /* @__PURE__ */ React31.createElement(ConnectLogo, null), /* @__PURE__ */ React31.createElement(Text13, { style: [styles15.title, { color: theme.colors.text }] }, "Select an account to link to ", appName)), /* @__PURE__ */ React31.createElement(
|
|
3095
3414
|
FlatList,
|
|
3096
3415
|
{
|
|
3097
3416
|
data: isLoading ? Array.from({ length: 8 }, (_, i) => ({
|
|
@@ -3102,14 +3421,14 @@ var Integration = ({
|
|
|
3102
3421
|
})) : filteredResults,
|
|
3103
3422
|
keyExtractor: (item, index) => isLoading ? item.id : `provider-${item.id}-${index}`,
|
|
3104
3423
|
renderItem: isLoading ? renderSkeletonItem : renderProviderItem,
|
|
3105
|
-
style:
|
|
3424
|
+
style: styles15.list,
|
|
3106
3425
|
contentContainerStyle: [
|
|
3107
|
-
|
|
3426
|
+
styles15.listContent,
|
|
3108
3427
|
{ paddingHorizontal: theme.spacing.xl }
|
|
3109
3428
|
],
|
|
3110
3429
|
showsVerticalScrollIndicator: false,
|
|
3111
|
-
ListHeaderComponent: /* @__PURE__ */
|
|
3112
|
-
|
|
3430
|
+
ListHeaderComponent: /* @__PURE__ */ React31.createElement(
|
|
3431
|
+
View15,
|
|
3113
3432
|
{
|
|
3114
3433
|
style: {
|
|
3115
3434
|
paddingVertical: theme.spacing.sm + 2,
|
|
@@ -3117,29 +3436,63 @@ var Integration = ({
|
|
|
3117
3436
|
zIndex: 10
|
|
3118
3437
|
}
|
|
3119
3438
|
},
|
|
3120
|
-
/* @__PURE__ */
|
|
3439
|
+
/* @__PURE__ */ React31.createElement(
|
|
3121
3440
|
Input,
|
|
3122
3441
|
{
|
|
3123
3442
|
value: query,
|
|
3124
3443
|
onChangeText: setQuery,
|
|
3125
3444
|
placeholder: "Search Integrations...",
|
|
3126
|
-
containerStyle:
|
|
3445
|
+
containerStyle: styles15.searchInput
|
|
3127
3446
|
}
|
|
3128
|
-
)
|
|
3447
|
+
),
|
|
3448
|
+
/* @__PURE__ */ React31.createElement(View15, { style: styles15.tabsContainer }, [
|
|
3449
|
+
{ label: "All", value: "all" },
|
|
3450
|
+
{ label: "Exchanges", value: "exchange" },
|
|
3451
|
+
{ label: "Blockchains", value: "blockchain" },
|
|
3452
|
+
{ label: "Wallets", value: "wallet" }
|
|
3453
|
+
].map((tab) => /* @__PURE__ */ React31.createElement(
|
|
3454
|
+
TouchableOpacity6,
|
|
3455
|
+
{
|
|
3456
|
+
key: tab.value,
|
|
3457
|
+
style: [
|
|
3458
|
+
styles15.tab,
|
|
3459
|
+
{
|
|
3460
|
+
backgroundColor: activeTab === tab.value ? theme.colors.primary : theme.colors.surface,
|
|
3461
|
+
borderColor: theme.colors.border
|
|
3462
|
+
}
|
|
3463
|
+
],
|
|
3464
|
+
onPress: () => setActiveTab(
|
|
3465
|
+
tab.value
|
|
3466
|
+
),
|
|
3467
|
+
activeOpacity: 0.7
|
|
3468
|
+
},
|
|
3469
|
+
/* @__PURE__ */ React31.createElement(
|
|
3470
|
+
Text13,
|
|
3471
|
+
{
|
|
3472
|
+
style: [
|
|
3473
|
+
styles15.tabText,
|
|
3474
|
+
{
|
|
3475
|
+
color: activeTab === tab.value ? theme.colors.white : theme.colors.text
|
|
3476
|
+
}
|
|
3477
|
+
]
|
|
3478
|
+
},
|
|
3479
|
+
tab.label
|
|
3480
|
+
)
|
|
3481
|
+
)))
|
|
3129
3482
|
),
|
|
3130
3483
|
stickyHeaderIndices: [0],
|
|
3131
|
-
ListEmptyComponent: /* @__PURE__ */
|
|
3132
|
-
|
|
3484
|
+
ListEmptyComponent: /* @__PURE__ */ React31.createElement(View15, { style: styles15.emptyContainer }, !isLoading && /* @__PURE__ */ React31.createElement(
|
|
3485
|
+
Text13,
|
|
3133
3486
|
{
|
|
3134
3487
|
style: [
|
|
3135
|
-
|
|
3488
|
+
styles15.emptyText,
|
|
3136
3489
|
{ color: theme.colors.textSecondary }
|
|
3137
3490
|
]
|
|
3138
3491
|
},
|
|
3139
3492
|
query ? "No search results found" : "No supported integrations found"
|
|
3140
3493
|
))
|
|
3141
3494
|
}
|
|
3142
|
-
), errorMessage && /* @__PURE__ */
|
|
3495
|
+
), errorMessage && /* @__PURE__ */ React31.createElement(View15, { style: styles15.errorContainer }, /* @__PURE__ */ React31.createElement(Alert, { variant: "destructive", style: styles15.errorAlert }, /* @__PURE__ */ React31.createElement(AlertDescription, null, errorMessage))))), /* @__PURE__ */ React31.createElement(ModalFooter, { style: { paddingVertical: 8 } }, /* @__PURE__ */ React31.createElement(
|
|
3143
3496
|
Button,
|
|
3144
3497
|
{
|
|
3145
3498
|
variant: "outline",
|
|
@@ -3147,10 +3500,10 @@ var Integration = ({
|
|
|
3147
3500
|
onPress: handleAddIntegration,
|
|
3148
3501
|
loading: isLoading,
|
|
3149
3502
|
disabled: isLoading,
|
|
3150
|
-
style:
|
|
3503
|
+
style: styles15.continueButton
|
|
3151
3504
|
},
|
|
3152
3505
|
"Continue"
|
|
3153
|
-
))) : /* @__PURE__ */
|
|
3506
|
+
), /* @__PURE__ */ React31.createElement(Footer, null))) : /* @__PURE__ */ React31.createElement(
|
|
3154
3507
|
IntegrationForm,
|
|
3155
3508
|
{
|
|
3156
3509
|
metadata: addIntegrationMode,
|
|
@@ -3160,11 +3513,12 @@ var Integration = ({
|
|
|
3160
3513
|
},
|
|
3161
3514
|
open: !!addIntegrationMode,
|
|
3162
3515
|
setAddIntegrationMode,
|
|
3163
|
-
handleClose
|
|
3516
|
+
handleClose,
|
|
3517
|
+
providersList: supportedProviders
|
|
3164
3518
|
}
|
|
3165
3519
|
));
|
|
3166
3520
|
};
|
|
3167
|
-
var
|
|
3521
|
+
var styles15 = StyleSheet15.create({
|
|
3168
3522
|
headerContent: {
|
|
3169
3523
|
flexDirection: "row",
|
|
3170
3524
|
alignItems: "center"
|
|
@@ -3279,25 +3633,47 @@ var styles12 = StyleSheet12.create({
|
|
|
3279
3633
|
errorAlert: {
|
|
3280
3634
|
marginTop: 16
|
|
3281
3635
|
// theme.spacing.lg - consistent alert spacing
|
|
3636
|
+
},
|
|
3637
|
+
tabsContainer: {
|
|
3638
|
+
flexDirection: "row",
|
|
3639
|
+
gap: 4,
|
|
3640
|
+
// theme.spacing.sm
|
|
3641
|
+
flexWrap: "wrap"
|
|
3642
|
+
},
|
|
3643
|
+
tab: {
|
|
3644
|
+
paddingVertical: 8,
|
|
3645
|
+
// theme.spacing.sm
|
|
3646
|
+
paddingHorizontal: 16,
|
|
3647
|
+
// theme.spacing.lg
|
|
3648
|
+
borderRadius: 20,
|
|
3649
|
+
// theme.borderRadius.full / 2
|
|
3650
|
+
borderWidth: 1,
|
|
3651
|
+
alignItems: "center",
|
|
3652
|
+
justifyContent: "center"
|
|
3653
|
+
},
|
|
3654
|
+
tabText: {
|
|
3655
|
+
fontSize: 13,
|
|
3656
|
+
// theme.fontSize.sm
|
|
3657
|
+
fontWeight: "600"
|
|
3282
3658
|
}
|
|
3283
3659
|
});
|
|
3284
3660
|
|
|
3285
3661
|
// src/molecules/OTPVerify.tsx
|
|
3286
|
-
import
|
|
3287
|
-
import { StyleSheet as
|
|
3662
|
+
import React32 from "react";
|
|
3663
|
+
import { StyleSheet as StyleSheet16, Text as Text14, TouchableOpacity as TouchableOpacity7, View as View16 } from "react-native";
|
|
3288
3664
|
var OTPVerify = ({
|
|
3289
3665
|
open,
|
|
3290
3666
|
onSuccess,
|
|
3291
3667
|
onClose
|
|
3292
3668
|
}) => {
|
|
3293
3669
|
const theme = useTheme();
|
|
3294
|
-
const [otp, setOtp] =
|
|
3670
|
+
const [otp, setOtp] = React32.useState("");
|
|
3295
3671
|
const { linkToken, clientId, email, setUser } = useKryptosConnect();
|
|
3296
|
-
const [isLoading, setIsLoading] =
|
|
3297
|
-
const [isResending, setIsResending] =
|
|
3298
|
-
const [resendCooldown, setResendCooldown] =
|
|
3299
|
-
const [errorMessage, setErrorMessage] =
|
|
3300
|
-
const [successMessage, setSuccessMessage] =
|
|
3672
|
+
const [isLoading, setIsLoading] = React32.useState(false);
|
|
3673
|
+
const [isResending, setIsResending] = React32.useState(false);
|
|
3674
|
+
const [resendCooldown, setResendCooldown] = React32.useState(0);
|
|
3675
|
+
const [errorMessage, setErrorMessage] = React32.useState("");
|
|
3676
|
+
const [successMessage, setSuccessMessage] = React32.useState("");
|
|
3301
3677
|
const handleSubmit = async () => {
|
|
3302
3678
|
if (otp.length !== 6) return;
|
|
3303
3679
|
setIsLoading(true);
|
|
@@ -3348,7 +3724,7 @@ var OTPVerify = ({
|
|
|
3348
3724
|
setSuccessMessage("");
|
|
3349
3725
|
setOtp("");
|
|
3350
3726
|
};
|
|
3351
|
-
|
|
3727
|
+
React32.useEffect(() => {
|
|
3352
3728
|
if (resendCooldown > 0) {
|
|
3353
3729
|
const timer = setTimeout(() => {
|
|
3354
3730
|
setResendCooldown(resendCooldown - 1);
|
|
@@ -3357,13 +3733,20 @@ var OTPVerify = ({
|
|
|
3357
3733
|
}
|
|
3358
3734
|
return void 0;
|
|
3359
3735
|
}, [resendCooldown]);
|
|
3360
|
-
return /* @__PURE__ */
|
|
3361
|
-
|
|
3736
|
+
return /* @__PURE__ */ React32.createElement(Modal, { isOpen: open, onClose: handleClose, size: "lg" }, /* @__PURE__ */ React32.createElement(ModalHeader, { onClose: handleClose }, /* @__PURE__ */ React32.createElement(View16, { style: styles16.headerContent }, /* @__PURE__ */ React32.createElement(Text14, { style: [styles16.headerTitle, { color: theme.colors.text }] }, "OTP Verification"))), /* @__PURE__ */ React32.createElement(ModalBody, null, /* @__PURE__ */ React32.createElement(View16, { style: styles16.container }, /* @__PURE__ */ React32.createElement(ConnectLogo, null), /* @__PURE__ */ React32.createElement(View16, { style: styles16.emailInfo }, /* @__PURE__ */ React32.createElement(
|
|
3737
|
+
Text14,
|
|
3362
3738
|
{
|
|
3363
|
-
style: [
|
|
3739
|
+
style: [styles16.infoText, { color: theme.colors.textSecondary }]
|
|
3364
3740
|
},
|
|
3365
3741
|
"We have sent a verification code to"
|
|
3366
|
-
), /* @__PURE__ */
|
|
3742
|
+
), /* @__PURE__ */ React32.createElement(Text14, { style: [styles16.emailText, { color: theme.colors.text }] }, email)), /* @__PURE__ */ React32.createElement(
|
|
3743
|
+
OTP,
|
|
3744
|
+
{
|
|
3745
|
+
onComplete: handleOtpComplete,
|
|
3746
|
+
length: 6,
|
|
3747
|
+
setErrorMessage
|
|
3748
|
+
}
|
|
3749
|
+
), errorMessage ? /* @__PURE__ */ React32.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React32.createElement(AlertDescription, null, errorMessage)) : null, successMessage ? /* @__PURE__ */ React32.createElement(Alert, { variant: "default" }, /* @__PURE__ */ React32.createElement(AlertDescription, null, successMessage)) : null, /* @__PURE__ */ React32.createElement(
|
|
3367
3750
|
Button,
|
|
3368
3751
|
{
|
|
3369
3752
|
variant: "outline",
|
|
@@ -3371,44 +3754,44 @@ var OTPVerify = ({
|
|
|
3371
3754
|
onPress: handleSubmit,
|
|
3372
3755
|
loading: isLoading,
|
|
3373
3756
|
disabled: otp.length !== 6 || isLoading,
|
|
3374
|
-
style:
|
|
3757
|
+
style: styles16.button
|
|
3375
3758
|
},
|
|
3376
3759
|
"Continue"
|
|
3377
|
-
), /* @__PURE__ */
|
|
3378
|
-
|
|
3760
|
+
), /* @__PURE__ */ React32.createElement(
|
|
3761
|
+
TouchableOpacity7,
|
|
3379
3762
|
{
|
|
3380
3763
|
onPress: handleResendOtp,
|
|
3381
3764
|
disabled: resendCooldown > 0 || isResending,
|
|
3382
|
-
style:
|
|
3765
|
+
style: styles16.resendContainer
|
|
3383
3766
|
},
|
|
3384
|
-
isResending ? /* @__PURE__ */
|
|
3385
|
-
|
|
3767
|
+
isResending ? /* @__PURE__ */ React32.createElement(View16, { style: styles16.resendLoading }, /* @__PURE__ */ React32.createElement(LoaderIcon, { size: 16, color: theme.colors.primary }), /* @__PURE__ */ React32.createElement(
|
|
3768
|
+
Text14,
|
|
3386
3769
|
{
|
|
3387
|
-
style: [
|
|
3770
|
+
style: [styles16.resendText, { color: theme.colors.primary }]
|
|
3388
3771
|
},
|
|
3389
3772
|
" ",
|
|
3390
3773
|
"Sending..."
|
|
3391
|
-
)) : resendCooldown > 0 ? /* @__PURE__ */
|
|
3392
|
-
|
|
3774
|
+
)) : resendCooldown > 0 ? /* @__PURE__ */ React32.createElement(
|
|
3775
|
+
Text14,
|
|
3393
3776
|
{
|
|
3394
3777
|
style: [
|
|
3395
|
-
|
|
3778
|
+
styles16.resendText,
|
|
3396
3779
|
{ color: theme.colors.textSecondary }
|
|
3397
3780
|
]
|
|
3398
3781
|
},
|
|
3399
3782
|
"Resend OTP in ",
|
|
3400
3783
|
resendCooldown,
|
|
3401
3784
|
"s"
|
|
3402
|
-
) : /* @__PURE__ */
|
|
3403
|
-
|
|
3785
|
+
) : /* @__PURE__ */ React32.createElement(
|
|
3786
|
+
Text14,
|
|
3404
3787
|
{
|
|
3405
|
-
style: [
|
|
3788
|
+
style: [styles16.resendText, { color: theme.colors.primary }]
|
|
3406
3789
|
},
|
|
3407
3790
|
"Resend OTP"
|
|
3408
3791
|
)
|
|
3409
|
-
))));
|
|
3792
|
+
))), /* @__PURE__ */ React32.createElement(ModalFooter, { style: { paddingVertical: 0 } }, /* @__PURE__ */ React32.createElement(Footer, null)));
|
|
3410
3793
|
};
|
|
3411
|
-
var
|
|
3794
|
+
var styles16 = StyleSheet16.create({
|
|
3412
3795
|
headerContent: {
|
|
3413
3796
|
flexDirection: "row",
|
|
3414
3797
|
alignItems: "center"
|
|
@@ -3467,8 +3850,8 @@ var styles13 = StyleSheet13.create({
|
|
|
3467
3850
|
});
|
|
3468
3851
|
|
|
3469
3852
|
// src/molecules/Permissions.tsx
|
|
3470
|
-
import
|
|
3471
|
-
import {
|
|
3853
|
+
import React33 from "react";
|
|
3854
|
+
import { StyleSheet as StyleSheet17, Text as Text15, View as View17 } from "react-native";
|
|
3472
3855
|
var Permissions = ({
|
|
3473
3856
|
open,
|
|
3474
3857
|
onClose,
|
|
@@ -3476,8 +3859,8 @@ var Permissions = ({
|
|
|
3476
3859
|
}) => {
|
|
3477
3860
|
const { appName, linkToken, setUserConsent } = useKryptosConnect();
|
|
3478
3861
|
const theme = useTheme();
|
|
3479
|
-
const [isLoading, setIsLoading] =
|
|
3480
|
-
const [errorMessage, setErrorMessage] =
|
|
3862
|
+
const [isLoading, setIsLoading] = React33.useState(false);
|
|
3863
|
+
const [errorMessage, setErrorMessage] = React33.useState("");
|
|
3481
3864
|
const handleConsentClick = async () => {
|
|
3482
3865
|
try {
|
|
3483
3866
|
setIsLoading(true);
|
|
@@ -3500,42 +3883,42 @@ var Permissions = ({
|
|
|
3500
3883
|
"Access your transaction history and trading activity",
|
|
3501
3884
|
"Keep this data updated and accessible when you're offline"
|
|
3502
3885
|
];
|
|
3503
|
-
return /* @__PURE__ */
|
|
3504
|
-
|
|
3886
|
+
return /* @__PURE__ */ React33.createElement(Modal, { isOpen: open, onClose, size: "xl" }, /* @__PURE__ */ React33.createElement(ModalHeader, { onClose }, "Permissions"), /* @__PURE__ */ React33.createElement(ModalBody, null, /* @__PURE__ */ React33.createElement(View17, { style: styles17.container }, /* @__PURE__ */ React33.createElement(ConnectLogo, null), errorMessage ? /* @__PURE__ */ React33.createElement(Alert, { variant: "destructive" }, /* @__PURE__ */ React33.createElement(AlertDescription, null, errorMessage)) : null, /* @__PURE__ */ React33.createElement(View17, { style: styles17.permissionsList }, /* @__PURE__ */ React33.createElement(
|
|
3887
|
+
Text15,
|
|
3505
3888
|
{
|
|
3506
|
-
style: [
|
|
3889
|
+
style: [styles17.subtitle, { color: theme.colors.textSecondary }]
|
|
3507
3890
|
},
|
|
3508
3891
|
"Allow ",
|
|
3509
3892
|
appName,
|
|
3510
3893
|
" to:"
|
|
3511
|
-
), permissionItems.map((item, index) => /* @__PURE__ */
|
|
3512
|
-
|
|
3894
|
+
), permissionItems.map((item, index) => /* @__PURE__ */ React33.createElement(View17, { key: `permission-${index}`, style: styles17.permissionItem }, /* @__PURE__ */ React33.createElement(Text15, { style: [styles17.bullet, { color: theme.colors.primary }] }, index + 1, "."), /* @__PURE__ */ React33.createElement(
|
|
3895
|
+
Text15,
|
|
3513
3896
|
{
|
|
3514
|
-
style: [
|
|
3897
|
+
style: [styles17.permissionText, { color: theme.colors.text }]
|
|
3515
3898
|
},
|
|
3516
3899
|
item
|
|
3517
|
-
)))), /* @__PURE__ */
|
|
3518
|
-
|
|
3900
|
+
)))), /* @__PURE__ */ React33.createElement(
|
|
3901
|
+
View17,
|
|
3519
3902
|
{
|
|
3520
3903
|
style: [
|
|
3521
|
-
|
|
3904
|
+
styles17.infoBox,
|
|
3522
3905
|
{
|
|
3523
3906
|
backgroundColor: theme.colors.surface,
|
|
3524
3907
|
borderColor: theme.colors.border
|
|
3525
3908
|
}
|
|
3526
3909
|
]
|
|
3527
3910
|
},
|
|
3528
|
-
/* @__PURE__ */
|
|
3529
|
-
|
|
3911
|
+
/* @__PURE__ */ React33.createElement(
|
|
3912
|
+
Text15,
|
|
3530
3913
|
{
|
|
3531
|
-
style: [
|
|
3914
|
+
style: [styles17.infoText, { color: theme.colors.textSecondary }]
|
|
3532
3915
|
},
|
|
3533
3916
|
"By selecting",
|
|
3534
3917
|
" ",
|
|
3535
|
-
/* @__PURE__ */
|
|
3918
|
+
/* @__PURE__ */ React33.createElement(Text15, { style: { fontWeight: "600", color: theme.colors.text } }, "'Allow'"),
|
|
3536
3919
|
", you agree to share this information and keep it updated."
|
|
3537
3920
|
)
|
|
3538
|
-
))), /* @__PURE__ */
|
|
3921
|
+
))), /* @__PURE__ */ React33.createElement(ModalFooter, { style: { paddingVertical: 8 } }, /* @__PURE__ */ React33.createElement(
|
|
3539
3922
|
Button,
|
|
3540
3923
|
{
|
|
3541
3924
|
variant: "outline",
|
|
@@ -3543,12 +3926,12 @@ var Permissions = ({
|
|
|
3543
3926
|
onPress: handleConsentClick,
|
|
3544
3927
|
loading: isLoading,
|
|
3545
3928
|
disabled: isLoading,
|
|
3546
|
-
style:
|
|
3929
|
+
style: styles17.button
|
|
3547
3930
|
},
|
|
3548
3931
|
"Allow"
|
|
3549
|
-
)));
|
|
3932
|
+
), /* @__PURE__ */ React33.createElement(Footer, null)));
|
|
3550
3933
|
};
|
|
3551
|
-
var
|
|
3934
|
+
var styles17 = StyleSheet17.create({
|
|
3552
3935
|
container: {
|
|
3553
3936
|
flex: 1
|
|
3554
3937
|
},
|
|
@@ -3606,8 +3989,8 @@ var styles14 = StyleSheet14.create({
|
|
|
3606
3989
|
});
|
|
3607
3990
|
|
|
3608
3991
|
// src/molecules/StatusModal.tsx
|
|
3609
|
-
import
|
|
3610
|
-
import {
|
|
3992
|
+
import React34 from "react";
|
|
3993
|
+
import { StyleSheet as StyleSheet18, Text as Text16, View as View18 } from "react-native";
|
|
3611
3994
|
var StatusModal = ({
|
|
3612
3995
|
open,
|
|
3613
3996
|
onClose,
|
|
@@ -3624,18 +4007,18 @@ var StatusModal = ({
|
|
|
3624
4007
|
}
|
|
3625
4008
|
onClose();
|
|
3626
4009
|
};
|
|
3627
|
-
return /* @__PURE__ */
|
|
4010
|
+
return /* @__PURE__ */ React34.createElement(Modal, { isOpen: open, onClose: handleClose, size: "sm" }, /* @__PURE__ */ React34.createElement(ModalHeader, { showCloseButton: false, onClose: handleClose }, ""), /* @__PURE__ */ React34.createElement(ModalBody, null, /* @__PURE__ */ React34.createElement(View18, { style: styles18.container }, /* @__PURE__ */ React34.createElement(View18, { style: styles18.iconContainer }, status === "success" ? /* @__PURE__ */ React34.createElement(SuccessIcon, { size: 80 }) : /* @__PURE__ */ React34.createElement(ErrorIcon, { size: 80 })), /* @__PURE__ */ React34.createElement(Text16, { style: [styles18.message, { color: theme.colors.text }] }, status === "success" ? "Connection successful" : "Connection failed"))), /* @__PURE__ */ React34.createElement(ModalFooter, { style: { paddingVertical: 8 } }, /* @__PURE__ */ React34.createElement(
|
|
3628
4011
|
Button,
|
|
3629
4012
|
{
|
|
3630
4013
|
variant: "outline",
|
|
3631
4014
|
size: "lg",
|
|
3632
4015
|
onPress: status === "success" ? onSuccess : onError,
|
|
3633
|
-
style:
|
|
4016
|
+
style: styles18.button
|
|
3634
4017
|
},
|
|
3635
4018
|
status === "success" ? "Continue" : "Try again later"
|
|
3636
|
-
))));
|
|
4019
|
+
), /* @__PURE__ */ React34.createElement(Footer, null)));
|
|
3637
4020
|
};
|
|
3638
|
-
var
|
|
4021
|
+
var styles18 = StyleSheet18.create({
|
|
3639
4022
|
container: {
|
|
3640
4023
|
flex: 1,
|
|
3641
4024
|
alignItems: "center",
|
|
@@ -3659,6 +4042,64 @@ var styles15 = StyleSheet15.create({
|
|
|
3659
4042
|
}
|
|
3660
4043
|
});
|
|
3661
4044
|
|
|
4045
|
+
// src/molecules/EndModal.tsx
|
|
4046
|
+
import React35, { useEffect as useEffect3 } from "react";
|
|
4047
|
+
import { StyleSheet as StyleSheet19, Text as Text17, View as View19 } from "react-native";
|
|
4048
|
+
var EndModal = ({ open, onClose }) => {
|
|
4049
|
+
const theme = useTheme();
|
|
4050
|
+
useEffect3(() => {
|
|
4051
|
+
if (!open) return;
|
|
4052
|
+
const timer = setTimeout(() => {
|
|
4053
|
+
onClose();
|
|
4054
|
+
}, 5e3);
|
|
4055
|
+
return () => clearTimeout(timer);
|
|
4056
|
+
}, []);
|
|
4057
|
+
return /* @__PURE__ */ React35.createElement(Modal, { isOpen: open, onClose, size: "md" }, /* @__PURE__ */ React35.createElement(ModalHeader, { onClose }, ""), /* @__PURE__ */ React35.createElement(ModalBody, null, /* @__PURE__ */ React35.createElement(View19, { style: styles19.container }, /* @__PURE__ */ React35.createElement(
|
|
4058
|
+
View19,
|
|
4059
|
+
{
|
|
4060
|
+
style: [
|
|
4061
|
+
styles19.iconContainer,
|
|
4062
|
+
{ backgroundColor: theme.colors.successLight }
|
|
4063
|
+
]
|
|
4064
|
+
},
|
|
4065
|
+
/* @__PURE__ */ React35.createElement(SuccessIcon, { size: 80 })
|
|
4066
|
+
), /* @__PURE__ */ React35.createElement(Text17, { style: [styles19.message, { color: theme.colors.text }] }, `All set! We're redirecting you back to the app. If it takes longer
|
|
4067
|
+
than expected, tap the button below to continue.`))), /* @__PURE__ */ React35.createElement(ModalFooter, { style: { paddingVertical: 8 } }, /* @__PURE__ */ React35.createElement(
|
|
4068
|
+
Button,
|
|
4069
|
+
{
|
|
4070
|
+
variant: "primary",
|
|
4071
|
+
size: "lg",
|
|
4072
|
+
onPress: onClose,
|
|
4073
|
+
style: styles19.button
|
|
4074
|
+
},
|
|
4075
|
+
"Continue to App"
|
|
4076
|
+
), /* @__PURE__ */ React35.createElement(Footer, null)));
|
|
4077
|
+
};
|
|
4078
|
+
var styles19 = StyleSheet19.create({
|
|
4079
|
+
container: {
|
|
4080
|
+
alignItems: "center",
|
|
4081
|
+
paddingVertical: 20
|
|
4082
|
+
},
|
|
4083
|
+
iconContainer: {
|
|
4084
|
+
width: 80,
|
|
4085
|
+
height: 80,
|
|
4086
|
+
borderRadius: 40,
|
|
4087
|
+
alignItems: "center",
|
|
4088
|
+
justifyContent: "center",
|
|
4089
|
+
marginBottom: 20
|
|
4090
|
+
},
|
|
4091
|
+
message: {
|
|
4092
|
+
fontSize: 14,
|
|
4093
|
+
textAlign: "center",
|
|
4094
|
+
lineHeight: 20,
|
|
4095
|
+
marginBottom: 24,
|
|
4096
|
+
paddingHorizontal: 20
|
|
4097
|
+
},
|
|
4098
|
+
button: {
|
|
4099
|
+
width: "100%"
|
|
4100
|
+
}
|
|
4101
|
+
});
|
|
4102
|
+
|
|
3662
4103
|
// src/KryptosConnectButton.tsx
|
|
3663
4104
|
var KryptosConnectButton = ({
|
|
3664
4105
|
children,
|
|
@@ -3669,14 +4110,14 @@ var KryptosConnectButton = ({
|
|
|
3669
4110
|
textStyle
|
|
3670
4111
|
}) => {
|
|
3671
4112
|
const { theme: themeName } = useKryptosConnect();
|
|
3672
|
-
const [open, setOpen] =
|
|
4113
|
+
const [open, setOpen] = React36.useState(false);
|
|
3673
4114
|
const theme = useTheme();
|
|
3674
|
-
return /* @__PURE__ */
|
|
3675
|
-
|
|
4115
|
+
return /* @__PURE__ */ React36.createElement(React36.Fragment, null, children ? /* @__PURE__ */ React36.createElement(TouchableOpacity8, { onPress: () => setOpen(true), style }, children) : /* @__PURE__ */ React36.createElement(
|
|
4116
|
+
TouchableOpacity8,
|
|
3676
4117
|
{
|
|
3677
4118
|
onPress: () => setOpen(true),
|
|
3678
4119
|
style: [
|
|
3679
|
-
|
|
4120
|
+
styles20.defaultButton,
|
|
3680
4121
|
themeName === "light" ? {
|
|
3681
4122
|
backgroundColor: theme.colors.white,
|
|
3682
4123
|
borderRadius: theme.borderRadius.md,
|
|
@@ -3690,11 +4131,11 @@ var KryptosConnectButton = ({
|
|
|
3690
4131
|
],
|
|
3691
4132
|
activeOpacity: 0.8
|
|
3692
4133
|
},
|
|
3693
|
-
/* @__PURE__ */
|
|
3694
|
-
|
|
4134
|
+
/* @__PURE__ */ React36.createElement(
|
|
4135
|
+
Text18,
|
|
3695
4136
|
{
|
|
3696
4137
|
style: [
|
|
3697
|
-
|
|
4138
|
+
styles20.buttonText,
|
|
3698
4139
|
{
|
|
3699
4140
|
color: themeName === "light" ? theme.colors.primary : theme.colors.white,
|
|
3700
4141
|
fontSize: theme.fontSize.lg
|
|
@@ -3705,8 +4146,8 @@ var KryptosConnectButton = ({
|
|
|
3705
4146
|
"Connect with",
|
|
3706
4147
|
" "
|
|
3707
4148
|
),
|
|
3708
|
-
/* @__PURE__ */
|
|
3709
|
-
), /* @__PURE__ */
|
|
4149
|
+
/* @__PURE__ */ React36.createElement(LogoIcon, { size: 24 })
|
|
4150
|
+
), /* @__PURE__ */ React36.createElement(
|
|
3710
4151
|
KryptosConnectModal,
|
|
3711
4152
|
{
|
|
3712
4153
|
open,
|
|
@@ -3730,9 +4171,11 @@ var KryptosConnectModal = ({
|
|
|
3730
4171
|
setUserConsent,
|
|
3731
4172
|
setUser,
|
|
3732
4173
|
setEmail,
|
|
3733
|
-
setLinkToken
|
|
4174
|
+
setLinkToken,
|
|
4175
|
+
isAuthorized,
|
|
4176
|
+
linkToken
|
|
3734
4177
|
} = useKryptosConnect();
|
|
3735
|
-
const [step, setStep] =
|
|
4178
|
+
const [step, setStep] = React36.useState("INIT" /* INIT */);
|
|
3736
4179
|
const handleClose = () => {
|
|
3737
4180
|
setOpen(false);
|
|
3738
4181
|
setIsInitialized(false);
|
|
@@ -3750,12 +4193,25 @@ var KryptosConnectModal = ({
|
|
|
3750
4193
|
onError?.(userConsent);
|
|
3751
4194
|
handleClose();
|
|
3752
4195
|
};
|
|
4196
|
+
const handleConsentClick = async () => {
|
|
4197
|
+
try {
|
|
4198
|
+
if (isAuthorized) {
|
|
4199
|
+
setStep("END" /* END */);
|
|
4200
|
+
return;
|
|
4201
|
+
}
|
|
4202
|
+
const res = await giveUserConsent(linkToken);
|
|
4203
|
+
setUserConsent(res);
|
|
4204
|
+
setStep("STATUS" /* STATUS */);
|
|
4205
|
+
} catch (error) {
|
|
4206
|
+
console.error(error);
|
|
4207
|
+
}
|
|
4208
|
+
};
|
|
3753
4209
|
const handleAbort = () => {
|
|
3754
4210
|
onError?.(new Error("User closed the modal"));
|
|
3755
4211
|
handleClose();
|
|
3756
4212
|
};
|
|
3757
4213
|
if (!open) return null;
|
|
3758
|
-
return /* @__PURE__ */
|
|
4214
|
+
return /* @__PURE__ */ React36.createElement(View20, { style: styles20.container }, step === "INIT" /* INIT */ && /* @__PURE__ */ React36.createElement(
|
|
3759
4215
|
Init,
|
|
3760
4216
|
{
|
|
3761
4217
|
open,
|
|
@@ -3769,7 +4225,7 @@ var KryptosConnectModal = ({
|
|
|
3769
4225
|
},
|
|
3770
4226
|
onClose: handleAbort
|
|
3771
4227
|
}
|
|
3772
|
-
), step === "AUTH" /* AUTH */ && /* @__PURE__ */
|
|
4228
|
+
), step === "AUTH" /* AUTH */ && /* @__PURE__ */ React36.createElement(
|
|
3773
4229
|
Auth,
|
|
3774
4230
|
{
|
|
3775
4231
|
open,
|
|
@@ -3777,28 +4233,28 @@ var KryptosConnectModal = ({
|
|
|
3777
4233
|
onGuestSuccess: () => setStep("INTEGRATION" /* INTEGRATION */),
|
|
3778
4234
|
onClose: handleAbort
|
|
3779
4235
|
}
|
|
3780
|
-
), step === "OTP" /* OTP */ && /* @__PURE__ */
|
|
4236
|
+
), step === "OTP" /* OTP */ && /* @__PURE__ */ React36.createElement(
|
|
3781
4237
|
OTPVerify,
|
|
3782
4238
|
{
|
|
3783
4239
|
open,
|
|
3784
4240
|
onSuccess: () => setStep("INTEGRATION" /* INTEGRATION */),
|
|
3785
4241
|
onClose: handleAbort
|
|
3786
4242
|
}
|
|
3787
|
-
), step === "INTEGRATION" /* INTEGRATION */ && /* @__PURE__ */
|
|
4243
|
+
), step === "INTEGRATION" /* INTEGRATION */ && /* @__PURE__ */ React36.createElement(
|
|
3788
4244
|
Integration,
|
|
3789
4245
|
{
|
|
3790
4246
|
open,
|
|
3791
|
-
onSuccess:
|
|
4247
|
+
onSuccess: handleConsentClick,
|
|
3792
4248
|
onClose: handleAbort
|
|
3793
4249
|
}
|
|
3794
|
-
), step === "PERMISSIONS" /* PERMISSIONS */ && /* @__PURE__ */
|
|
4250
|
+
), step === "PERMISSIONS" /* PERMISSIONS */ && /* @__PURE__ */ React36.createElement(
|
|
3795
4251
|
Permissions,
|
|
3796
4252
|
{
|
|
3797
4253
|
open,
|
|
3798
4254
|
onClose: handleAbort,
|
|
3799
4255
|
onSuccess: () => setStep("STATUS" /* STATUS */)
|
|
3800
4256
|
}
|
|
3801
|
-
), step === "STATUS" /* STATUS */ && /* @__PURE__ */
|
|
4257
|
+
), step === "STATUS" /* STATUS */ && /* @__PURE__ */ React36.createElement(
|
|
3802
4258
|
StatusModal,
|
|
3803
4259
|
{
|
|
3804
4260
|
open,
|
|
@@ -3807,9 +4263,19 @@ var KryptosConnectModal = ({
|
|
|
3807
4263
|
onError: handleError,
|
|
3808
4264
|
status: userConsent?.public_token ? "success" : "error"
|
|
3809
4265
|
}
|
|
4266
|
+
), step === "END" /* END */ && /* @__PURE__ */ React36.createElement(
|
|
4267
|
+
EndModal,
|
|
4268
|
+
{
|
|
4269
|
+
open,
|
|
4270
|
+
onClose: () => {
|
|
4271
|
+
onSuccess?.(userConsent);
|
|
4272
|
+
setStep("INIT" /* INIT */);
|
|
4273
|
+
setOpen(false);
|
|
4274
|
+
}
|
|
4275
|
+
}
|
|
3810
4276
|
));
|
|
3811
4277
|
};
|
|
3812
|
-
var
|
|
4278
|
+
var styles20 = StyleSheet20.create({
|
|
3813
4279
|
defaultButton: {
|
|
3814
4280
|
flexDirection: "row",
|
|
3815
4281
|
alignItems: "center",
|