@gluwa/connect-kit 0.2.0-next.8 → 0.2.0-next.9
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/CHANGELOG.md +6 -0
- package/dist/index.css +33 -34
- package/dist/index.js +96 -61
- package/dist/package.json +1 -1
- package/package.json +4 -4
- package/src/components/qrArea/index.tsx +3 -1
- package/src/components/qrArea/style.scss +25 -33
- package/src/hooks/useMetaMaskExtension.ts +29 -0
- package/src/hooks/useWCState.ts +7 -8
- package/src/hooks/useWagmiConnect.ts +1 -6
- package/src/layout/allWallets/index.tsx +1 -1
- package/src/layout/allWallets/style.scss +2 -7
- package/src/layout/connectDialog/index.tsx +22 -10
- package/src/layout/connectDialog/style.scss +2 -1
- package/src/layout/detailPanel/style.scss +5 -0
- package/src/utils/platform.ts +0 -4
- package/src/wallet-display-override.ts +15 -0
package/CHANGELOG.md
CHANGED
package/dist/index.css
CHANGED
|
@@ -564,8 +564,9 @@
|
|
|
564
564
|
width: 100%;
|
|
565
565
|
max-width: none;
|
|
566
566
|
grid-template-columns: 1fr;
|
|
567
|
+
grid-template-rows: minmax(0, 1fr);
|
|
567
568
|
max-height: 82dvh;
|
|
568
|
-
height:
|
|
569
|
+
height: auto;
|
|
569
570
|
border-radius: 12px 12px 0 0;
|
|
570
571
|
}
|
|
571
572
|
.ck-root .ck-dialog[data-step=selector] .ck-detail {
|
|
@@ -877,6 +878,7 @@
|
|
|
877
878
|
.ck-detail {
|
|
878
879
|
display: flex;
|
|
879
880
|
flex-direction: column;
|
|
881
|
+
min-width: 0;
|
|
880
882
|
background: var(--semantic-paper-dialog);
|
|
881
883
|
min-height: 0;
|
|
882
884
|
position: relative;
|
|
@@ -959,6 +961,9 @@
|
|
|
959
961
|
.ck-detail-body::-webkit-scrollbar-thumb:hover {
|
|
960
962
|
background-color: var(--scale-gray-400);
|
|
961
963
|
}
|
|
964
|
+
.ck-detail-body:has(.ck-all-wallets) {
|
|
965
|
+
padding-bottom: 0;
|
|
966
|
+
}
|
|
962
967
|
|
|
963
968
|
/* src/layout/connectDialog/idle/style.scss */
|
|
964
969
|
.ck-idle {
|
|
@@ -1158,15 +1163,15 @@
|
|
|
1158
1163
|
overflow: hidden;
|
|
1159
1164
|
outline: none;
|
|
1160
1165
|
}
|
|
1161
|
-
.ck-qr-
|
|
1162
|
-
|
|
1163
|
-
}
|
|
1164
|
-
.ck-qr-timeout {
|
|
1166
|
+
.ck-qr-skeleton {
|
|
1167
|
+
padding: 20px;
|
|
1165
1168
|
border: 1px solid var(--semantic-divider-divider-1);
|
|
1169
|
+
border-radius: 20px;
|
|
1166
1170
|
}
|
|
1167
|
-
.ck-qr-skeleton {
|
|
1168
|
-
|
|
1169
|
-
|
|
1171
|
+
.ck-qr-skeleton-inner {
|
|
1172
|
+
display: block;
|
|
1173
|
+
width: 246px;
|
|
1174
|
+
height: 246px;
|
|
1170
1175
|
background:
|
|
1171
1176
|
linear-gradient(
|
|
1172
1177
|
132deg,
|
|
@@ -1177,9 +1182,24 @@
|
|
|
1177
1182
|
animation: ck-qr-shimmer 1.5s linear infinite;
|
|
1178
1183
|
}
|
|
1179
1184
|
@media (max-width: 767px) {
|
|
1180
|
-
.ck-qr-skeleton {
|
|
1181
|
-
width:
|
|
1182
|
-
height:
|
|
1185
|
+
.ck-qr-skeleton-inner {
|
|
1186
|
+
width: 198px;
|
|
1187
|
+
height: 198px;
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
.ck-qr-timeout {
|
|
1191
|
+
width: 288px;
|
|
1192
|
+
height: 288px;
|
|
1193
|
+
border: 1px solid var(--semantic-divider-divider-1);
|
|
1194
|
+
background: var(--scale-gray-100);
|
|
1195
|
+
display: flex;
|
|
1196
|
+
align-items: center;
|
|
1197
|
+
justify-content: center;
|
|
1198
|
+
}
|
|
1199
|
+
@media (max-width: 767px) {
|
|
1200
|
+
.ck-qr-timeout {
|
|
1201
|
+
width: 240px;
|
|
1202
|
+
height: 240px;
|
|
1183
1203
|
}
|
|
1184
1204
|
}
|
|
1185
1205
|
@keyframes ck-qr-shimmer {
|
|
@@ -1207,20 +1227,6 @@
|
|
|
1207
1227
|
height: 198px;
|
|
1208
1228
|
}
|
|
1209
1229
|
}
|
|
1210
|
-
.ck-qr-timeout {
|
|
1211
|
-
width: 248px;
|
|
1212
|
-
height: 248px;
|
|
1213
|
-
background: var(--scale-gray-100);
|
|
1214
|
-
display: flex;
|
|
1215
|
-
align-items: center;
|
|
1216
|
-
justify-content: center;
|
|
1217
|
-
}
|
|
1218
|
-
@media (max-width: 767px) {
|
|
1219
|
-
.ck-qr-timeout {
|
|
1220
|
-
width: 200px;
|
|
1221
|
-
height: 200px;
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
1230
|
.ck-qr-timeout-inner {
|
|
1225
1231
|
display: flex;
|
|
1226
1232
|
flex-direction: column;
|
|
@@ -1690,15 +1696,8 @@
|
|
|
1690
1696
|
gap: 8px;
|
|
1691
1697
|
flex-shrink: 0;
|
|
1692
1698
|
}
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
flex-direction: column;
|
|
1696
|
-
align-items: flex-end;
|
|
1697
|
-
gap: 12px;
|
|
1698
|
-
}
|
|
1699
|
-
.ck-all-wallets-controls .ck-search {
|
|
1700
|
-
width: 100%;
|
|
1701
|
-
}
|
|
1699
|
+
.ck-all-wallets-controls .ck-search {
|
|
1700
|
+
min-width: 0;
|
|
1702
1701
|
}
|
|
1703
1702
|
.ck-wc-filter-btn {
|
|
1704
1703
|
display: inline-flex;
|
package/dist/index.js
CHANGED
|
@@ -194,13 +194,13 @@ var disconnectAll = /* @__PURE__ */ __name(async (onLog) => {
|
|
|
194
194
|
}, "disconnectAll");
|
|
195
195
|
|
|
196
196
|
// src/ConnectKitProvider.tsx
|
|
197
|
-
import { createContext, useCallback as useCallback4, useContext, useEffect as
|
|
197
|
+
import { createContext, useCallback as useCallback4, useContext, useEffect as useEffect6, useMemo as useMemo2, useRef as useRef5, useState as useState6 } from "react";
|
|
198
198
|
import { WagmiProvider, useAccount, useConfig as useConfig3, useDisconnect, useSwitchChain } from "wagmi";
|
|
199
199
|
import { getAccount as getAccount2 } from "@wagmi/core";
|
|
200
200
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
201
201
|
|
|
202
202
|
// src/layout/connectDialog/index.tsx
|
|
203
|
-
import { useEffect as
|
|
203
|
+
import { useEffect as useEffect5, useRef as useRef4, useState as useState5 } from "react";
|
|
204
204
|
import { useConfig as useConfig2 } from "wagmi";
|
|
205
205
|
|
|
206
206
|
// src/layout/connectDialog/asset/closeIcon.tsx
|
|
@@ -504,7 +504,9 @@ var QrArea = /* @__PURE__ */ __name(({ uri, status, logoUrl, hasBg = false, labe
|
|
|
504
504
|
className: "ck-qr-skeleton",
|
|
505
505
|
"aria-busy": "true",
|
|
506
506
|
"aria-label": "Loading QR code"
|
|
507
|
-
}
|
|
507
|
+
}, /* @__PURE__ */ React.createElement("div", {
|
|
508
|
+
className: "ck-qr-skeleton-inner"
|
|
509
|
+
})), status === "ready" && uri && /* @__PURE__ */ React.createElement("div", {
|
|
508
510
|
className: "ck-qr-frame",
|
|
509
511
|
style: {
|
|
510
512
|
"background": bgColor,
|
|
@@ -869,7 +871,7 @@ var AllWallets = /* @__PURE__ */ __name(({ wallets, isLoading, onSelectWallet })
|
|
|
869
871
|
}))), !isLoading && filtered.length === 0 ? /* @__PURE__ */ React.createElement("div", {
|
|
870
872
|
className: "ck-all-wallets-empty",
|
|
871
873
|
role: "status"
|
|
872
|
-
}, /* @__PURE__ */ React.createElement("p", null, "No
|
|
874
|
+
}, /* @__PURE__ */ React.createElement("p", null, "No Wallet found")) : /* @__PURE__ */ React.createElement(WalletGrid, {
|
|
873
875
|
wallets: filtered,
|
|
874
876
|
isLoading,
|
|
875
877
|
onSelect: onSelectWallet
|
|
@@ -1024,18 +1026,36 @@ var Snackbar = /* @__PURE__ */ __name(({ message, onClose }) => {
|
|
|
1024
1026
|
})));
|
|
1025
1027
|
}, "Snackbar");
|
|
1026
1028
|
|
|
1029
|
+
// src/hooks/useMetaMaskExtension.ts
|
|
1030
|
+
import { useEffect, useState as useState2 } from "react";
|
|
1031
|
+
var METAMASK_RDNS = "io.metamask";
|
|
1032
|
+
var isMetaMaskAnnouncement = /* @__PURE__ */ __name((event) => {
|
|
1033
|
+
var _a, _b;
|
|
1034
|
+
const detail = event.detail;
|
|
1035
|
+
return ((_b = (_a = detail == null ? void 0 : detail.info) == null ? void 0 : _a.rdns) == null ? void 0 : _b.toLowerCase()) === METAMASK_RDNS && detail.provider != null;
|
|
1036
|
+
}, "isMetaMaskAnnouncement");
|
|
1037
|
+
var useMetaMaskExtension = /* @__PURE__ */ __name(() => {
|
|
1038
|
+
const [isInstalled, setIsInstalled] = useState2(false);
|
|
1039
|
+
useEffect(() => {
|
|
1040
|
+
const handleAnnouncement = /* @__PURE__ */ __name((event) => {
|
|
1041
|
+
if (isMetaMaskAnnouncement(event)) setIsInstalled(true);
|
|
1042
|
+
}, "handleAnnouncement");
|
|
1043
|
+
window.addEventListener("eip6963:announceProvider", handleAnnouncement);
|
|
1044
|
+
window.dispatchEvent(new Event("eip6963:requestProvider"));
|
|
1045
|
+
return () => {
|
|
1046
|
+
window.removeEventListener("eip6963:announceProvider", handleAnnouncement);
|
|
1047
|
+
};
|
|
1048
|
+
}, []);
|
|
1049
|
+
return isInstalled;
|
|
1050
|
+
}, "useMetaMaskExtension");
|
|
1051
|
+
|
|
1027
1052
|
// src/hooks/useWagmiConnect.ts
|
|
1028
|
-
import { useEffect, useRef, useCallback } from "react";
|
|
1053
|
+
import { useEffect as useEffect2, useRef, useCallback } from "react";
|
|
1029
1054
|
import { useConnect, useConfig } from "wagmi";
|
|
1030
1055
|
var hasMetaMaskKeyword = /* @__PURE__ */ __name((value) => value.toLowerCase().includes("metamask"), "hasMetaMaskKeyword");
|
|
1031
1056
|
var hasWalletConnectKeyword = /* @__PURE__ */ __name((value) => value.toLowerCase().includes("walletconnect"), "hasWalletConnectKeyword");
|
|
1032
1057
|
var isMetaMaskConnector = /* @__PURE__ */ __name((connector) => {
|
|
1033
1058
|
if (connector.id === "metaMaskSDK") return true;
|
|
1034
|
-
if (connector.id === "injected") {
|
|
1035
|
-
if (typeof window === "undefined") return false;
|
|
1036
|
-
const eth = window.ethereum;
|
|
1037
|
-
return (eth == null ? void 0 : eth.isMetaMask) === true;
|
|
1038
|
-
}
|
|
1039
1059
|
if (hasMetaMaskKeyword(connector.id) || hasMetaMaskKeyword(connector.name)) return true;
|
|
1040
1060
|
if (connector.rdns) {
|
|
1041
1061
|
const rdnsList = Array.isArray(connector.rdns) ? connector.rdns : [
|
|
@@ -1070,7 +1090,7 @@ var useWagmiConnect = /* @__PURE__ */ __name(({ onConnect, onError, onQrUri, onS
|
|
|
1070
1090
|
const onErrorRef = useRef(onError);
|
|
1071
1091
|
const onQrUriRef = useRef(onQrUri);
|
|
1072
1092
|
const onSessionExpiredRef = useRef(onSessionExpired);
|
|
1073
|
-
|
|
1093
|
+
useEffect2(() => {
|
|
1074
1094
|
onConnectRef.current = onConnect;
|
|
1075
1095
|
onErrorRef.current = onError;
|
|
1076
1096
|
onQrUriRef.current = onQrUri;
|
|
@@ -1082,7 +1102,7 @@ var useWagmiConnect = /* @__PURE__ */ __name(({ onConnect, onError, onQrUri, onS
|
|
|
1082
1102
|
onSessionExpired
|
|
1083
1103
|
]);
|
|
1084
1104
|
const { connectAsync, reset, isPending } = useConnect();
|
|
1085
|
-
|
|
1105
|
+
useEffect2(() => {
|
|
1086
1106
|
const handler = /* @__PURE__ */ __name((data) => {
|
|
1087
1107
|
var _a;
|
|
1088
1108
|
const msg = data;
|
|
@@ -1155,19 +1175,19 @@ var useWagmiConnect = /* @__PURE__ */ __name(({ onConnect, onError, onQrUri, onS
|
|
|
1155
1175
|
}, "useWagmiConnect");
|
|
1156
1176
|
|
|
1157
1177
|
// src/hooks/useConnectTimeout.ts
|
|
1158
|
-
import { useCallback as useCallback2, useEffect as
|
|
1178
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
1159
1179
|
var DEFAULT_CONNECT_TIMEOUT_MS = 6e5;
|
|
1160
1180
|
var useConnectTimeout = /* @__PURE__ */ __name(({ connectorId, active, expiredSignal = 0, onRetry }) => {
|
|
1161
|
-
const [timedOut, setTimedOut] =
|
|
1181
|
+
const [timedOut, setTimedOut] = useState3(false);
|
|
1162
1182
|
const fire = useCallback2(() => {
|
|
1163
1183
|
setTimedOut(true);
|
|
1164
1184
|
}, []);
|
|
1165
|
-
|
|
1185
|
+
useEffect3(() => {
|
|
1166
1186
|
setTimedOut(false);
|
|
1167
1187
|
}, [
|
|
1168
1188
|
connectorId
|
|
1169
1189
|
]);
|
|
1170
|
-
|
|
1190
|
+
useEffect3(() => {
|
|
1171
1191
|
if (!active || connectorId !== "METAMASK") return;
|
|
1172
1192
|
const timer = setTimeout(fire, DEFAULT_CONNECT_TIMEOUT_MS);
|
|
1173
1193
|
return () => clearTimeout(timer);
|
|
@@ -1177,7 +1197,7 @@ var useConnectTimeout = /* @__PURE__ */ __name(({ connectorId, active, expiredSi
|
|
|
1177
1197
|
fire
|
|
1178
1198
|
]);
|
|
1179
1199
|
const prevSignal = useRef2(expiredSignal);
|
|
1180
|
-
|
|
1200
|
+
useEffect3(() => {
|
|
1181
1201
|
if (!active || connectorId === "METAMASK" || !connectorId) {
|
|
1182
1202
|
prevSignal.current = expiredSignal;
|
|
1183
1203
|
return;
|
|
@@ -1205,13 +1225,22 @@ var useConnectTimeout = /* @__PURE__ */ __name(({ connectorId, active, expiredSi
|
|
|
1205
1225
|
}, "useConnectTimeout");
|
|
1206
1226
|
|
|
1207
1227
|
// src/hooks/useWCState.ts
|
|
1208
|
-
import { useState as
|
|
1209
|
-
|
|
1228
|
+
import { useState as useState4, useRef as useRef3, useCallback as useCallback3, useEffect as useEffect4 } from "react";
|
|
1229
|
+
|
|
1230
|
+
// src/wallet-display-override.ts
|
|
1231
|
+
var CREDIT_WALLET_LISTING_ID = "ce02f1ae74686234eabfa7d31876c442779b730dfe7924a3ca0e6559a7afa30f";
|
|
1232
|
+
var overrideWalletDisplay = /* @__PURE__ */ __name((wallet) => wallet.id === CREDIT_WALLET_LISTING_ID ? {
|
|
1233
|
+
...wallet,
|
|
1234
|
+
name: "PenguinWallet",
|
|
1235
|
+
imageUrl: penguinwallet_default
|
|
1236
|
+
} : wallet, "overrideWalletDisplay");
|
|
1237
|
+
|
|
1238
|
+
// src/hooks/useWCState.ts
|
|
1210
1239
|
var sortCreditWalletFirst = /* @__PURE__ */ __name((list) => [
|
|
1211
1240
|
...list
|
|
1212
1241
|
].sort((a, b) => {
|
|
1213
|
-
if (a.
|
|
1214
|
-
if (b.
|
|
1242
|
+
if (a.id === CREDIT_WALLET_LISTING_ID) return -1;
|
|
1243
|
+
if (b.id === CREDIT_WALLET_LISTING_ID) return 1;
|
|
1215
1244
|
return 0;
|
|
1216
1245
|
}), "sortCreditWalletFirst");
|
|
1217
1246
|
var fetchWCWalletList = /* @__PURE__ */ __name(async (projectId, signal) => {
|
|
@@ -1252,16 +1281,16 @@ var fetchWCWalletList = /* @__PURE__ */ __name(async (projectId, signal) => {
|
|
|
1252
1281
|
return Array.from(byId.values());
|
|
1253
1282
|
}, "fetchWCWalletList");
|
|
1254
1283
|
var useWCState = /* @__PURE__ */ __name(() => {
|
|
1255
|
-
const [subView, setSubView] =
|
|
1256
|
-
const [walletList, setWalletList] =
|
|
1257
|
-
const [walletListLoading, setWalletListLoading] =
|
|
1258
|
-
const [walletListSearch, setWalletListSearch] =
|
|
1259
|
-
const [filterActive, setFilterActive] =
|
|
1260
|
-
const [selectedWallet, setSelectedWallet] =
|
|
1284
|
+
const [subView, setSubView] = useState4("qr");
|
|
1285
|
+
const [walletList, setWalletList] = useState4([]);
|
|
1286
|
+
const [walletListLoading, setWalletListLoading] = useState4(false);
|
|
1287
|
+
const [walletListSearch, setWalletListSearch] = useState4("");
|
|
1288
|
+
const [filterActive, setFilterActive] = useState4(false);
|
|
1289
|
+
const [selectedWallet, setSelectedWallet] = useState4(null);
|
|
1261
1290
|
const loadedRef = useRef3(false);
|
|
1262
1291
|
const abortControllerRef = useRef3(null);
|
|
1263
1292
|
const isMountedRef = useRef3(true);
|
|
1264
|
-
|
|
1293
|
+
useEffect4(() => {
|
|
1265
1294
|
isMountedRef.current = true;
|
|
1266
1295
|
return () => {
|
|
1267
1296
|
var _a;
|
|
@@ -1278,7 +1307,7 @@ var useWCState = /* @__PURE__ */ __name(() => {
|
|
|
1278
1307
|
setWalletListLoading(true);
|
|
1279
1308
|
try {
|
|
1280
1309
|
const list = await fetchWCWalletList(projectId, controller.signal);
|
|
1281
|
-
const sorted = sortCreditWalletFirst(list);
|
|
1310
|
+
const sorted = sortCreditWalletFirst(list).map(overrideWalletDisplay);
|
|
1282
1311
|
if (isMountedRef.current) setWalletList(sorted);
|
|
1283
1312
|
} catch (err) {
|
|
1284
1313
|
const isAbort = err instanceof DOMException && err.name === "AbortError";
|
|
@@ -1349,10 +1378,6 @@ var tryOpenDeepLink = /* @__PURE__ */ __name((uri, deepLinkBase) => {
|
|
|
1349
1378
|
var tryOpenCreditWalletDeeplink = /* @__PURE__ */ __name((payloadUrl) => {
|
|
1350
1379
|
window.location.replace(`creditwallet://?uri=${encodeURIComponent(payloadUrl)}`);
|
|
1351
1380
|
}, "tryOpenCreditWalletDeeplink");
|
|
1352
|
-
var detectMetaMaskExtension = /* @__PURE__ */ __name(() => {
|
|
1353
|
-
var _a;
|
|
1354
|
-
return typeof window !== "undefined" && Boolean((_a = window.ethereum) == null ? void 0 : _a.isMetaMask);
|
|
1355
|
-
}, "detectMetaMaskExtension");
|
|
1356
1381
|
|
|
1357
1382
|
// src/layout/connectDialog/index.tsx
|
|
1358
1383
|
var getContentForConnector = /* @__PURE__ */ __name((id) => {
|
|
@@ -1361,7 +1386,7 @@ var getContentForConnector = /* @__PURE__ */ __name((id) => {
|
|
|
1361
1386
|
if (id === "WALLET_CONNECT") return "walletconnect";
|
|
1362
1387
|
return "idle";
|
|
1363
1388
|
}, "getContentForConnector");
|
|
1364
|
-
var getInitialContentForConnector = /* @__PURE__ */ __name((id) => id === "METAMASK" && !
|
|
1389
|
+
var getInitialContentForConnector = /* @__PURE__ */ __name((id, isMetaMaskExtensionInstalled) => id === "METAMASK" && !isMetaMaskExtensionInstalled ? "metamask-qr" : getContentForConnector(id), "getInitialContentForConnector");
|
|
1365
1390
|
var ConnectDialog = /* @__PURE__ */ __name(({
|
|
1366
1391
|
open,
|
|
1367
1392
|
theme = "dark",
|
|
@@ -1381,14 +1406,15 @@ var ConnectDialog = /* @__PURE__ */ __name(({
|
|
|
1381
1406
|
onError
|
|
1382
1407
|
}) => {
|
|
1383
1408
|
const dialogRef = useRef4(null);
|
|
1384
|
-
const [selectedConnector, setSelectedConnector] =
|
|
1385
|
-
const [recentConnector, setRecentConnector] =
|
|
1386
|
-
const [selectedWallet, setSelectedWallet] =
|
|
1387
|
-
const [step, setStep] =
|
|
1388
|
-
const [content, setContent] =
|
|
1389
|
-
const [showCopySnackbar, setShowCopySnackbar] =
|
|
1390
|
-
const [qrUri, setQrUri] =
|
|
1391
|
-
const [expiredSignal, setExpiredSignal] =
|
|
1409
|
+
const [selectedConnector, setSelectedConnector] = useState5(selectedConnectorProp);
|
|
1410
|
+
const [recentConnector, setRecentConnector] = useState5(null);
|
|
1411
|
+
const [selectedWallet, setSelectedWallet] = useState5(null);
|
|
1412
|
+
const [step, setStep] = useState5(stepProp);
|
|
1413
|
+
const [content, setContent] = useState5("idle");
|
|
1414
|
+
const [showCopySnackbar, setShowCopySnackbar] = useState5(false);
|
|
1415
|
+
const [qrUri, setQrUri] = useState5(null);
|
|
1416
|
+
const [expiredSignal, setExpiredSignal] = useState5(0);
|
|
1417
|
+
const isMetaMaskExtensionInstalled = useMetaMaskExtension();
|
|
1392
1418
|
const contentRef = useRef4(content);
|
|
1393
1419
|
contentRef.current = content;
|
|
1394
1420
|
const preTimeoutContentRef = useRef4("idle");
|
|
@@ -1418,12 +1444,12 @@ var ConnectDialog = /* @__PURE__ */ __name(({
|
|
|
1418
1444
|
cancelConnect();
|
|
1419
1445
|
setQrUri(null);
|
|
1420
1446
|
const restore = preTimeoutContentRef.current;
|
|
1421
|
-
const nextContent = restore !== "idle" && restore !== "timeout" ? restore : getInitialContentForConnector(selectedConnector);
|
|
1447
|
+
const nextContent = restore !== "idle" && restore !== "timeout" ? restore : getInitialContentForConnector(selectedConnector, isMetaMaskExtensionInstalled);
|
|
1422
1448
|
setContent(nextContent);
|
|
1423
1449
|
triggerConnect(selectedConnector);
|
|
1424
1450
|
}, "onRetry")
|
|
1425
1451
|
});
|
|
1426
|
-
|
|
1452
|
+
useEffect5(() => {
|
|
1427
1453
|
if (!timedOut) return;
|
|
1428
1454
|
preTimeoutContentRef.current = contentRef.current;
|
|
1429
1455
|
cancelConnect();
|
|
@@ -1432,7 +1458,16 @@ var ConnectDialog = /* @__PURE__ */ __name(({
|
|
|
1432
1458
|
timedOut,
|
|
1433
1459
|
cancelConnect
|
|
1434
1460
|
]);
|
|
1435
|
-
|
|
1461
|
+
useEffect5(() => {
|
|
1462
|
+
if (isMetaMaskExtensionInstalled && selectedConnector === "METAMASK" && content === "metamask-qr") {
|
|
1463
|
+
setContent("metamask-ext");
|
|
1464
|
+
}
|
|
1465
|
+
}, [
|
|
1466
|
+
isMetaMaskExtensionInstalled,
|
|
1467
|
+
selectedConnector,
|
|
1468
|
+
content
|
|
1469
|
+
]);
|
|
1470
|
+
useEffect5(() => {
|
|
1436
1471
|
const restoreRecent = /* @__PURE__ */ __name(async () => {
|
|
1437
1472
|
var _a;
|
|
1438
1473
|
const wagmiId = await ((_a = config.storage) == null ? void 0 : _a.getItem("recentConnectorId"));
|
|
@@ -1446,7 +1481,7 @@ var ConnectDialog = /* @__PURE__ */ __name(({
|
|
|
1446
1481
|
const wc = useWCState();
|
|
1447
1482
|
const handleSelect = /* @__PURE__ */ __name((id) => {
|
|
1448
1483
|
setSelectedConnector(id);
|
|
1449
|
-
setContent(getInitialContentForConnector(id));
|
|
1484
|
+
setContent(getInitialContentForConnector(id, isMetaMaskExtensionInstalled));
|
|
1450
1485
|
setStep("detail");
|
|
1451
1486
|
triggerConnect(id);
|
|
1452
1487
|
onSelectConnector == null ? void 0 : onSelectConnector(id);
|
|
@@ -1478,7 +1513,7 @@ var ConnectDialog = /* @__PURE__ */ __name(({
|
|
|
1478
1513
|
wc.loadWalletList(wcProjectId).catch(() => void 0);
|
|
1479
1514
|
}
|
|
1480
1515
|
}, "handleShowAllWallets");
|
|
1481
|
-
|
|
1516
|
+
useEffect5(() => {
|
|
1482
1517
|
const dialog = dialogRef.current;
|
|
1483
1518
|
if (!dialog) return;
|
|
1484
1519
|
if (open && !dialog.open) dialog.showModal();
|
|
@@ -1487,12 +1522,12 @@ var ConnectDialog = /* @__PURE__ */ __name(({
|
|
|
1487
1522
|
open
|
|
1488
1523
|
]);
|
|
1489
1524
|
const deeplinkTriedRef = useRef4(false);
|
|
1490
|
-
|
|
1525
|
+
useEffect5(() => {
|
|
1491
1526
|
deeplinkTriedRef.current = false;
|
|
1492
1527
|
}, [
|
|
1493
1528
|
selectedWallet
|
|
1494
1529
|
]);
|
|
1495
|
-
|
|
1530
|
+
useEffect5(() => {
|
|
1496
1531
|
if (deeplinkTriedRef.current) return;
|
|
1497
1532
|
if (!selectedWallet || !qrUri || content !== "wallet-qr") return;
|
|
1498
1533
|
if (!isMobileDevice()) return;
|
|
@@ -1506,12 +1541,12 @@ var ConnectDialog = /* @__PURE__ */ __name(({
|
|
|
1506
1541
|
content
|
|
1507
1542
|
]);
|
|
1508
1543
|
const creditConnectDeeplinkTriedRef = useRef4(false);
|
|
1509
|
-
|
|
1544
|
+
useEffect5(() => {
|
|
1510
1545
|
creditConnectDeeplinkTriedRef.current = false;
|
|
1511
1546
|
}, [
|
|
1512
1547
|
selectedConnector
|
|
1513
1548
|
]);
|
|
1514
|
-
|
|
1549
|
+
useEffect5(() => {
|
|
1515
1550
|
if (creditConnectDeeplinkTriedRef.current) return;
|
|
1516
1551
|
if (content !== "qr" || !qrUri) return;
|
|
1517
1552
|
if (selectedConnector !== "CREDIT_CONNECT") return;
|
|
@@ -1523,7 +1558,7 @@ var ConnectDialog = /* @__PURE__ */ __name(({
|
|
|
1523
1558
|
qrUri,
|
|
1524
1559
|
selectedConnector
|
|
1525
1560
|
]);
|
|
1526
|
-
|
|
1561
|
+
useEffect5(() => {
|
|
1527
1562
|
const prev = document.body.style.overflow;
|
|
1528
1563
|
if (open) document.body.style.overflow = "hidden";
|
|
1529
1564
|
return () => {
|
|
@@ -1532,7 +1567,7 @@ var ConnectDialog = /* @__PURE__ */ __name(({
|
|
|
1532
1567
|
}, [
|
|
1533
1568
|
open
|
|
1534
1569
|
]);
|
|
1535
|
-
|
|
1570
|
+
useEffect5(() => {
|
|
1536
1571
|
if (!open) {
|
|
1537
1572
|
cancelConnect();
|
|
1538
1573
|
setQrUri(null);
|
|
@@ -1545,7 +1580,7 @@ var ConnectDialog = /* @__PURE__ */ __name(({
|
|
|
1545
1580
|
open,
|
|
1546
1581
|
cancelConnect
|
|
1547
1582
|
]);
|
|
1548
|
-
|
|
1583
|
+
useEffect5(() => {
|
|
1549
1584
|
const dialog = dialogRef.current;
|
|
1550
1585
|
if (!dialog) return void 0;
|
|
1551
1586
|
const handleCancel = /* @__PURE__ */ __name((e) => {
|
|
@@ -1633,27 +1668,27 @@ var ConnectKitProvider = /* @__PURE__ */ __name((props) => {
|
|
|
1633
1668
|
}, "ConnectKitProvider");
|
|
1634
1669
|
var ConnectKitProviderInner = /* @__PURE__ */ __name(({ children, connectors, kitConfig, requiredChainId, theme, onConnect, onLog }) => {
|
|
1635
1670
|
var _a;
|
|
1636
|
-
const [isOpen, setIsOpen] =
|
|
1637
|
-
const [pendingResult, setPendingResult] =
|
|
1671
|
+
const [isOpen, setIsOpen] = useState6(false);
|
|
1672
|
+
const [pendingResult, setPendingResult] = useState6(null);
|
|
1638
1673
|
const account = useAccount();
|
|
1639
1674
|
const wagmiConfig = useConfig3();
|
|
1640
1675
|
const { disconnectAsync } = useDisconnect();
|
|
1641
1676
|
const { switchChainAsync } = useSwitchChain();
|
|
1642
1677
|
const onConnectRef = useRef5(onConnect);
|
|
1643
|
-
|
|
1678
|
+
useEffect6(() => {
|
|
1644
1679
|
onConnectRef.current = onConnect;
|
|
1645
1680
|
}, [
|
|
1646
1681
|
onConnect
|
|
1647
1682
|
]);
|
|
1648
1683
|
const isMountedRef = useRef5(true);
|
|
1649
|
-
|
|
1684
|
+
useEffect6(() => {
|
|
1650
1685
|
isMountedRef.current = true;
|
|
1651
1686
|
return () => {
|
|
1652
1687
|
isMountedRef.current = false;
|
|
1653
1688
|
};
|
|
1654
1689
|
}, []);
|
|
1655
1690
|
const needsChainSwitch = requiredChainId != null && account.status === "connected" && account.chainId != null && account.chainId !== requiredChainId;
|
|
1656
|
-
const [isSwitchingChain, setIsSwitchingChain] =
|
|
1691
|
+
const [isSwitchingChain, setIsSwitchingChain] = useState6(false);
|
|
1657
1692
|
const effectiveOpen = isOpen;
|
|
1658
1693
|
const open = useCallback4(() => {
|
|
1659
1694
|
setIsOpen(true);
|
|
@@ -1695,7 +1730,7 @@ var ConnectKitProviderInner = /* @__PURE__ */ __name(({ children, connectors, ki
|
|
|
1695
1730
|
}, [
|
|
1696
1731
|
onLog
|
|
1697
1732
|
]);
|
|
1698
|
-
|
|
1733
|
+
useEffect6(() => {
|
|
1699
1734
|
if (!effectiveOpen) return;
|
|
1700
1735
|
if (account.status !== "connected") return;
|
|
1701
1736
|
setIsOpen(false);
|
|
@@ -1703,7 +1738,7 @@ var ConnectKitProviderInner = /* @__PURE__ */ __name(({ children, connectors, ki
|
|
|
1703
1738
|
effectiveOpen,
|
|
1704
1739
|
account.status
|
|
1705
1740
|
]);
|
|
1706
|
-
|
|
1741
|
+
useEffect6(() => {
|
|
1707
1742
|
var _a2;
|
|
1708
1743
|
if (!pendingResult) return;
|
|
1709
1744
|
if (account.status !== "connected") {
|
package/dist/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gluwa/connect-kit",
|
|
3
|
-
"version": "0.2.0-next.
|
|
3
|
+
"version": "0.2.0-next.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"qrcode.react": "^4.2.0",
|
|
27
27
|
"wagmi": "^2.15.6",
|
|
28
28
|
"@wagmi/core": "^2.16.7",
|
|
29
|
-
"@gluwa/credit-connect-sdk": "0.2.0-next.4",
|
|
30
|
-
"@gluwa/credit-connect-storage-local": "0.2.0-next.4",
|
|
31
29
|
"@gluwa/credit-connect-e2ee-tweetnacl": "0.2.0-next.4",
|
|
32
|
-
"@gluwa/credit-connect-hub-node-ws": "0.1.0-next.4"
|
|
30
|
+
"@gluwa/credit-connect-hub-node-ws": "0.1.0-next.4",
|
|
31
|
+
"@gluwa/credit-connect-sdk": "0.2.0-next.4",
|
|
32
|
+
"@gluwa/credit-connect-storage-local": "0.2.0-next.4"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@tanstack/react-query": "^5.62.0",
|
|
@@ -27,7 +27,9 @@ export const QrArea: FC<QrAreaProps> = ({ uri, status, logoUrl, hasBg = false, l
|
|
|
27
27
|
<div className="ck-qr-group">
|
|
28
28
|
<figure className={`ck-qr ck-qr-${status}`} aria-label="QR Code">
|
|
29
29
|
{status === 'loading' && (
|
|
30
|
-
<div className="ck-qr-skeleton" aria-busy="true" aria-label="Loading QR code"
|
|
30
|
+
<div className="ck-qr-skeleton" aria-busy="true" aria-label="Loading QR code">
|
|
31
|
+
<div className="ck-qr-skeleton-inner" />
|
|
32
|
+
</div>
|
|
31
33
|
)}
|
|
32
34
|
{status === 'ready' && uri && (
|
|
33
35
|
<div
|
|
@@ -9,13 +9,6 @@
|
|
|
9
9
|
padding-bottom: 32px;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
// .ck-qr-group {
|
|
13
|
-
// display: flex;
|
|
14
|
-
// flex-direction: column;
|
|
15
|
-
// align-items: center;
|
|
16
|
-
// gap: 24px;
|
|
17
|
-
// }
|
|
18
|
-
|
|
19
12
|
// ── Text ──────────────────────────────────────────────────────────────────────
|
|
20
13
|
.ck-qr-text {
|
|
21
14
|
display: flex;
|
|
@@ -42,18 +35,16 @@
|
|
|
42
35
|
outline: none;
|
|
43
36
|
}
|
|
44
37
|
|
|
45
|
-
.ck-qr-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.ck-qr-timeout {
|
|
38
|
+
.ck-qr-skeleton {
|
|
39
|
+
padding: 20px;
|
|
50
40
|
border: 1px solid var(--semantic-divider-divider-1);
|
|
41
|
+
border-radius: 20px;
|
|
51
42
|
}
|
|
52
43
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
width:
|
|
56
|
-
height:
|
|
44
|
+
.ck-qr-skeleton-inner {
|
|
45
|
+
display: block;
|
|
46
|
+
width: 246px;
|
|
47
|
+
height: 246px;
|
|
57
48
|
background: linear-gradient(
|
|
58
49
|
132deg,
|
|
59
50
|
var(--scale-gray-100) 36%,
|
|
@@ -64,8 +55,24 @@
|
|
|
64
55
|
animation: ck-qr-shimmer 1.5s linear infinite;
|
|
65
56
|
|
|
66
57
|
@include tablet {
|
|
67
|
-
width:
|
|
68
|
-
height:
|
|
58
|
+
width: 198px;
|
|
59
|
+
height: 198px;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ── Timeout ───────────────────────────────────────────────────────────────────
|
|
64
|
+
.ck-qr-timeout {
|
|
65
|
+
width: 288px;
|
|
66
|
+
height: 288px;
|
|
67
|
+
border: 1px solid var(--semantic-divider-divider-1);
|
|
68
|
+
background: var(--scale-gray-100);
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
justify-content: center;
|
|
72
|
+
|
|
73
|
+
@include tablet {
|
|
74
|
+
width: 240px;
|
|
75
|
+
height: 240px;
|
|
69
76
|
}
|
|
70
77
|
}
|
|
71
78
|
|
|
@@ -93,21 +100,6 @@
|
|
|
93
100
|
}
|
|
94
101
|
}
|
|
95
102
|
|
|
96
|
-
// ── Timeout ───────────────────────────────────────────────────────────────────
|
|
97
|
-
.ck-qr-timeout {
|
|
98
|
-
width: 248px;
|
|
99
|
-
height: 248px;
|
|
100
|
-
background: var(--scale-gray-100);
|
|
101
|
-
display: flex;
|
|
102
|
-
align-items: center;
|
|
103
|
-
justify-content: center;
|
|
104
|
-
|
|
105
|
-
@include tablet {
|
|
106
|
-
width: 200px;
|
|
107
|
-
height: 200px;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
103
|
.ck-qr-timeout-inner {
|
|
112
104
|
display: flex;
|
|
113
105
|
flex-direction: column;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
const METAMASK_RDNS = 'io.metamask';
|
|
4
|
+
|
|
5
|
+
// EIP-6963 응답의 rdns 로 MetaMask 확장을 식별.
|
|
6
|
+
const isMetaMaskAnnouncement = (event: Event): boolean => {
|
|
7
|
+
const detail = (event as CustomEvent<{ info?: { rdns?: string }; provider?: unknown }>).detail;
|
|
8
|
+
return detail?.info?.rdns?.toLowerCase() === METAMASK_RDNS && detail.provider != null;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const useMetaMaskExtension = (): boolean => {
|
|
12
|
+
const [isInstalled, setIsInstalled] = useState(false);
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const handleAnnouncement = (event: Event): void => {
|
|
16
|
+
if (isMetaMaskAnnouncement(event)) setIsInstalled(true);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// 응답 listener를 먼저 등록한 뒤 설치된 provider 목록을 요청.
|
|
20
|
+
window.addEventListener('eip6963:announceProvider', handleAnnouncement);
|
|
21
|
+
window.dispatchEvent(new Event('eip6963:requestProvider'));
|
|
22
|
+
|
|
23
|
+
return () => {
|
|
24
|
+
window.removeEventListener('eip6963:announceProvider', handleAnnouncement);
|
|
25
|
+
};
|
|
26
|
+
}, []);
|
|
27
|
+
|
|
28
|
+
return isInstalled;
|
|
29
|
+
};
|
package/src/hooks/useWCState.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
2
2
|
import type { WCWallet, WCSubView } from '../types';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// CONNECTOR_META.CREDIT_CONNECT.label 은 selector button 표시용 ('Continue with Credit Wallet')
|
|
6
|
-
// 이라 다름 — 별도 상수로 분리.
|
|
7
|
-
const WC_EXPLORER_CREDIT_WALLET_NAME = 'Credit Wallet';
|
|
3
|
+
// TODO-CRCN-11: WC에 PenguinWallet 추가 시 변경
|
|
4
|
+
import { CREDIT_WALLET_LISTING_ID, overrideWalletDisplay } from '../wallet-display-override';
|
|
8
5
|
|
|
9
6
|
const sortCreditWalletFirst = (list: WCWallet[]): WCWallet[] =>
|
|
10
7
|
[...list].sort((a, b) => {
|
|
11
|
-
|
|
12
|
-
if (
|
|
8
|
+
// TODO-CRCN-11: WC에 PenguinWallet 추가 시 변경
|
|
9
|
+
if (a.id === CREDIT_WALLET_LISTING_ID) return -1;
|
|
10
|
+
if (b.id === CREDIT_WALLET_LISTING_ID) return 1;
|
|
13
11
|
return 0;
|
|
14
12
|
});
|
|
15
13
|
|
|
@@ -115,7 +113,8 @@ export const useWCState = (): WCState => {
|
|
|
115
113
|
setWalletListLoading(true);
|
|
116
114
|
try {
|
|
117
115
|
const list = await fetchWCWalletList(projectId, controller.signal);
|
|
118
|
-
|
|
116
|
+
// TODO-CRCN-11: WC에 PenguinWallet 추가 시 변경
|
|
117
|
+
const sorted = sortCreditWalletFirst(list).map(overrideWalletDisplay);
|
|
119
118
|
// Credit Wallet 을 최상단으로 정렬한 상태로 state 저장 — view 측은 정렬 신경 X.
|
|
120
119
|
if (isMountedRef.current) setWalletList(sorted);
|
|
121
120
|
} catch (err) {
|
|
@@ -13,15 +13,10 @@ const hasMetaMaskKeyword = (value: string): boolean => value.toLowerCase().inclu
|
|
|
13
13
|
const hasWalletConnectKeyword = (value: string): boolean =>
|
|
14
14
|
value.toLowerCase().includes('walletconnect');
|
|
15
15
|
|
|
16
|
+
// 전역 provider 대신 wagmi connector 메타데이터로 MetaMask를 판별.
|
|
16
17
|
const isMetaMaskConnector = (connector: WagmiConnectorLike): boolean => {
|
|
17
18
|
if (connector.id === 'metaMaskSDK') return true;
|
|
18
19
|
|
|
19
|
-
if (connector.id === 'injected') {
|
|
20
|
-
if (typeof window === 'undefined') return false;
|
|
21
|
-
const eth = (window as Window & { ethereum?: { isMetaMask?: boolean } }).ethereum;
|
|
22
|
-
return eth?.isMetaMask === true;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
20
|
if (hasMetaMaskKeyword(connector.id) || hasMetaMaskKeyword(connector.name)) return true;
|
|
26
21
|
|
|
27
22
|
if (connector.rdns) {
|
|
@@ -42,7 +42,7 @@ export const AllWallets: FC<AllWalletsProps> = ({ wallets, isLoading, onSelectWa
|
|
|
42
42
|
</div>
|
|
43
43
|
{!isLoading && filtered.length === 0 ? (
|
|
44
44
|
<div className="ck-all-wallets-empty" role="status">
|
|
45
|
-
<p>No
|
|
45
|
+
<p>No Wallet found</p>
|
|
46
46
|
</div>
|
|
47
47
|
) : (
|
|
48
48
|
<WalletGrid wallets={filtered} isLoading={isLoading} onSelect={onSelectWallet} />
|
|
@@ -12,15 +12,11 @@ import { SelectorPanel } from '../selectorPanel';
|
|
|
12
12
|
import { DetailPanel } from '../detailPanel';
|
|
13
13
|
import { Snackbar } from '../../components/snackbar';
|
|
14
14
|
import { resolveConnectorId } from '../../connector-meta';
|
|
15
|
+
import { useMetaMaskExtension } from '../../hooks/useMetaMaskExtension';
|
|
15
16
|
import { useWagmiConnect } from '../../hooks/useWagmiConnect';
|
|
16
17
|
import { useConnectTimeout } from '../../hooks/useConnectTimeout';
|
|
17
18
|
import { useWCState } from '../../hooks/useWCState';
|
|
18
|
-
import {
|
|
19
|
-
detectMetaMaskExtension,
|
|
20
|
-
isMobileDevice,
|
|
21
|
-
tryOpenDeepLink,
|
|
22
|
-
tryOpenCreditWalletDeeplink,
|
|
23
|
-
} from '../../utils/platform';
|
|
19
|
+
import { isMobileDevice, tryOpenDeepLink, tryOpenCreditWalletDeeplink } from '../../utils/platform';
|
|
24
20
|
|
|
25
21
|
export type DialogStep = 'selector' | 'detail';
|
|
26
22
|
|
|
@@ -49,8 +45,11 @@ const getContentForConnector = (id: ConnectorId): DetailContent => {
|
|
|
49
45
|
};
|
|
50
46
|
|
|
51
47
|
// MM 은 확장 감지 시 즉시 extension 연결, 아니면 QR. (select / retry 공통)
|
|
52
|
-
const getInitialContentForConnector = (
|
|
53
|
-
id
|
|
48
|
+
const getInitialContentForConnector = (
|
|
49
|
+
id: ConnectorId,
|
|
50
|
+
isMetaMaskExtensionInstalled: boolean,
|
|
51
|
+
): DetailContent =>
|
|
52
|
+
id === 'METAMASK' && !isMetaMaskExtensionInstalled ? 'metamask-qr' : getContentForConnector(id);
|
|
54
53
|
|
|
55
54
|
export const ConnectDialog: FC<ConnectDialogProps> = ({
|
|
56
55
|
open,
|
|
@@ -90,6 +89,8 @@ export const ConnectDialog: FC<ConnectDialogProps> = ({
|
|
|
90
89
|
const [qrUri, setQrUri] = useState<string | null>(null);
|
|
91
90
|
// 외부 만료 신호 카운터 — CC(서버 push session_expired) / WC(connect reject) 수신 시 증가.
|
|
92
91
|
const [expiredSignal, setExpiredSignal] = useState(0);
|
|
92
|
+
// EIP-6963 기반 MetaMask 확장 설치 상태.
|
|
93
|
+
const isMetaMaskExtensionInstalled = useMetaMaskExtension();
|
|
93
94
|
|
|
94
95
|
// 현재 content 를 ref 로 추적 (effect deps 없이 최신값 참조용).
|
|
95
96
|
const contentRef = useRef<DetailContent>(content);
|
|
@@ -137,7 +138,7 @@ export const ConnectDialog: FC<ConnectDialogProps> = ({
|
|
|
137
138
|
const nextContent: DetailContent =
|
|
138
139
|
restore !== 'idle' && restore !== 'timeout'
|
|
139
140
|
? restore
|
|
140
|
-
: getInitialContentForConnector(selectedConnector);
|
|
141
|
+
: getInitialContentForConnector(selectedConnector, isMetaMaskExtensionInstalled);
|
|
141
142
|
setContent(nextContent);
|
|
142
143
|
triggerConnect(selectedConnector);
|
|
143
144
|
},
|
|
@@ -152,6 +153,17 @@ export const ConnectDialog: FC<ConnectDialogProps> = ({
|
|
|
152
153
|
setContent('timeout');
|
|
153
154
|
}, [timedOut, cancelConnect]);
|
|
154
155
|
|
|
156
|
+
// provider 응답이 늦게 도착하면 QR에서 확장 연결 화면으로 전환.
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
if (
|
|
159
|
+
isMetaMaskExtensionInstalled &&
|
|
160
|
+
selectedConnector === 'METAMASK' &&
|
|
161
|
+
content === 'metamask-qr'
|
|
162
|
+
) {
|
|
163
|
+
setContent('metamask-ext');
|
|
164
|
+
}
|
|
165
|
+
}, [isMetaMaskExtensionInstalled, selectedConnector, content]);
|
|
166
|
+
|
|
155
167
|
// 마운트 시 wagmi storage 의 recentConnectorId(연결 성공 시 wagmi 가 저장) 복원.
|
|
156
168
|
useEffect(() => {
|
|
157
169
|
const restoreRecent = async (): Promise<void> => {
|
|
@@ -168,7 +180,7 @@ export const ConnectDialog: FC<ConnectDialogProps> = ({
|
|
|
168
180
|
const handleSelect = (id: ConnectorId) => {
|
|
169
181
|
setSelectedConnector(id);
|
|
170
182
|
// recent 는 클릭이 아니라 연결 성공(onConnect) 시점에 기록 — 위 useWagmiConnect onConnect 참조.
|
|
171
|
-
setContent(getInitialContentForConnector(id));
|
|
183
|
+
setContent(getInitialContentForConnector(id, isMetaMaskExtensionInstalled));
|
|
172
184
|
setStep('detail');
|
|
173
185
|
// wagmi connect 시작 (display_uri 도착 시 setQrUri 자동 호출)
|
|
174
186
|
triggerConnect(id);
|
|
@@ -37,8 +37,9 @@
|
|
|
37
37
|
width: 100%;
|
|
38
38
|
max-width: none;
|
|
39
39
|
grid-template-columns: 1fr;
|
|
40
|
+
grid-template-rows: minmax(0, 1fr);
|
|
40
41
|
max-height: 82dvh;
|
|
41
|
-
height:
|
|
42
|
+
height: auto;
|
|
42
43
|
border-radius: 12px 12px 0 0;
|
|
43
44
|
|
|
44
45
|
&[data-step='selector'] .ck-detail { display: none !important; }
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
.ck-detail {
|
|
4
4
|
display: flex;
|
|
5
5
|
flex-direction: column;
|
|
6
|
+
min-width: 0;
|
|
6
7
|
background: var(--semantic-paper-dialog);
|
|
7
8
|
min-height: 0;
|
|
8
9
|
position: relative;
|
|
@@ -61,4 +62,8 @@
|
|
|
61
62
|
overflow-y: auto;
|
|
62
63
|
padding: 20px;
|
|
63
64
|
@include themedScrollbar;
|
|
65
|
+
|
|
66
|
+
&:has(.ck-all-wallets) {
|
|
67
|
+
padding-bottom: 0;
|
|
68
|
+
}
|
|
64
69
|
}
|
package/src/utils/platform.ts
CHANGED
|
@@ -13,7 +13,3 @@ export const tryOpenDeepLink = (uri: string, deepLinkBase: string): void => {
|
|
|
13
13
|
export const tryOpenCreditWalletDeeplink = (payloadUrl: string): void => {
|
|
14
14
|
window.location.replace(`creditwallet://?uri=${encodeURIComponent(payloadUrl)}`);
|
|
15
15
|
};
|
|
16
|
-
|
|
17
|
-
export const detectMetaMaskExtension = (): boolean =>
|
|
18
|
-
typeof window !== 'undefined' &&
|
|
19
|
-
Boolean((window as Window & { ethereum?: { isMetaMask?: boolean } }).ethereum?.isMetaMask);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import penguinWalletIcon from '../assets/penguinwallet.png';
|
|
2
|
+
import type { WCWallet } from './types';
|
|
3
|
+
|
|
4
|
+
// TODO-CRCN-11: WC에 PenguinWallet 추가 시 삭제
|
|
5
|
+
export const CREDIT_WALLET_LISTING_ID =
|
|
6
|
+
'ce02f1ae74686234eabfa7d31876c442779b730dfe7924a3ca0e6559a7afa30f';
|
|
7
|
+
|
|
8
|
+
export const overrideWalletDisplay = (wallet: WCWallet): WCWallet =>
|
|
9
|
+
wallet.id === CREDIT_WALLET_LISTING_ID
|
|
10
|
+
? {
|
|
11
|
+
...wallet,
|
|
12
|
+
name: 'PenguinWallet',
|
|
13
|
+
imageUrl: penguinWalletIcon,
|
|
14
|
+
}
|
|
15
|
+
: wallet;
|