@gluwa/connect-kit 0.1.0-next.2 → 0.1.0-next.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/CHANGELOG.md +6 -0
- package/dist/chunk-DDA6FP6U.js +7 -0
- package/dist/credit-connect.d.ts +16 -0
- package/dist/credit-connect.js +399 -0
- package/dist/index.d.ts +12 -15
- package/dist/index.js +34 -426
- package/dist/package.json +13 -1
- package/package.json +10 -1
- package/src/ConnectKitProvider.tsx +31 -2
- package/src/ConnectModal.scss +2 -2
- package/src/ConnectModal.tsx +14 -23
- package/src/credit-connect.ts +2 -0
- package/src/creditConnectConnector.ts +1 -0
- package/src/index.ts +0 -2
- package/src/views/CreditWalletView.tsx +5 -2
- package/tsup.config.ts +5 -1
|
@@ -9,10 +9,16 @@ import {
|
|
|
9
9
|
type FC,
|
|
10
10
|
type ReactNode,
|
|
11
11
|
} from 'react';
|
|
12
|
-
import { useAccount, useDisconnect } from 'wagmi';
|
|
12
|
+
import { WagmiProvider, useAccount, useDisconnect } from 'wagmi';
|
|
13
|
+
import type { Config } from 'wagmi';
|
|
14
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
13
15
|
import { ConnectModal } from './ConnectModal';
|
|
14
16
|
import type { ConnectErrorContext, ConnectResult, ConnectorId, Connectors } from './types';
|
|
15
17
|
|
|
18
|
+
// wagmiConfig prop으로 기존 프로젝트 통합 시 내부에서 사용하는 QueryClient.
|
|
19
|
+
// 모듈 레벨에 한 번만 생성 — 연결 플로우용으로만 쓰이므로 공유해도 무방.
|
|
20
|
+
const internalQueryClient = new QueryClient();
|
|
21
|
+
|
|
16
22
|
export interface ConnectKitProviderProps {
|
|
17
23
|
children: ReactNode;
|
|
18
24
|
connectors: Connectors;
|
|
@@ -33,6 +39,16 @@ export interface ConnectKitProviderProps {
|
|
|
33
39
|
* 미제공 시 기본 동작은 selector로 복귀.
|
|
34
40
|
*/
|
|
35
41
|
renderConnectError?: (ctx: ConnectErrorContext) => ReactNode;
|
|
42
|
+
/**
|
|
43
|
+
* 기존 프로젝트 통합용. wagmi config를 넘기면 ConnectKitProvider 내부에서
|
|
44
|
+
* WagmiProvider를 직접 세운다.
|
|
45
|
+
*
|
|
46
|
+
* - 기존 프로젝트: 앱에 WagmiProvider가 없으므로 wagmiConfig를 넘긴다.
|
|
47
|
+
* ConnectKitProvider가 같은 config 인스턴스로 WagmiProvider를 셀프 마운트하므로
|
|
48
|
+
* 기존 wagmi 상태 store와 단일 config를 공유한다.
|
|
49
|
+
* - 신규 프로젝트: 앱이 이미 WagmiProvider를 감싸므로 이 prop은 불필요하다.
|
|
50
|
+
*/
|
|
51
|
+
wagmiConfig?: Config;
|
|
36
52
|
}
|
|
37
53
|
|
|
38
54
|
export interface ConnectKitContextValue {
|
|
@@ -57,7 +73,20 @@ const resolveConnectorId = (wagmiConnectorId: string | undefined): ConnectorId |
|
|
|
57
73
|
return null;
|
|
58
74
|
};
|
|
59
75
|
|
|
60
|
-
export const ConnectKitProvider: FC<ConnectKitProviderProps> = ({
|
|
76
|
+
export const ConnectKitProvider: FC<ConnectKitProviderProps> = (props) => {
|
|
77
|
+
if (props.wagmiConfig) {
|
|
78
|
+
return (
|
|
79
|
+
<WagmiProvider config={props.wagmiConfig}>
|
|
80
|
+
<QueryClientProvider client={internalQueryClient}>
|
|
81
|
+
<ConnectKitProviderInner {...props} />
|
|
82
|
+
</QueryClientProvider>
|
|
83
|
+
</WagmiProvider>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
return <ConnectKitProviderInner {...props} />;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const ConnectKitProviderInner: FC<ConnectKitProviderProps> = ({
|
|
61
90
|
children,
|
|
62
91
|
connectors,
|
|
63
92
|
wcProjectId,
|
package/src/ConnectModal.scss
CHANGED
|
@@ -520,11 +520,11 @@
|
|
|
520
520
|
}
|
|
521
521
|
}
|
|
522
522
|
|
|
523
|
-
// 스크롤 wrapper —
|
|
523
|
+
// 스크롤 wrapper — 세로 스크롤만 담당
|
|
524
524
|
.ck-wallet-grid-scroll {
|
|
525
525
|
flex: 1;
|
|
526
526
|
min-height: 0;
|
|
527
|
-
width:
|
|
527
|
+
width: 100%;
|
|
528
528
|
overflow-x: hidden;
|
|
529
529
|
overflow-y: auto;
|
|
530
530
|
}
|
package/src/ConnectModal.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState, useEffect, useCallback,
|
|
1
|
+
import { useState, useEffect, useCallback, useMemo, type FC, type ReactNode } from 'react';
|
|
2
2
|
import './ConnectModal.scss';
|
|
3
3
|
import { useAccount, useConfig, useDisconnect } from 'wagmi';
|
|
4
4
|
import {
|
|
@@ -303,8 +303,7 @@ const ConnectModalInner: FC<ConnectModalInnerProps> = ({
|
|
|
303
303
|
renderConnectError,
|
|
304
304
|
}) => {
|
|
305
305
|
const [selectedConnector, setSelectedConnector] = useState<ConnectorId | null>(null);
|
|
306
|
-
const [
|
|
307
|
-
const pendingQrConnectorRef = useRef<ConnectorId | null>(null);
|
|
306
|
+
const [qrUri, setQrUri] = useState<string | null>(null);
|
|
308
307
|
const [recentConnector, setRecentConnector] = useState<ConnectorId | null>(null);
|
|
309
308
|
const [hasMetaMaskExtension, setHasMetaMaskExtension] = useState<boolean>(false);
|
|
310
309
|
const [errorState, setErrorState] = useState<{ connectorId: ConnectorId; error: Error } | null>(
|
|
@@ -329,12 +328,9 @@ const ConnectModalInner: FC<ConnectModalInnerProps> = ({
|
|
|
329
328
|
return wagmiConfig.chains.find((chain) => chain.id === requiredChainId)?.name;
|
|
330
329
|
}, [wagmiConfig.chains, requiredChainId]);
|
|
331
330
|
|
|
332
|
-
// QR URI 수신
|
|
331
|
+
// QR URI 수신
|
|
333
332
|
const handleQrUri = useCallback((uri: string | null) => {
|
|
334
|
-
|
|
335
|
-
const id = pendingQrConnectorRef.current;
|
|
336
|
-
if (id) setQrUriMap((prev) => ({ ...prev, [id]: uri }));
|
|
337
|
-
}
|
|
333
|
+
setQrUri(uri);
|
|
338
334
|
}, []);
|
|
339
335
|
|
|
340
336
|
// 연결 완료
|
|
@@ -349,7 +345,7 @@ const ConnectModalInner: FC<ConnectModalInnerProps> = ({
|
|
|
349
345
|
[onConnect, onClose],
|
|
350
346
|
);
|
|
351
347
|
|
|
352
|
-
// 연결 실패
|
|
348
|
+
// 연결 실패
|
|
353
349
|
const handleError = useCallback(
|
|
354
350
|
(error: unknown, connectorId: ConnectorId): void => {
|
|
355
351
|
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
@@ -357,11 +353,7 @@ const ConnectModalInner: FC<ConnectModalInnerProps> = ({
|
|
|
357
353
|
`[connect-kit] connection failed (${connectorId}): ${normalizedError.message}`,
|
|
358
354
|
normalizedError,
|
|
359
355
|
);
|
|
360
|
-
|
|
361
|
-
const next = { ...prev };
|
|
362
|
-
delete next[connectorId];
|
|
363
|
-
return next;
|
|
364
|
-
});
|
|
356
|
+
setQrUri(null);
|
|
365
357
|
wc.resetView();
|
|
366
358
|
if (renderConnectError) {
|
|
367
359
|
setErrorState({ connectorId, error: normalizedError });
|
|
@@ -401,24 +393,23 @@ const ConnectModalInner: FC<ConnectModalInnerProps> = ({
|
|
|
401
393
|
setHasMetaMaskExtension(detectMetaMaskExtension());
|
|
402
394
|
}, []);
|
|
403
395
|
|
|
404
|
-
// 모달 닫힐 때 상태
|
|
396
|
+
// 모달 닫힐 때 상태 초기화
|
|
405
397
|
useEffect(() => {
|
|
406
398
|
if (!open) {
|
|
407
399
|
setSelectedConnector(null);
|
|
408
|
-
|
|
409
|
-
pendingQrConnectorRef.current = null;
|
|
400
|
+
setQrUri(null);
|
|
410
401
|
setErrorState(null);
|
|
411
402
|
wc.reset();
|
|
412
403
|
cancelConnect();
|
|
413
404
|
}
|
|
414
405
|
}, [open, cancelConnect, wc.reset]);
|
|
415
406
|
|
|
416
|
-
// 커넥터 선택
|
|
407
|
+
// 커넥터 선택 — 선택할 때마다 QR을 초기화해 새 세션 URI가 표시되도록 함
|
|
417
408
|
const handleSelectConnector = useCallback(
|
|
418
409
|
(id: ConnectorId): void => {
|
|
419
410
|
if (id === selectedConnector && !errorState) return;
|
|
420
|
-
pendingQrConnectorRef.current = id;
|
|
421
411
|
setSelectedConnector(id);
|
|
412
|
+
setQrUri(null);
|
|
422
413
|
setErrorState(null);
|
|
423
414
|
wc.resetView();
|
|
424
415
|
writeRecentConnector(id);
|
|
@@ -442,7 +433,7 @@ const ConnectModalInner: FC<ConnectModalInnerProps> = ({
|
|
|
442
433
|
],
|
|
443
434
|
);
|
|
444
435
|
|
|
445
|
-
// 뒤로가기
|
|
436
|
+
// 뒤로가기
|
|
446
437
|
const handleBack = useCallback((): void => {
|
|
447
438
|
if (errorState) {
|
|
448
439
|
setErrorState(null);
|
|
@@ -450,8 +441,8 @@ const ConnectModalInner: FC<ConnectModalInnerProps> = ({
|
|
|
450
441
|
return;
|
|
451
442
|
}
|
|
452
443
|
if (selectedConnector === 'WALLET_CONNECT' && wc.handleBack()) return;
|
|
453
|
-
pendingQrConnectorRef.current = null;
|
|
454
444
|
setSelectedConnector(null);
|
|
445
|
+
setQrUri(null);
|
|
455
446
|
cancelConnect();
|
|
456
447
|
}, [selectedConnector, errorState, wc.handleBack, cancelConnect]);
|
|
457
448
|
|
|
@@ -487,7 +478,7 @@ const ConnectModalInner: FC<ConnectModalInnerProps> = ({
|
|
|
487
478
|
retry: () => {
|
|
488
479
|
const id = errorState.connectorId;
|
|
489
480
|
setErrorState(null);
|
|
490
|
-
|
|
481
|
+
setQrUri(null);
|
|
491
482
|
cancelConnect();
|
|
492
483
|
triggerConnect(id);
|
|
493
484
|
},
|
|
@@ -554,7 +545,7 @@ const ConnectModalInner: FC<ConnectModalInnerProps> = ({
|
|
|
554
545
|
/>
|
|
555
546
|
<DetailPane
|
|
556
547
|
selectedConnector={selectedConnector}
|
|
557
|
-
qrUri={
|
|
548
|
+
qrUri={qrUri}
|
|
558
549
|
hasMetaMaskExtension={hasMetaMaskExtension}
|
|
559
550
|
connectorLogoMap={connectorLogoMap}
|
|
560
551
|
wc={wc}
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export { ConnectModal } from './ConnectModal';
|
|
2
2
|
export { ConnectKitProvider, useConnectKit } from './ConnectKitProvider';
|
|
3
3
|
export type { ConnectKitContextValue, ConnectKitProviderProps } from './ConnectKitProvider';
|
|
4
|
-
export { creditConnectConnector } from './creditConnectConnector';
|
|
5
|
-
export type { CreditConnectConnectorOptions } from './creditConnectConnector';
|
|
6
4
|
export type {
|
|
7
5
|
ConnectErrorContext,
|
|
8
6
|
ConnectErrorReason,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type FC, useEffect, useMemo } from 'react';
|
|
1
|
+
import { type FC, useEffect, useMemo, useRef } from 'react';
|
|
2
2
|
import { isMobileDevice, tryOpenDeepLink } from '../utils/platform';
|
|
3
3
|
import { CONNECTOR_META } from '../connector-meta';
|
|
4
4
|
import { type ConnectorId } from '../types';
|
|
@@ -12,9 +12,12 @@ interface CreditWalletViewProps {
|
|
|
12
12
|
export const CreditWalletView: FC<CreditWalletViewProps> = ({ connectorId, qrUri }) => {
|
|
13
13
|
const { downloadUrl, logoUrl, deepLinkBase } = CONNECTOR_META[connectorId];
|
|
14
14
|
const isMobile = useMemo(() => isMobileDevice(), []);
|
|
15
|
+
// WC 세션 만료로 qrUri가 재발급되더라도 딥링크는 최초 1회만 실행
|
|
16
|
+
const hasRedirectedRef = useRef(false);
|
|
15
17
|
|
|
16
18
|
useEffect(() => {
|
|
17
|
-
if (isMobile && qrUri && deepLinkBase) {
|
|
19
|
+
if (isMobile && qrUri && deepLinkBase && !hasRedirectedRef.current) {
|
|
20
|
+
hasRedirectedRef.current = true;
|
|
18
21
|
tryOpenDeepLink(qrUri, deepLinkBase);
|
|
19
22
|
}
|
|
20
23
|
}, [isMobile, qrUri, deepLinkBase]);
|
package/tsup.config.ts
CHANGED
|
@@ -2,7 +2,10 @@ import { defineConfig } from 'tsup';
|
|
|
2
2
|
import { sassPlugin } from 'esbuild-sass-plugin';
|
|
3
3
|
|
|
4
4
|
export default defineConfig({
|
|
5
|
-
entry: {
|
|
5
|
+
entry: {
|
|
6
|
+
index: 'src/index.ts',
|
|
7
|
+
'credit-connect': 'src/credit-connect.ts',
|
|
8
|
+
},
|
|
6
9
|
format: ['esm'],
|
|
7
10
|
dts: true,
|
|
8
11
|
clean: true,
|
|
@@ -13,6 +16,7 @@ export default defineConfig({
|
|
|
13
16
|
'wagmi',
|
|
14
17
|
'@wagmi/core',
|
|
15
18
|
'viem',
|
|
19
|
+
'@tanstack/react-query',
|
|
16
20
|
'@gluwa/credit-connect-sdk',
|
|
17
21
|
'@gluwa/credit-connect-sdk/dapp',
|
|
18
22
|
'@gluwa/credit-connect-sdk/storage',
|