@gluwa/connect-kit 0.1.0-next.3 → 0.2.0-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/assets/fonts/Inter-Medium.ttf +0 -0
  3. package/assets/fonts/Inter-Medium.woff2 +0 -0
  4. package/assets/fonts/Inter-Regular.ttf +0 -0
  5. package/assets/fonts/Inter-Regular.woff2 +0 -0
  6. package/assets/fonts/Inter-SemiBold.ttf +0 -0
  7. package/assets/fonts/Inter-SemiBold.woff2 +0 -0
  8. package/assets/graphic.png +0 -0
  9. package/assets/metamask.png +0 -0
  10. package/assets/penguinwallet.png +0 -0
  11. package/assets/wc-logo.svg +3 -0
  12. package/assets/wc-search.png +0 -0
  13. package/dist/chunk-VE5LB7BN.js +405 -0
  14. package/dist/credit-connect.js +2 -394
  15. package/dist/index.css +2075 -0
  16. package/dist/index.d.ts +58 -33
  17. package/dist/index.js +1748 -1503
  18. package/dist/package.json +16 -10
  19. package/package.json +14 -11
  20. package/src/ConnectKitProvider.tsx +133 -75
  21. package/src/api/account.ts +21 -0
  22. package/src/api/asset.ts +10 -0
  23. package/src/api/balance.ts +10 -0
  24. package/src/api/chain.ts +17 -0
  25. package/src/api/contract.ts +33 -0
  26. package/src/api/transaction.ts +12 -0
  27. package/src/assets.d.ts +5 -0
  28. package/src/components/actionItem/index.tsx +50 -0
  29. package/src/components/actionItem/style.scss +47 -0
  30. package/src/components/copyLink/index.tsx +16 -0
  31. package/src/components/copyLink/style.scss +16 -0
  32. package/src/components/qrArea/index.tsx +72 -0
  33. package/src/components/qrArea/style.scss +122 -0
  34. package/src/components/searchBar/asset/Search.tsx +20 -0
  35. package/src/components/searchBar/asset/XMarkCircle.tsx +24 -0
  36. package/src/components/searchBar/index.tsx +44 -0
  37. package/src/components/searchBar/style.scss +58 -0
  38. package/src/components/toast/index.tsx +41 -0
  39. package/src/components/toast/style.scss +108 -0
  40. package/src/components/toggle/index.tsx +27 -0
  41. package/src/components/toggle/style.scss +53 -0
  42. package/src/components/walletGrid/index.tsx +64 -0
  43. package/src/components/walletGrid/style.scss +108 -0
  44. package/src/components/walletItem/index.tsx +49 -0
  45. package/src/components/walletItem/style.scss +70 -0
  46. package/src/connector-meta.ts +16 -11
  47. package/src/core/config.ts +102 -0
  48. package/src/creditConnectConnector.ts +198 -184
  49. package/src/events/account.ts +76 -0
  50. package/src/hooks/useConnectBanner.ts +79 -0
  51. package/src/hooks/useConnectTimeout.ts +92 -0
  52. package/src/hooks/useMetaMaskExtension.ts +29 -0
  53. package/src/hooks/useWCState.ts +45 -14
  54. package/src/hooks/useWagmiConnect.ts +42 -11
  55. package/src/index.ts +38 -2
  56. package/src/layout/allWallets/index.tsx +52 -0
  57. package/src/layout/allWallets/style.scss +57 -0
  58. package/src/layout/connectDialog/asset/backIcon.tsx +24 -0
  59. package/src/layout/connectDialog/asset/checkIcon.tsx +28 -0
  60. package/src/layout/connectDialog/asset/closeIcon.tsx +21 -0
  61. package/src/layout/connectDialog/asset/copyIcon.tsx +28 -0
  62. package/src/layout/connectDialog/asset/linkIcon.tsx +24 -0
  63. package/src/layout/connectDialog/asset/spinner.tsx +21 -0
  64. package/src/layout/connectDialog/asset/warningIcon.tsx +21 -0
  65. package/src/layout/connectDialog/idle/assets/banner-placeholder.png +0 -0
  66. package/src/layout/connectDialog/idle/index.tsx +55 -0
  67. package/src/layout/connectDialog/idle/style.scss +52 -0
  68. package/src/layout/connectDialog/index.tsx +432 -0
  69. package/src/layout/connectDialog/loading/index.tsx +13 -0
  70. package/src/layout/connectDialog/loading/style.scss +19 -0
  71. package/src/layout/connectDialog/metaMask/index.tsx +61 -0
  72. package/src/layout/connectDialog/metaMask/style.scss +65 -0
  73. package/src/layout/connectDialog/qr/index.tsx +33 -0
  74. package/src/layout/connectDialog/style.scss +48 -0
  75. package/src/layout/connectDialog/timeout/index.tsx +31 -0
  76. package/src/layout/connectDialog/timeout/style.scss +64 -0
  77. package/src/layout/connectDialog/walletConnect/index.tsx +45 -0
  78. package/src/layout/connectDialog/walletConnect/style.scss +48 -0
  79. package/src/layout/connectDialog/walletQR/index.tsx +37 -0
  80. package/src/layout/detailPanel/index.tsx +175 -0
  81. package/src/layout/detailPanel/style.scss +70 -0
  82. package/src/layout/selectorPanel/index.tsx +100 -0
  83. package/src/layout/selectorPanel/style.scss +113 -0
  84. package/src/style/color.scss +417 -0
  85. package/src/style/font.scss +28 -0
  86. package/src/style/index.scss +5 -0
  87. package/src/style/mixin.scss +217 -0
  88. package/src/style/reset.scss +110 -0
  89. package/src/style/variables.scss +13 -0
  90. package/src/types.ts +40 -7
  91. package/src/utils/platform.ts +6 -7
  92. package/src/wallet-display-override.ts +15 -0
  93. package/tsconfig.json +5 -1
  94. package/tsup.config.ts +32 -2
  95. package/assets/creditwallet.png +0 -0
  96. package/dist/chunk-DDA6FP6U.js +0 -7
  97. package/src/ConnectModal.scss +0 -665
  98. package/src/ConnectModal.tsx +0 -559
  99. package/src/components/QRFrame.tsx +0 -43
  100. package/src/views/CreditWalletView.tsx +0 -59
  101. package/src/views/IdleView.tsx +0 -10
  102. package/src/views/MetaMaskView.tsx +0 -64
  103. package/src/views/SwitchChainView.tsx +0 -67
  104. package/src/views/WalletConnectView.tsx +0 -206
package/dist/package.json CHANGED
@@ -1,14 +1,17 @@
1
1
  {
2
2
  "name": "@gluwa/connect-kit",
3
- "version": "0.1.0-next.3",
3
+ "version": "0.2.0-next.10",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
7
+ "types": "./src/index.ts",
7
8
  "default": "./src/index.ts"
8
9
  },
9
10
  "./credit-connect": {
11
+ "types": "./src/credit-connect.ts",
10
12
  "default": "./src/credit-connect.ts"
11
13
  },
14
+ "./index.css": "./dist/index.css",
12
15
  "./package.json": "./package.json"
13
16
  },
14
17
  "publishConfig": {
@@ -27,7 +30,10 @@
27
30
  "./index.css": "./dist/index.css"
28
31
  }
29
32
  },
30
- "sideEffects": true,
33
+ "sideEffects": [
34
+ "**/*.scss",
35
+ "**/*.css"
36
+ ],
31
37
  "scripts": {
32
38
  "prepack": "pnpm build && cp package.json dist/ && cp README.md dist/",
33
39
  "build": "tsup",
@@ -38,7 +44,13 @@
38
44
  "author": "",
39
45
  "license": "ISC",
40
46
  "dependencies": {
41
- "qrcode.react": "^3.2.0"
47
+ "qrcode.react": "^4.2.0",
48
+ "wagmi": "^2.15.6",
49
+ "@wagmi/core": "^2.16.7",
50
+ "@gluwa/credit-connect-sdk": "workspace:*",
51
+ "@gluwa/credit-connect-storage-local": "workspace:*",
52
+ "@gluwa/credit-connect-e2ee-tweetnacl": "workspace:*",
53
+ "@gluwa/credit-connect-hub-node-ws": "workspace:*"
42
54
  },
43
55
  "devDependencies": {
44
56
  "@gluwa/credit-connect-sdk": "workspace:*",
@@ -55,17 +67,11 @@
55
67
  "wagmi": "^2.15.6"
56
68
  },
57
69
  "peerDependencies": {
58
- "@gluwa/credit-connect-sdk": "workspace:*",
59
70
  "@tanstack/react-query": ">=5.0.0",
60
- "@wagmi/core": ">=2.0.0",
61
71
  "react": "^18.0.0 || ^19.0.0",
62
- "viem": ">=2.0.0",
63
- "wagmi": ">=2.0.0"
72
+ "viem": ">=2.0.0"
64
73
  },
65
74
  "peerDependenciesMeta": {
66
- "@gluwa/credit-connect-sdk": {
67
- "optional": true
68
- },
69
75
  "@tanstack/react-query": {
70
76
  "optional": true
71
77
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gluwa/connect-kit",
3
- "version": "0.1.0-next.3",
3
+ "version": "0.2.0-next.10",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -16,11 +16,20 @@
16
16
  "publishConfig": {
17
17
  "access": "public"
18
18
  },
19
- "sideEffects": true,
19
+ "sideEffects": [
20
+ "**/*.scss",
21
+ "**/*.css"
22
+ ],
20
23
  "author": "",
21
24
  "license": "ISC",
22
25
  "dependencies": {
23
- "qrcode.react": "^3.2.0"
26
+ "qrcode.react": "^4.2.0",
27
+ "wagmi": "^2.15.6",
28
+ "@wagmi/core": "^2.16.7",
29
+ "@gluwa/credit-connect-sdk": "0.2.0-next.5",
30
+ "@gluwa/credit-connect-storage-local": "0.2.0-next.5",
31
+ "@gluwa/credit-connect-e2ee-tweetnacl": "0.2.0-next.5",
32
+ "@gluwa/credit-connect-hub-node-ws": "0.1.0-next.5"
24
33
  },
25
34
  "devDependencies": {
26
35
  "@tanstack/react-query": "^5.62.0",
@@ -34,20 +43,14 @@
34
43
  "typescript-eslint": "^8.18.2",
35
44
  "viem": "^2.31.7",
36
45
  "wagmi": "^2.15.6",
37
- "@gluwa/credit-connect-sdk": "0.2.0-next.1"
46
+ "@gluwa/credit-connect-sdk": "0.2.0-next.5"
38
47
  },
39
48
  "peerDependencies": {
40
49
  "@tanstack/react-query": ">=5.0.0",
41
- "@wagmi/core": ">=2.0.0",
42
50
  "react": "^18.0.0 || ^19.0.0",
43
- "viem": ">=2.0.0",
44
- "wagmi": ">=2.0.0",
45
- "@gluwa/credit-connect-sdk": "0.2.0-next.1"
51
+ "viem": ">=2.0.0"
46
52
  },
47
53
  "peerDependenciesMeta": {
48
- "@gluwa/credit-connect-sdk": {
49
- "optional": true
50
- },
51
54
  "@tanstack/react-query": {
52
55
  "optional": true
53
56
  }
@@ -9,53 +9,48 @@ import {
9
9
  type FC,
10
10
  type ReactNode,
11
11
  } from 'react';
12
- import { WagmiProvider, useAccount, useDisconnect } from 'wagmi';
13
- import type { Config } from 'wagmi';
12
+ import { WagmiProvider, useAccount, useConfig, useDisconnect, useSwitchChain } from 'wagmi';
13
+ import { getAccount } from '@wagmi/core';
14
14
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
15
- import { ConnectModal } from './ConnectModal';
16
- import type { ConnectErrorContext, ConnectResult, ConnectorId, Connectors } from './types';
15
+ // import { ConnectModal } from './ConnectModal';
16
+ import { ConnectDialog } from './layout/connectDialog';
17
+ import { getConfig, getKitConfig, initConfig } from './core/config';
18
+ import { resolveConnectorId } from './connector-meta';
19
+ import type {
20
+ ConnectErrorContext,
21
+ ConnectBannerSiteKey,
22
+ ConnectKitConfig,
23
+ ConnectKitTheme,
24
+ ConnectResult,
25
+ ConnectorId,
26
+ ConnectorKey,
27
+ Connectors,
28
+ } from './types';
17
29
 
18
- // wagmiConfig prop으로 기존 프로젝트 통합 시 내부에서 사용하는 QueryClient.
19
- // 모듈 레벨에 한 번만 생성 — 연결 플로우용으로만 쓰이므로 공유해도 무방.
20
30
  const internalQueryClient = new QueryClient();
21
31
 
22
32
  export interface ConnectKitProviderProps {
23
33
  children: ReactNode;
34
+ siteKey: ConnectBannerSiteKey;
35
+ connectBannerUrl: string;
36
+ kitConfig?: ConnectKitConfig;
24
37
  connectors: Connectors;
25
- wcProjectId?: string;
26
- /**
27
- * 연결돼 있는 동안 강제할 체인 ID. 다른 체인에 연결돼 있으면
28
- * 자동으로 스위치 모달이 떠서 사용자에게 전환 또는 disconnect를 요구.
29
- */
30
38
  requiredChainId?: number;
31
- /**
32
- * 연결이 정상적으로 끝나고(체인 검증까지 통과) "사용 가능한 상태"가 됐을 때 한 번 호출.
33
- * 재연결(reconnect)에서는 호출되지 않음 — 그쪽은 dApp의 watchAccount 책임.
34
- */
39
+ theme: ConnectKitTheme;
35
40
  onConnect?: (result: ConnectResult) => void;
36
41
  onLog?: (message: string, error?: Error) => void;
37
- /**
38
- * 연결 실패(거절/미설치/기타) 시 모달 안에 표시할 fallback UI를 dApp이 직접 그리고 싶을 때.
39
- * 미제공 시 기본 동작은 selector로 복귀.
40
- */
41
42
  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;
52
43
  }
53
-
54
44
  export interface ConnectKitContextValue {
55
45
  isOpen: boolean;
56
46
  open: () => void;
57
47
  close: () => void;
58
48
  isConnected: boolean;
49
+ needsChainSwitch: boolean;
50
+ requiredChainId: number | undefined;
51
+ currentChainId: number | undefined;
52
+ isSwitchingChain: boolean;
53
+ switchToRequiredChain: () => Promise<void>;
59
54
  address: `0x${string}` | undefined;
60
55
  connectorId: ConnectorId | null;
61
56
  disconnect: () => Promise<void>;
@@ -63,58 +58,82 @@ export interface ConnectKitContextValue {
63
58
 
64
59
  const ConnectKitContext = createContext<ConnectKitContextValue | null>(null);
65
60
 
66
- const resolveConnectorId = (wagmiConnectorId: string | undefined): ConnectorId | null => {
67
- if (!wagmiConnectorId) return null;
68
- if (wagmiConnectorId === 'credit-connect') return 'CREDIT_CONNECT';
69
- if (wagmiConnectorId === 'walletConnect') return 'WALLET_CONNECT';
70
- const lower = wagmiConnectorId.toLowerCase();
71
- if (lower.includes('metamask') || wagmiConnectorId === 'injected') return 'METAMASK';
72
- if (lower.includes('walletconnect')) return 'WALLET_CONNECT';
73
- return null;
61
+ // 외부 API Connectors (ConnectorKey 배열) 내부 ConnectorId[] 매핑.
62
+ // 입력 순서 그대로 selector 표시 순서.
63
+ const CONNECTOR_KEY_TO_ID: Record<ConnectorKey, ConnectorId> = {
64
+ creditWallet: 'CREDIT_CONNECT',
65
+ metamask: 'METAMASK',
66
+ walletConnect: 'WALLET_CONNECT',
67
+ };
68
+ const resolveConnectorsFromConfig = (connectorsConfig?: Connectors): ConnectorId[] => {
69
+ if (!connectorsConfig) return [];
70
+ return connectorsConfig.map((key) => CONNECTOR_KEY_TO_ID[key]);
74
71
  };
75
72
 
76
73
  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} />;
74
+ const wagmiConfig = useMemo(
75
+ () => (props.kitConfig ? initConfig(props.kitConfig) : getConfig()),
76
+ [props.kitConfig],
77
+ );
78
+
79
+ const resolvedKitConfig = props.kitConfig ?? getKitConfig();
80
+
81
+ return (
82
+ <WagmiProvider config={wagmiConfig} reconnectOnMount={false}>
83
+ <QueryClientProvider client={internalQueryClient}>
84
+ <ConnectKitProviderInner {...props} kitConfig={resolvedKitConfig} />
85
+ </QueryClientProvider>
86
+ </WagmiProvider>
87
+ );
88
+ };
89
+
90
+ type ConnectKitProviderInnerProps = Omit<ConnectKitProviderProps, 'kitConfig'> & {
91
+ kitConfig: ConnectKitConfig;
87
92
  };
88
93
 
89
- const ConnectKitProviderInner: FC<ConnectKitProviderProps> = ({
94
+ const ConnectKitProviderInner: FC<ConnectKitProviderInnerProps> = ({
90
95
  children,
96
+ siteKey,
97
+ connectBannerUrl,
91
98
  connectors,
92
- wcProjectId,
99
+ kitConfig,
93
100
  requiredChainId,
101
+ theme,
94
102
  onConnect,
95
103
  onLog,
96
- renderConnectError,
97
104
  }) => {
105
+ // NOTE: renderConnectError 는 ConnectDialog 가 아직 error UI customization 을 받지 않으므로
106
+ // destructure 에서 제외. 추후 ConnectDialog 의 timeout/error content 에 wire 필요 시 복원.
98
107
  const [isOpen, setIsOpen] = useState(false);
99
108
  const [pendingResult, setPendingResult] = useState<ConnectResult | null>(null);
100
109
 
101
110
  const account = useAccount();
111
+ const wagmiConfig = useConfig();
102
112
  const { disconnectAsync } = useDisconnect();
113
+ const { switchChainAsync } = useSwitchChain();
103
114
 
104
- // dApp의 onConnect는 ref로 잡아 effect 재실행 노이즈 차단
105
115
  const onConnectRef = useRef(onConnect);
106
116
  useEffect(() => {
107
117
  onConnectRef.current = onConnect;
108
118
  }, [onConnect]);
109
119
 
110
- // chain mismatch invariant: 연결돼 있지만 요구 체인이 아니면 modal force-open
111
- const chainMismatch =
120
+ const isMountedRef = useRef(true);
121
+ useEffect(() => {
122
+ isMountedRef.current = true;
123
+ return () => {
124
+ isMountedRef.current = false;
125
+ };
126
+ }, []);
127
+
128
+ const needsChainSwitch =
112
129
  requiredChainId != null &&
113
130
  account.status === 'connected' &&
114
131
  account.chainId != null &&
115
132
  account.chainId !== requiredChainId;
116
133
 
117
- const effectiveOpen = isOpen || chainMismatch;
134
+ const [isSwitchingChain, setIsSwitchingChain] = useState(false);
135
+
136
+ const effectiveOpen = isOpen;
118
137
 
119
138
  const open = useCallback((): void => {
120
139
  setIsOpen(true);
@@ -122,34 +141,62 @@ const ConnectKitProviderInner: FC<ConnectKitProviderProps> = ({
122
141
 
123
142
  const close = useCallback((): void => {
124
143
  setIsOpen(false);
125
- }, []);
144
+ const status = getAccount(wagmiConfig).status;
145
+ if (status === 'connecting' || status === 'reconnecting') {
146
+ disconnectAsync().catch(() => undefined);
147
+ }
148
+ }, [wagmiConfig, disconnectAsync]);
126
149
 
127
150
  const disconnect = useCallback(async (): Promise<void> => {
128
151
  await disconnectAsync();
129
152
  }, [disconnectAsync]);
130
153
 
131
- // ConnectModal Provider: 연결 결과를 일단 보류했다가
132
- // chain 검증까지 통과한 후에만 dApp으로 forward
133
- const handleModalConnect = useCallback((result: ConnectResult): void => {
154
+ const switchToRequiredChain = useCallback(async (): Promise<void> => {
155
+ if (requiredChainId == null) return;
156
+ setIsSwitchingChain(true);
157
+ try {
158
+ await switchChainAsync({ chainId: requiredChainId });
159
+ } finally {
160
+ if (isMountedRef.current) setIsSwitchingChain(false);
161
+ }
162
+ }, [requiredChainId, switchChainAsync]);
163
+
164
+ // ConnectDialog 의 wagmi connect 성공 → pendingResult set → 아래 useEffect 가
165
+ // account.status === 'connected' 확인 후 외부 onConnect 호출 + modal close.
166
+ // wagmi state 가 비동기로 'connected' 로 전환되는 race 흡수용.
167
+ const handleDialogConnect = useCallback((result: ConnectResult): void => {
134
168
  setPendingResult(result);
135
169
  }, []);
136
170
 
137
- // pendingResult가 있고, 연결 + chain 매칭이 충족되면 dApp으로 발화
138
- useEffect(() => {
171
+ const handleDialogError = useCallback(
172
+ (error: Error, connectorId: ConnectorId): void => {
173
+ onLog?.(`[connect-kit] connect failed: ${connectorId} — ${error.message}`, error);
174
+ },
175
+ [onLog],
176
+ );
177
+
178
+ // 연결 성공 시 modal 자동 close — wagmi state 만 기준으로.
179
+ // 이전 구현은 pendingResult 가 set 된 경우만 close 했는데, `setPendingResult` 는
180
+ // ConnectDialog 의 onConnect (`connectAsync.then`) 안에서만 호출됨. MM deeplink 같은
181
+ // 시나리오 (앱 이동 → 승인 → 복귀) 에서 wagmi 가 자체적으로 'connected' 로 전이하지만
182
+ // connectAsync 의 promise 는 resolve 안 될 수 있음 → pendingResult set 안 됨 → modal 안 닫힘.
183
+ // 모든 connector (WC/CC/MM) 의 connected 가 일관된 close 트리거가 되도록 단순화.
184
+ useEffect((): void => {
185
+ if (!effectiveOpen) return;
186
+ if (account.status !== 'connected') return;
187
+ setIsOpen(false);
188
+ }, [effectiveOpen, account.status]);
189
+
190
+ // 외부 onConnect 콜백은 best-effort — pendingResult 가 set 된 경우만 호출.
191
+ useEffect((): void => {
139
192
  if (!pendingResult) return;
140
193
  if (account.status !== 'connected') {
141
- // 연결이 끊겼거나 진행 중 — pending 폐기
142
194
  setPendingResult(null);
143
195
  return;
144
196
  }
145
- if (requiredChainId != null && account.chainId !== requiredChainId) {
146
- // chain 아직 안 맞음 — switch 후 다시 평가
147
- return;
148
- }
149
197
  onConnectRef.current?.(pendingResult);
150
198
  setPendingResult(null);
151
- setIsOpen(false);
152
- }, [pendingResult, account.status, account.chainId, requiredChainId]);
199
+ }, [pendingResult, account.status]);
153
200
 
154
201
  const value = useMemo<ConnectKitContextValue>(
155
202
  () => ({
@@ -157,6 +204,11 @@ const ConnectKitProviderInner: FC<ConnectKitProviderProps> = ({
157
204
  open,
158
205
  close,
159
206
  isConnected: account.status === 'connected',
207
+ needsChainSwitch,
208
+ requiredChainId,
209
+ currentChainId: account.chainId,
210
+ isSwitchingChain,
211
+ switchToRequiredChain,
160
212
  address: account.address,
161
213
  connectorId: resolveConnectorId(account.connector?.id),
162
214
  disconnect,
@@ -166,6 +218,11 @@ const ConnectKitProviderInner: FC<ConnectKitProviderProps> = ({
166
218
  open,
167
219
  close,
168
220
  account.status,
221
+ needsChainSwitch,
222
+ requiredChainId,
223
+ account.chainId,
224
+ isSwitchingChain,
225
+ switchToRequiredChain,
169
226
  account.address,
170
227
  account.connector?.id,
171
228
  disconnect,
@@ -175,15 +232,16 @@ const ConnectKitProviderInner: FC<ConnectKitProviderProps> = ({
175
232
  return (
176
233
  <ConnectKitContext.Provider value={value}>
177
234
  {children}
178
- <ConnectModal
235
+ <ConnectDialog
179
236
  open={effectiveOpen}
180
- connectors={connectors}
181
- wcProjectId={wcProjectId}
182
- requiredChainId={requiredChainId}
183
- renderConnectError={renderConnectError}
184
- onConnect={handleModalConnect}
237
+ siteKey={siteKey}
238
+ connectBannerUrl={connectBannerUrl}
239
+ theme={theme}
240
+ connectors={resolveConnectorsFromConfig(connectors)}
241
+ wcProjectId={kitConfig.wcProjectId}
185
242
  onClose={close}
186
- onLog={onLog}
243
+ onConnect={handleDialogConnect}
244
+ onError={handleDialogError}
187
245
  />
188
246
  </ConnectKitContext.Provider>
189
247
  );
@@ -0,0 +1,21 @@
1
+ import {
2
+ getAccount as wagmiGetAccount,
3
+ signMessage as wagmiSignMessage,
4
+ signTypedData as wagmiSignTypedData,
5
+ type GetAccountReturnType,
6
+ type SignMessageParameters,
7
+ type SignTypedDataParameters,
8
+ } from '@wagmi/core';
9
+ import { getConfig } from '../core/config';
10
+
11
+ export const getAccount = (): GetAccountReturnType => {
12
+ return wagmiGetAccount(getConfig());
13
+ };
14
+
15
+ export const signMessage = (params: SignMessageParameters): Promise<`0x${string}`> => {
16
+ return wagmiSignMessage(getConfig(), params);
17
+ };
18
+
19
+ export const signTypedData = (params: SignTypedDataParameters): Promise<`0x${string}`> => {
20
+ return wagmiSignTypedData(getConfig(), params);
21
+ };
@@ -0,0 +1,10 @@
1
+ import {
2
+ watchAsset as wagmiWatchAsset,
3
+ type WatchAssetParameters,
4
+ type WatchAssetReturnType,
5
+ } from '@wagmi/core';
6
+ import { getConfig } from '../core/config';
7
+
8
+ export const watchAsset = (params: WatchAssetParameters): Promise<WatchAssetReturnType> => {
9
+ return wagmiWatchAsset(getConfig(), params);
10
+ };
@@ -0,0 +1,10 @@
1
+ import {
2
+ getBalance as wagmiGetBalance,
3
+ type GetBalanceParameters,
4
+ type GetBalanceReturnType,
5
+ } from '@wagmi/core';
6
+ import { getConfig } from '../core/config';
7
+
8
+ export const getBalance = (params: GetBalanceParameters): Promise<GetBalanceReturnType> => {
9
+ return wagmiGetBalance(getConfig(), params);
10
+ };
@@ -0,0 +1,17 @@
1
+ import {
2
+ switchChain as wagmiSwitchChain,
3
+ getPublicClient as wagmiGetPublicClient,
4
+ type SwitchChainParameters,
5
+ type GetPublicClientParameters,
6
+ type GetPublicClientReturnType,
7
+ } from '@wagmi/core';
8
+ import type { Chain } from 'viem';
9
+ import { getConfig } from '../core/config';
10
+
11
+ export const switchChain = (params: SwitchChainParameters): Promise<Chain> => {
12
+ return wagmiSwitchChain(getConfig(), params);
13
+ };
14
+
15
+ export const getPublicClient = (params?: GetPublicClientParameters): GetPublicClientReturnType => {
16
+ return wagmiGetPublicClient(getConfig(), params);
17
+ };
@@ -0,0 +1,33 @@
1
+ import {
2
+ readContract as wagmiReadContract,
3
+ writeContract as wagmiWriteContract,
4
+ type ReadContractParameters,
5
+ type ReadContractReturnType,
6
+ type WriteContractParameters,
7
+ type WriteContractReturnType,
8
+ type Config,
9
+ } from '@wagmi/core';
10
+ import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem';
11
+ import { getConfig } from '../core/config';
12
+
13
+ export function readContract<
14
+ const abi extends Abi | readonly unknown[],
15
+ functionName extends ContractFunctionName<abi, 'pure' | 'view'>,
16
+ args extends ContractFunctionArgs<abi, 'pure' | 'view', functionName>,
17
+ >(
18
+ parameters: ReadContractParameters<abi, functionName, args, Config>,
19
+ ): Promise<ReadContractReturnType<abi, functionName, args>> {
20
+ return wagmiReadContract(getConfig(), parameters as any) as Promise<
21
+ ReadContractReturnType<abi, functionName, args>
22
+ >;
23
+ }
24
+
25
+ export function writeContract<
26
+ const abi extends Abi | readonly unknown[],
27
+ functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
28
+ args extends ContractFunctionArgs<abi, 'nonpayable' | 'payable', functionName>,
29
+ >(
30
+ parameters: WriteContractParameters<abi, functionName, args, Config>,
31
+ ): Promise<WriteContractReturnType> {
32
+ return wagmiWriteContract(getConfig(), parameters as any);
33
+ }
@@ -0,0 +1,12 @@
1
+ import {
2
+ waitForTransactionReceipt as wagmiWaitForTransactionReceipt,
3
+ type WaitForTransactionReceiptParameters,
4
+ type WaitForTransactionReceiptReturnType,
5
+ } from '@wagmi/core';
6
+ import { getConfig } from '../core/config';
7
+
8
+ export const waitForTransactionReceipt = (
9
+ params: WaitForTransactionReceiptParameters,
10
+ ): Promise<WaitForTransactionReceiptReturnType> => {
11
+ return wagmiWaitForTransactionReceipt(getConfig(), params);
12
+ };
package/src/assets.d.ts CHANGED
@@ -2,3 +2,8 @@ declare module '*.png' {
2
2
  const src: string;
3
3
  export default src;
4
4
  }
5
+
6
+ declare module '*.svg' {
7
+ const src: string;
8
+ export default src;
9
+ }
@@ -0,0 +1,50 @@
1
+ import { type ReactNode, type AnchorHTMLAttributes, type ButtonHTMLAttributes } from 'react';
2
+ import './style.scss';
3
+
4
+ interface ActionItemContent {
5
+ label?: string;
6
+ description?: string;
7
+ action?: string;
8
+ children?: ReactNode;
9
+ }
10
+
11
+ type ActionItemAsAnchor = { as: 'a' } & AnchorHTMLAttributes<HTMLAnchorElement> & ActionItemContent;
12
+ type ActionItemAsButton = { as: 'button' } & ButtonHTMLAttributes<HTMLButtonElement> &
13
+ ActionItemContent;
14
+
15
+ type ActionItemProps = ActionItemAsAnchor | ActionItemAsButton;
16
+
17
+ const ActionItemBody = ({ label, description, action, children }: ActionItemContent): ReactNode => {
18
+ if (children) return <>{children}</>;
19
+ return (
20
+ <>
21
+ <span className="ck-action-item-content">
22
+ <span className="ck-action-item-label">{label}</span>
23
+ {description && <span className="ck-action-item-desc">{description}</span>}
24
+ </span>
25
+ {action && <span className="ck-action-item-action">{action}</span>}
26
+ </>
27
+ );
28
+ };
29
+
30
+ export const ActionItem = (props: ActionItemProps) => {
31
+ if (props.as === 'a') {
32
+ const { as: _, label, description, action, children, className, ...rest } = props;
33
+ return (
34
+ <a className={`ck-action-item${className ? ` ${className}` : ''}`} {...rest}>
35
+ <ActionItemBody label={label} description={description} action={action}>
36
+ {children}
37
+ </ActionItemBody>
38
+ </a>
39
+ );
40
+ }
41
+
42
+ const { as: _, label, description, action, children, className, ...rest } = props;
43
+ return (
44
+ <button className={`ck-action-item${className ? ` ${className}` : ''}`} {...rest}>
45
+ <ActionItemBody label={label} description={description} action={action}>
46
+ {children}
47
+ </ActionItemBody>
48
+ </button>
49
+ );
50
+ };
@@ -0,0 +1,47 @@
1
+ @use '../../style/mixin.scss' as *;
2
+
3
+ .ck-root .ck-action-item {
4
+ display: flex;
5
+ align-items: center;
6
+ gap: 16px;
7
+ width: 100%;
8
+ padding: 16px 20px;
9
+ border-radius: 12px;
10
+ background: var(--scale-gray-100);
11
+ cursor: pointer;
12
+ margin-top: auto;
13
+ flex-shrink: 0;
14
+ text-decoration: none;
15
+ }
16
+
17
+ .ck-action-item-content {
18
+ display: flex;
19
+ flex-direction: column;
20
+ gap: 2px;
21
+ flex: 1;
22
+ min-width: 0;
23
+ }
24
+
25
+ .ck-action-item-label {
26
+ @include textToken('subtitle2-bold');
27
+ color: var(--scale-gray-900);
28
+ }
29
+
30
+ .ck-action-item-desc {
31
+ @include textToken('label5-regular');
32
+ color: var(--scale-gray-600);
33
+ }
34
+
35
+ .ck-action-item-action {
36
+ display: inline-flex;
37
+ align-items: center;
38
+ justify-content: center;
39
+ padding: 0 20px;
40
+ height: 44px;
41
+ border-radius: 6px;
42
+ background: var(--scale-blue2-alpha-100);
43
+ @include textToken('label5-bold');
44
+ color: var(--semantic-brand-trugi-primary);
45
+ white-space: nowrap;
46
+ flex-shrink: 0;
47
+ }
@@ -0,0 +1,16 @@
1
+ import { type FC } from 'react';
2
+ import './style.scss';
3
+ import { CopyIcon } from '../../layout/connectDialog/asset/copyIcon';
4
+
5
+ interface CopyLinkProps {
6
+ onCopy?: () => void;
7
+ }
8
+
9
+ export const CopyLink: FC<CopyLinkProps> = ({ onCopy }) => {
10
+ return (
11
+ <button type="button" className="ck-copy-link" onClick={onCopy}>
12
+ <CopyIcon className="ck-copy-link-icon" />
13
+ Copy link
14
+ </button>
15
+ );
16
+ };