@gluwa/connect-kit 0.2.0-next.9 → 0.2.1-next.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/assets/wc.png +0 -0
  3. package/dist/{chunk-VE5LB7BN.js → chunk-TMKSC7ZT.js} +9 -2
  4. package/dist/credit-connect.js +1 -1
  5. package/dist/index.css +178 -122
  6. package/dist/index.d.ts +96 -26
  7. package/dist/index.js +681 -266
  8. package/dist/package.json +1 -1
  9. package/package.json +6 -6
  10. package/src/ConnectKitProvider.tsx +8 -1
  11. package/src/api/wrappers.ts +361 -0
  12. package/src/components/qrArea/index.tsx +25 -3
  13. package/src/components/qrArea/style.scss +61 -2
  14. package/src/components/toast/index.tsx +41 -0
  15. package/src/components/toast/style.scss +108 -0
  16. package/src/core/config.ts +23 -2
  17. package/src/core/deeplinkSignal.ts +25 -0
  18. package/src/creditConnectConnector.ts +15 -5
  19. package/src/events/account.ts +15 -18
  20. package/src/hooks/useConnectBanner.ts +79 -0
  21. package/src/hooks/useConnectTimeout.ts +21 -9
  22. package/src/hooks/useMetaMaskExtension.ts +2 -1
  23. package/src/hooks/useWCState.ts +7 -2
  24. package/src/hooks/useWagmiConnect.ts +41 -14
  25. package/src/index.ts +29 -24
  26. package/src/layout/allWallets/index.tsx +16 -2
  27. package/src/layout/connectDialog/asset/warningIcon.tsx +21 -0
  28. package/src/layout/connectDialog/idle/assets/banner-placeholder.png +0 -0
  29. package/src/layout/connectDialog/idle/index.tsx +40 -16
  30. package/src/layout/connectDialog/idle/style.scss +42 -51
  31. package/src/layout/connectDialog/index.tsx +174 -37
  32. package/src/layout/connectDialog/metaMask/index.tsx +3 -2
  33. package/src/layout/connectDialog/qr/index.tsx +3 -1
  34. package/src/layout/connectDialog/style.scss +0 -48
  35. package/src/layout/connectDialog/timeout/index.tsx +0 -5
  36. package/src/layout/connectDialog/timeout/style.scss +0 -5
  37. package/src/layout/connectDialog/walletQR/index.tsx +3 -1
  38. package/src/layout/detailPanel/index.tsx +39 -6
  39. package/src/layout/detailPanel/style.scss +2 -1
  40. package/src/layout/selectorPanel/index.tsx +1 -0
  41. package/src/types.ts +20 -0
  42. package/src/utils/platform.ts +7 -0
  43. package/src/api/account.ts +0 -21
  44. package/src/api/asset.ts +0 -10
  45. package/src/api/balance.ts +0 -10
  46. package/src/api/chain.ts +0 -17
  47. package/src/api/contract.ts +0 -33
  48. package/src/api/transaction.ts +0 -12
  49. package/src/components/snackbar/index.tsx +0 -25
  50. package/src/components/snackbar/style.scss +0 -51
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gluwa/connect-kit",
3
- "version": "0.2.0-next.9",
3
+ "version": "0.2.1-next.4",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gluwa/connect-kit",
3
- "version": "0.2.0-next.9",
3
+ "version": "0.2.1-next.4",
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-e2ee-tweetnacl": "0.2.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"
29
+ "@gluwa/credit-connect-storage-local": "0.2.1-next.7",
30
+ "@gluwa/credit-connect-e2ee-tweetnacl": "0.2.1-next.7",
31
+ "@gluwa/credit-connect-sdk": "0.2.1-next.7",
32
+ "@gluwa/credit-connect-hub-node-ws": "0.1.1-next.1"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@tanstack/react-query": "^5.62.0",
@@ -43,7 +43,7 @@
43
43
  "typescript-eslint": "^8.18.2",
44
44
  "viem": "^2.31.7",
45
45
  "wagmi": "^2.15.6",
46
- "@gluwa/credit-connect-sdk": "0.2.0-next.4"
46
+ "@gluwa/credit-connect-sdk": "0.2.1-next.7"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "@tanstack/react-query": ">=5.0.0",
@@ -18,6 +18,7 @@ import { getConfig, getKitConfig, initConfig } from './core/config';
18
18
  import { resolveConnectorId } from './connector-meta';
19
19
  import type {
20
20
  ConnectErrorContext,
21
+ ConnectBannerSiteKey,
21
22
  ConnectKitConfig,
22
23
  ConnectKitTheme,
23
24
  ConnectResult,
@@ -30,6 +31,8 @@ const internalQueryClient = new QueryClient();
30
31
 
31
32
  export interface ConnectKitProviderProps {
32
33
  children: ReactNode;
34
+ siteKey: ConnectBannerSiteKey;
35
+ connectBannerUrl: string;
33
36
  kitConfig?: ConnectKitConfig;
34
37
  connectors: Connectors;
35
38
  requiredChainId?: number;
@@ -90,6 +93,8 @@ type ConnectKitProviderInnerProps = Omit<ConnectKitProviderProps, 'kitConfig'> &
90
93
 
91
94
  const ConnectKitProviderInner: FC<ConnectKitProviderInnerProps> = ({
92
95
  children,
96
+ siteKey,
97
+ connectBannerUrl,
93
98
  connectors,
94
99
  kitConfig,
95
100
  requiredChainId,
@@ -154,7 +159,7 @@ const ConnectKitProviderInner: FC<ConnectKitProviderInnerProps> = ({
154
159
  } finally {
155
160
  if (isMountedRef.current) setIsSwitchingChain(false);
156
161
  }
157
- }, [requiredChainId, switchChainAsync]);
162
+ }, [requiredChainId, switchChainAsync, account.chainId]);
158
163
 
159
164
  // ConnectDialog 의 wagmi connect 성공 → pendingResult set → 아래 useEffect 가
160
165
  // account.status === 'connected' 확인 후 외부 onConnect 호출 + modal close.
@@ -229,6 +234,8 @@ const ConnectKitProviderInner: FC<ConnectKitProviderInnerProps> = ({
229
234
  {children}
230
235
  <ConnectDialog
231
236
  open={effectiveOpen}
237
+ siteKey={siteKey}
238
+ connectBannerUrl={connectBannerUrl}
232
239
  theme={theme}
233
240
  connectors={resolveConnectorsFromConfig(connectors)}
234
241
  wcProjectId={kitConfig.wcProjectId}
@@ -0,0 +1,361 @@
1
+ import * as w from '@wagmi/core/actions';
2
+ import type {
3
+ Abi,
4
+ BlockTag,
5
+ ContractEventName,
6
+ ContractFunctionArgs,
7
+ ContractFunctionName,
8
+ ContractFunctionParameters,
9
+ FeeValuesType,
10
+ TypedData,
11
+ PrepareTransactionRequestRequest as ViemPrepareTransactionRequestRequest,
12
+ } from 'viem';
13
+ import type {
14
+ Config,
15
+ ConnectParameters,
16
+ ConnectReturnType,
17
+ Connector,
18
+ CreateConnectorFn,
19
+ DeployContractParameters,
20
+ DeployContractReturnType,
21
+ EstimateFeesPerGasParameters,
22
+ EstimateFeesPerGasReturnType,
23
+ EstimateGasParameters,
24
+ EstimateGasReturnType,
25
+ EstimateMaxPriorityFeePerGasParameters,
26
+ EstimateMaxPriorityFeePerGasReturnType,
27
+ GetBlockNumberParameters,
28
+ GetBlockNumberReturnType,
29
+ GetBlockParameters,
30
+ GetBlockReturnType,
31
+ GetBlockTransactionCountParameters,
32
+ GetBlockTransactionCountReturnType,
33
+ GetCapabilitiesParameters,
34
+ GetCapabilitiesReturnType,
35
+ GetClientParameters,
36
+ GetClientReturnType,
37
+ GetConnectorClientParameters,
38
+ GetConnectorClientReturnType,
39
+ GetFeeHistoryParameters,
40
+ GetFeeHistoryReturnType,
41
+ GetGasPriceParameters,
42
+ GetGasPriceReturnType,
43
+ GetPublicClientParameters,
44
+ GetPublicClientReturnType,
45
+ GetTransactionConfirmationsParameters,
46
+ GetTransactionConfirmationsReturnType,
47
+ GetTransactionParameters,
48
+ GetTransactionReceiptParameters,
49
+ GetTransactionReceiptReturnType,
50
+ GetTransactionReturnType,
51
+ GetWalletClientParameters,
52
+ GetWalletClientReturnType,
53
+ MulticallParameters,
54
+ MulticallReturnType,
55
+ PrepareTransactionRequestParameters,
56
+ PrepareTransactionRequestReturnType,
57
+ ReadContractParameters,
58
+ ReadContractReturnType,
59
+ ReadContractsParameters,
60
+ ReadContractsReturnType,
61
+ SelectChains,
62
+ SendCallsParameters,
63
+ SendCallsReturnType,
64
+ SendTransactionParameters,
65
+ SendTransactionReturnType,
66
+ SignTypedDataParameters,
67
+ SignTypedDataReturnType,
68
+ SimulateContractParameters,
69
+ SimulateContractReturnType,
70
+ SwitchChainParameters,
71
+ SwitchChainReturnType,
72
+ VerifyTypedDataParameters,
73
+ VerifyTypedDataReturnType,
74
+ WaitForTransactionReceiptParameters,
75
+ WaitForTransactionReceiptReturnType,
76
+ WatchBlockNumberParameters,
77
+ WatchBlockNumberReturnType,
78
+ WatchBlocksParameters,
79
+ WatchBlocksReturnType,
80
+ WatchClientParameters,
81
+ WatchClientReturnType,
82
+ WatchContractEventParameters,
83
+ WatchPendingTransactionsParameters,
84
+ WatchPublicClientParameters,
85
+ WatchPublicClientReturnType,
86
+ WriteContractParameters,
87
+ WriteContractReturnType,
88
+ } from '@wagmi/core';
89
+ import { getConfig } from '../core/config';
90
+
91
+ export function connect<
92
+ connector extends Connector | CreateConnectorFn,
93
+ withCapabilities extends boolean = false,
94
+ >(
95
+ parameters: ConnectParameters<Config, connector, withCapabilities>,
96
+ ): Promise<ConnectReturnType<Config, connector, withCapabilities>> {
97
+ return w.connect(getConfig(), parameters as never) as never;
98
+ }
99
+
100
+ export function deployContract<
101
+ const abi extends Abi | readonly unknown[],
102
+ chainId extends Config['chains'][number]['id'],
103
+ >(parameters: DeployContractParameters<abi, Config, chainId>): Promise<DeployContractReturnType> {
104
+ return w.deployContract(getConfig(), parameters as never) as never;
105
+ }
106
+
107
+ export function estimateFeesPerGas<type extends FeeValuesType = 'eip1559'>(
108
+ parameters?: EstimateFeesPerGasParameters<type, Config>,
109
+ ): Promise<EstimateFeesPerGasReturnType<type>> {
110
+ return w.estimateFeesPerGas(getConfig(), parameters as never) as never;
111
+ }
112
+
113
+ export function estimateGas<chainId extends Config['chains'][number]['id'] | undefined = undefined>(
114
+ parameters: EstimateGasParameters<Config, chainId>,
115
+ ): Promise<EstimateGasReturnType> {
116
+ return w.estimateGas(getConfig(), parameters as never) as never;
117
+ }
118
+
119
+ export function estimateMaxPriorityFeePerGas<
120
+ chainId extends Config['chains'][number]['id'] = Config['chains'][number]['id'],
121
+ >(
122
+ parameters?: EstimateMaxPriorityFeePerGasParameters<Config, chainId>,
123
+ ): Promise<EstimateMaxPriorityFeePerGasReturnType> {
124
+ return w.estimateMaxPriorityFeePerGas(getConfig(), parameters as never) as never;
125
+ }
126
+
127
+ export function getBlock<
128
+ chainId extends Config['chains'][number]['id'],
129
+ includeTransactions extends boolean = false,
130
+ blockTag extends BlockTag = 'latest',
131
+ >(
132
+ parameters?: GetBlockParameters<includeTransactions, blockTag, Config, chainId>,
133
+ ): Promise<GetBlockReturnType<includeTransactions, blockTag, Config, chainId>> {
134
+ return w.getBlock(getConfig(), parameters as never) as never;
135
+ }
136
+
137
+ export function getBlockNumber<
138
+ chainId extends Config['chains'][number]['id'] = Config['chains'][number]['id'],
139
+ >(parameters?: GetBlockNumberParameters<Config, chainId>): Promise<GetBlockNumberReturnType> {
140
+ return w.getBlockNumber(getConfig(), parameters as never) as never;
141
+ }
142
+
143
+ export function getBlockTransactionCount<
144
+ chainId extends Config['chains'][number]['id'] = Config['chains'][number]['id'],
145
+ >(
146
+ parameters?: GetBlockTransactionCountParameters<Config, chainId>,
147
+ ): Promise<GetBlockTransactionCountReturnType> {
148
+ return w.getBlockTransactionCount(getConfig(), parameters as never) as never;
149
+ }
150
+
151
+ export function getCapabilities<
152
+ chainId extends Config['chains'][number]['id'] | undefined = undefined,
153
+ >(
154
+ parameters?: GetCapabilitiesParameters<Config, chainId>,
155
+ ): Promise<GetCapabilitiesReturnType<Config, chainId>> {
156
+ return w.getCapabilities(getConfig(), parameters as never) as never;
157
+ }
158
+
159
+ export function getClient<chainId extends Config['chains'][number]['id'] | number | undefined>(
160
+ parameters?: GetClientParameters<Config, chainId>,
161
+ ): GetClientReturnType<Config, chainId> {
162
+ return w.getClient(getConfig(), parameters as never) as never;
163
+ }
164
+
165
+ export function getConnectorClient<chainId extends Config['chains'][number]['id']>(
166
+ parameters?: GetConnectorClientParameters<Config, chainId>,
167
+ ): Promise<GetConnectorClientReturnType<Config, chainId>> {
168
+ return w.getConnectorClient(getConfig(), parameters as never) as never;
169
+ }
170
+
171
+ export function getFeeHistory<
172
+ chainId extends Config['chains'][number]['id'] = Config['chains'][number]['id'],
173
+ >(parameters: GetFeeHistoryParameters<Config, chainId>): Promise<GetFeeHistoryReturnType> {
174
+ return w.getFeeHistory(getConfig(), parameters as never) as never;
175
+ }
176
+
177
+ export function getGasPrice<
178
+ chainId extends Config['chains'][number]['id'] = Config['chains'][number]['id'],
179
+ >(parameters?: GetGasPriceParameters<Config, chainId>): Promise<GetGasPriceReturnType> {
180
+ return w.getGasPrice(getConfig(), parameters as never) as never;
181
+ }
182
+
183
+ export function getPublicClient<
184
+ chainId extends Config['chains'][number]['id'] | number | undefined,
185
+ >(
186
+ parameters?: GetPublicClientParameters<Config, chainId>,
187
+ ): GetPublicClientReturnType<Config, chainId> {
188
+ return w.getPublicClient(getConfig(), parameters as never) as never;
189
+ }
190
+
191
+ export function getTransaction<chainId extends Config['chains'][number]['id']>(
192
+ parameters: GetTransactionParameters<Config, chainId>,
193
+ ): Promise<GetTransactionReturnType<Config, chainId>> {
194
+ return w.getTransaction(getConfig(), parameters as never) as never;
195
+ }
196
+
197
+ export function getTransactionConfirmations<
198
+ chainId extends Config['chains'][number]['id'] | undefined = Config['chains'][number]['id'],
199
+ >(
200
+ parameters: GetTransactionConfirmationsParameters<Config, chainId>,
201
+ ): Promise<GetTransactionConfirmationsReturnType> {
202
+ return w.getTransactionConfirmations(getConfig(), parameters as never) as never;
203
+ }
204
+
205
+ export function getTransactionReceipt<chainId extends Config['chains'][number]['id']>(
206
+ parameters: GetTransactionReceiptParameters<Config>,
207
+ ): Promise<GetTransactionReceiptReturnType<Config, chainId>> {
208
+ return w.getTransactionReceipt(getConfig(), parameters as never) as never;
209
+ }
210
+
211
+ export function getWalletClient<chainId extends Config['chains'][number]['id']>(
212
+ parameters?: GetWalletClientParameters<Config, chainId>,
213
+ ): Promise<GetWalletClientReturnType<Config, chainId>> {
214
+ return w.getWalletClient(getConfig(), parameters as never) as never;
215
+ }
216
+
217
+ export function multicall<
218
+ const contracts extends readonly ContractFunctionParameters[],
219
+ allowFailure extends boolean = true,
220
+ >(
221
+ parameters: MulticallParameters<contracts, allowFailure, Config>,
222
+ ): Promise<MulticallReturnType<contracts, allowFailure>> {
223
+ return w.multicall(getConfig(), parameters as never) as never;
224
+ }
225
+
226
+ export function prepareTransactionRequest<
227
+ chainId extends Config['chains'][number]['id'] | undefined,
228
+ const request extends ViemPrepareTransactionRequestRequest<
229
+ SelectChains<Config, chainId>['0'],
230
+ SelectChains<Config, chainId>['0']
231
+ >,
232
+ >(
233
+ parameters: PrepareTransactionRequestParameters<Config, chainId, request>,
234
+ ): Promise<PrepareTransactionRequestReturnType<Config, chainId, request>> {
235
+ return w.prepareTransactionRequest(getConfig(), parameters as never) as never;
236
+ }
237
+
238
+ export function readContract<
239
+ const abi extends Abi | readonly unknown[],
240
+ functionName extends ContractFunctionName<abi, 'pure' | 'view'>,
241
+ args extends ContractFunctionArgs<abi, 'pure' | 'view', functionName>,
242
+ >(
243
+ parameters: ReadContractParameters<abi, functionName, args, Config>,
244
+ ): Promise<ReadContractReturnType<abi, functionName, args>> {
245
+ return w.readContract(getConfig(), parameters as never) as never;
246
+ }
247
+
248
+ export function readContracts<
249
+ const contracts extends readonly ContractFunctionParameters[],
250
+ allowFailure extends boolean = true,
251
+ >(
252
+ parameters: ReadContractsParameters<contracts, allowFailure, Config>,
253
+ ): Promise<ReadContractsReturnType<contracts, allowFailure>> {
254
+ return w.readContracts(getConfig(), parameters as never) as never;
255
+ }
256
+
257
+ export function sendCalls<
258
+ const calls extends readonly unknown[],
259
+ chainId extends Config['chains'][number]['id'],
260
+ >(parameters: SendCallsParameters<Config, chainId, calls>): Promise<SendCallsReturnType> {
261
+ return w.sendCalls(getConfig(), parameters as never) as never;
262
+ }
263
+
264
+ export function sendTransaction<chainId extends Config['chains'][number]['id']>(
265
+ parameters: SendTransactionParameters<Config, chainId>,
266
+ ): Promise<SendTransactionReturnType> {
267
+ return w.sendTransaction(getConfig(), parameters as never) as never;
268
+ }
269
+
270
+ export function signTypedData<
271
+ const typedData extends TypedData | Record<string, unknown>,
272
+ primaryType extends keyof typedData | 'EIP712Domain',
273
+ >(parameters: SignTypedDataParameters<typedData, primaryType>): Promise<SignTypedDataReturnType> {
274
+ return w.signTypedData(getConfig(), parameters as never) as never;
275
+ }
276
+
277
+ export function simulateContract<
278
+ const abi extends Abi | readonly unknown[],
279
+ functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
280
+ args extends ContractFunctionArgs<abi, 'nonpayable' | 'payable', functionName>,
281
+ chainId extends Config['chains'][number]['id'] | undefined = undefined,
282
+ >(
283
+ parameters: SimulateContractParameters<abi, functionName, args, Config, chainId>,
284
+ ): Promise<SimulateContractReturnType<abi, functionName, args, Config, chainId>> {
285
+ return w.simulateContract(getConfig(), parameters as never) as never;
286
+ }
287
+
288
+ export function switchChain<chainId extends Config['chains'][number]['id']>(
289
+ parameters: SwitchChainParameters<Config, chainId>,
290
+ ): Promise<SwitchChainReturnType<Config, chainId>> {
291
+ return w.switchChain(getConfig(), parameters as never) as never;
292
+ }
293
+
294
+ export function verifyTypedData<
295
+ const typedData extends TypedData | Record<string, unknown>,
296
+ primaryType extends keyof typedData | 'EIP712Domain',
297
+ >(
298
+ parameters: VerifyTypedDataParameters<typedData, primaryType, Config>,
299
+ ): Promise<VerifyTypedDataReturnType> {
300
+ return w.verifyTypedData(getConfig(), parameters as never) as never;
301
+ }
302
+
303
+ export function waitForTransactionReceipt<chainId extends Config['chains'][number]['id']>(
304
+ parameters: WaitForTransactionReceiptParameters<Config, chainId>,
305
+ ): Promise<WaitForTransactionReceiptReturnType<Config, chainId>> {
306
+ return w.waitForTransactionReceipt(getConfig(), parameters as never) as never;
307
+ }
308
+
309
+ export function watchBlockNumber<
310
+ chainId extends Config['chains'][number]['id'] = Config['chains'][number]['id'],
311
+ >(parameters: WatchBlockNumberParameters<Config, chainId>): WatchBlockNumberReturnType {
312
+ return w.watchBlockNumber(getConfig(), parameters as never) as never;
313
+ }
314
+
315
+ export function watchBlocks<
316
+ chainId extends Config['chains'][number]['id'] = Config['chains'][number]['id'],
317
+ includeTransactions extends boolean = false,
318
+ blockTag extends BlockTag = 'latest',
319
+ >(
320
+ parameters: WatchBlocksParameters<includeTransactions, blockTag, Config, chainId>,
321
+ ): WatchBlocksReturnType {
322
+ return w.watchBlocks(getConfig(), parameters as never) as never;
323
+ }
324
+
325
+ export function watchClient<chainId extends Config['chains'][number]['id']>(
326
+ parameters: WatchClientParameters<Config, chainId>,
327
+ ): WatchClientReturnType {
328
+ return w.watchClient(getConfig(), parameters as never) as never;
329
+ }
330
+
331
+ export function watchContractEvent<
332
+ chainId extends Config['chains'][number]['id'],
333
+ const abi extends Abi | readonly unknown[],
334
+ eventName extends ContractEventName<abi> | undefined,
335
+ strict extends boolean | undefined = undefined,
336
+ >(parameters: WatchContractEventParameters<abi, eventName, strict, Config, chainId>): () => void {
337
+ return w.watchContractEvent(getConfig(), parameters as never) as never;
338
+ }
339
+
340
+ export function watchPendingTransactions<chainId extends Config['chains'][number]['id']>(
341
+ parameters: WatchPendingTransactionsParameters<Config, chainId>,
342
+ ): () => void {
343
+ return w.watchPendingTransactions(getConfig(), parameters as never) as never;
344
+ }
345
+
346
+ export function watchPublicClient<chainId extends Config['chains'][number]['id']>(
347
+ parameters: WatchPublicClientParameters<Config, chainId>,
348
+ ): WatchPublicClientReturnType {
349
+ return w.watchPublicClient(getConfig(), parameters as never) as never;
350
+ }
351
+
352
+ export function writeContract<
353
+ const abi extends Abi | readonly unknown[],
354
+ functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
355
+ args extends ContractFunctionArgs<abi, 'nonpayable' | 'payable', functionName>,
356
+ chainId extends Config['chains'][number]['id'],
357
+ >(
358
+ parameters: WriteContractParameters<abi, functionName, args, Config, chainId>,
359
+ ): Promise<WriteContractReturnType> {
360
+ return w.writeContract(getConfig(), parameters as never) as never;
361
+ }
@@ -12,13 +12,22 @@ interface QrAreaProps {
12
12
  hasBg?: boolean;
13
13
  label?: string;
14
14
  onCopy?: () => void;
15
+ onOpenApp?: () => void;
15
16
  }
16
17
 
17
18
  const BG_COLOR = '#ffffff';
18
19
  const FG_COLOR = '#000000';
19
20
  const FG_GRADIENT = 'url(#ck-qr-gradient)';
20
21
 
21
- export const QrArea: FC<QrAreaProps> = ({ uri, status, logoUrl, hasBg = false, label, onCopy }) => {
22
+ export const QrArea: FC<QrAreaProps> = ({
23
+ uri,
24
+ status,
25
+ logoUrl,
26
+ hasBg = false,
27
+ label,
28
+ onCopy,
29
+ onOpenApp,
30
+ }) => {
22
31
  const bgColor = hasBg ? BG_COLOR : 'transparent';
23
32
  const fgColor = hasBg ? FG_COLOR : FG_GRADIENT;
24
33
 
@@ -60,10 +69,23 @@ export const QrArea: FC<QrAreaProps> = ({ uri, status, logoUrl, hasBg = false, l
60
69
  </div>
61
70
  )}
62
71
  </figure>
63
- {(label || onCopy) && (
72
+ {(label || onCopy || onOpenApp) && (
64
73
  <div className="ck-qr-text">
65
74
  {label && <p className="ck-qr-label">{label}</p>}
66
- {onCopy && <CopyLink onCopy={onCopy} />}
75
+ {onOpenApp &&
76
+ (status === 'loading' ? (
77
+ <span className="ck-qr-open-app-skeleton" aria-hidden="true" />
78
+ ) : (
79
+ <button type="button" className="ck-qr-open-app" onClick={onOpenApp}>
80
+ Open app
81
+ </button>
82
+ ))}
83
+ {onCopy &&
84
+ (status === 'loading' ? (
85
+ <span className="ck-qr-copy-skeleton" aria-hidden="true" />
86
+ ) : (
87
+ <CopyLink onCopy={onCopy} />
88
+ ))}
67
89
  </div>
68
90
  )}
69
91
  </div>
@@ -2,11 +2,11 @@
2
2
 
3
3
  .ck-qr-area {
4
4
  display: flex;
5
+ flex-direction: column;
5
6
  align-items: center;
6
- justify-content: center;
7
7
  flex: 1;
8
8
  width: 100%;
9
- padding-bottom: 32px;
9
+ padding: 32px 0;
10
10
  }
11
11
 
12
12
  // ── Text ──────────────────────────────────────────────────────────────────────
@@ -17,6 +17,10 @@
17
17
  gap: 6px;
18
18
  width: 100%;
19
19
  margin-top: 24px;
20
+
21
+ @include tablet {
22
+ gap: 12px;
23
+ }
20
24
  }
21
25
 
22
26
  .ck-qr-label {
@@ -25,6 +29,46 @@
25
29
  text-align: center;
26
30
  }
27
31
 
32
+ .ck-root .ck-qr-open-app {
33
+ display: none;
34
+ align-items: center;
35
+ justify-content: center;
36
+ padding: 12px 28px;
37
+ border: 1px solid var(--semantic-divider-divider-4);
38
+ border-radius: 500px;
39
+ @include textToken('label4-bold');
40
+ color: var(--scale-gray-900);
41
+ cursor: pointer;
42
+ transition: background 0.15s ease;
43
+
44
+ @include tablet {
45
+ display: inline-flex;
46
+ }
47
+
48
+ &:hover {
49
+ background: var(--scale-gray-100);
50
+ }
51
+ }
52
+
53
+ .ck-qr-open-app-skeleton {
54
+ display: none;
55
+ width: 116px;
56
+ height: 44px;
57
+ border-radius: 500px;
58
+ background: linear-gradient(
59
+ 132deg,
60
+ var(--scale-gray-100) 36%,
61
+ var(--scale-gray-200) 51%,
62
+ var(--scale-gray-100) 66%
63
+ );
64
+ background-size: 200% 100%;
65
+ animation: ck-qr-shimmer 1.5s linear infinite;
66
+
67
+ @include tablet {
68
+ display: block;
69
+ }
70
+ }
71
+
28
72
  .ck-qr {
29
73
  display: flex;
30
74
  flex-direction: column;
@@ -76,6 +120,21 @@
76
120
  }
77
121
  }
78
122
 
123
+ .ck-qr-copy-skeleton {
124
+ display: block;
125
+ width: 84px;
126
+ height: 20px;
127
+ border-radius: 4px;
128
+ background: linear-gradient(
129
+ 132deg,
130
+ var(--scale-gray-100) 36%,
131
+ var(--scale-gray-200) 51%,
132
+ var(--scale-gray-100) 66%
133
+ );
134
+ background-size: 200% 100%;
135
+ animation: ck-qr-shimmer 1.5s linear infinite;
136
+ }
137
+
79
138
  @keyframes ck-qr-shimmer {
80
139
  0% { background-position: 200% 0; }
81
140
  100% { background-position: -200% 0; }
@@ -0,0 +1,41 @@
1
+ import { type FC, useEffect } from 'react';
2
+ import './style.scss';
3
+ import { CloseIcon } from '../../layout/connectDialog/asset/closeIcon';
4
+ import { CheckIcon } from '../../layout/connectDialog/asset/checkIcon';
5
+ import { WarningIcon } from '../../layout/connectDialog/asset/warningIcon';
6
+
7
+ export type ToastVariant = 'success' | 'warning';
8
+
9
+ const AUTO_CLOSE_MS = 3000;
10
+
11
+ interface ToastProps {
12
+ message: string;
13
+ variant?: ToastVariant;
14
+ onClose?: () => void;
15
+ }
16
+
17
+ export const Toast: FC<ToastProps> = ({ message, variant = 'success', onClose }) => {
18
+ useEffect(() => {
19
+ if (!onClose) return;
20
+ const timer = setTimeout(onClose, AUTO_CLOSE_MS);
21
+ return () => clearTimeout(timer);
22
+ }, [variant, onClose, message]);
23
+
24
+ return (
25
+ <div className="ck-toast" data-variant={variant} role="status" aria-live="polite">
26
+ <div className="ck-toast-content">
27
+ {variant === 'warning' ? (
28
+ <WarningIcon className="ck-toast-icon ck-toast-icon--warning" />
29
+ ) : (
30
+ <CheckIcon className="ck-toast-icon ck-toast-icon--success" />
31
+ )}
32
+ <p className="ck-toast-message">{message}</p>
33
+ </div>
34
+ {onClose && (
35
+ <button type="button" className="ck-toast-close" onClick={onClose} aria-label="Close">
36
+ <CloseIcon width={20} height={20} />
37
+ </button>
38
+ )}
39
+ </div>
40
+ );
41
+ };