@gluwa/connect-kit 0.1.0-next.2 → 0.2.0-next.1

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/src/index.ts CHANGED
@@ -1,12 +1,21 @@
1
+ import { readContract, writeContract } from './api/contract';
2
+ import { getBalance } from './api/balance';
3
+ import { switchChain, getPublicClient } from './api/chain';
4
+ import { waitForTransactionReceipt } from './api/transaction';
5
+ import { getAccount, signMessage, signTypedData } from './api/account';
6
+ import { watchAccount, watchConnections, reconnect, disconnectAll } from './events/account';
7
+
1
8
  export { ConnectModal } from './ConnectModal';
2
9
  export { ConnectKitProvider, useConnectKit } from './ConnectKitProvider';
3
10
  export type { ConnectKitContextValue, ConnectKitProviderProps } from './ConnectKitProvider';
4
- export { creditConnectConnector } from './creditConnectConnector';
5
- export type { CreditConnectConnectorOptions } from './creditConnectConnector';
11
+
12
+ export { initConfig } from './core/config';
13
+
6
14
  export type {
7
15
  ConnectErrorContext,
8
16
  ConnectErrorReason,
9
17
  ConnectModalProps,
18
+ ConnectKitConfig,
10
19
  Connectors,
11
20
  ConnectResult,
12
21
  ConnectorId,
@@ -14,3 +23,25 @@ export type {
14
23
  WCSubView,
15
24
  WCWallet,
16
25
  } from './types';
26
+
27
+ export const connectKit = {
28
+ api: {
29
+ readContract,
30
+ writeContract,
31
+ getBalance,
32
+ switchChain,
33
+ getPublicClient,
34
+ waitForTransactionReceipt,
35
+ getAccount,
36
+ signMessage,
37
+ signTypedData,
38
+ },
39
+ events: {
40
+ watchAccount,
41
+ watchConnections,
42
+ reconnect,
43
+ disconnectAll,
44
+ },
45
+ } as const;
46
+
47
+ export type * from '@wagmi/core';
package/src/types.ts CHANGED
@@ -1,7 +1,16 @@
1
1
  import type { ReactNode } from 'react';
2
+ import type { Chain, Transport } from 'viem';
3
+ import type { CreateConnectorFn } from 'wagmi';
2
4
 
3
5
  export type ConnectorId = 'CREDIT_WALLET' | 'CREDIT_CONNECT' | 'METAMASK' | 'WALLET_CONNECT';
4
6
 
7
+ export interface ConnectKitConfig {
8
+ chains: [Chain, ...Chain[]];
9
+ transports: Record<number, Transport>;
10
+ wcProjectId?: string;
11
+ extraConnectors?: CreateConnectorFn[];
12
+ }
13
+
5
14
  export type CreditWalletStrategy = 'walletConnect' | 'creditConnect';
6
15
 
7
16
  export interface Connectors {
@@ -1,16 +1,13 @@
1
- // 모바일 기기 감지
2
1
  export const isMobileDevice = (): boolean => {
3
2
  if (typeof window === 'undefined') return false;
4
3
  return /android|iphone|ipad|ipod/i.test(navigator.userAgent);
5
4
  };
6
5
 
7
- // 딥링크 열기 (walletConnect가 지원하는 지갑앱)
8
6
  export const tryOpenDeepLink = (uri: string, deepLinkBase: string): void => {
9
7
  const sep = deepLinkBase.endsWith('/') ? '' : '/';
10
- window.location.href = `${deepLinkBase}${sep}wc?uri=${encodeURIComponent(uri)}`;
8
+ window.location.replace(`${deepLinkBase}${sep}wc?uri=${encodeURIComponent(uri)}`);
11
9
  };
12
10
 
13
- // metaMask extension 감지
14
11
  export const detectMetaMaskExtension = (): boolean =>
15
12
  typeof window !== 'undefined' &&
16
13
  Boolean((window as Window & { ethereum?: { isMetaMask?: boolean } }).ethereum?.isMetaMask);
@@ -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,11 @@ 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
+ const hasRedirectedRef = useRef(false);
15
16
 
16
17
  useEffect(() => {
17
- if (isMobile && qrUri && deepLinkBase) {
18
+ if (isMobile && qrUri && deepLinkBase && !hasRedirectedRef.current) {
19
+ hasRedirectedRef.current = true;
18
20
  tryOpenDeepLink(qrUri, deepLinkBase);
19
21
  }
20
22
  }, [isMobile, qrUri, deepLinkBase]);
@@ -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 { QRFrame, CopyLinkButton } from '../components/QRFrame';
@@ -13,9 +13,11 @@ interface MetaMaskViewProps {
13
13
 
14
14
  export const MetaMaskView: FC<MetaMaskViewProps> = ({ qrUri, hasExtension, logoUrl }) => {
15
15
  const isMobile = useMemo(() => isMobileDevice(), []);
16
+ const hasRedirectedRef = useRef(false);
16
17
 
17
18
  useEffect(() => {
18
- if (isMobile && qrUri && deepLinkBase) {
19
+ if (isMobile && qrUri && deepLinkBase && !hasRedirectedRef.current) {
20
+ hasRedirectedRef.current = true;
19
21
  tryOpenDeepLink(qrUri, deepLinkBase);
20
22
  }
21
23
  }, [isMobile, qrUri]);
@@ -1,4 +1,4 @@
1
- import { useState, type FC } from 'react';
1
+ import { useEffect, useRef, useState, type FC } from 'react';
2
2
  import { useSwitchChain } from 'wagmi';
3
3
 
4
4
  interface SwitchChainViewProps {
@@ -18,6 +18,13 @@ export const SwitchChainView: FC<SwitchChainViewProps> = ({
18
18
  }) => {
19
19
  const { switchChainAsync, isPending } = useSwitchChain();
20
20
  const [error, setError] = useState<Error | null>(null);
21
+ const isMountedRef = useRef(true);
22
+ useEffect(() => {
23
+ isMountedRef.current = true;
24
+ return () => {
25
+ isMountedRef.current = false;
26
+ };
27
+ }, []);
21
28
 
22
29
  const targetLabel = requiredChainName ?? `chain ${requiredChainId}`;
23
30
 
@@ -25,8 +32,6 @@ export const SwitchChainView: FC<SwitchChainViewProps> = ({
25
32
  setError(null);
26
33
  switchChainAsync({ chainId: requiredChainId }).catch((err: unknown) => {
27
34
  const normalized = err instanceof Error ? err : new Error(String(err));
28
- // wagmi's MetaMask connector handles 4902 (chain not added) via wallet_addEthereumChain
29
- // automatically when chain metadata is configured. We only surface what reaches us.
30
35
  const code =
31
36
  typeof err === 'object' && err !== null && 'code' in err
32
37
  ? (err as { code: unknown }).code
@@ -36,7 +41,7 @@ export const SwitchChainView: FC<SwitchChainViewProps> = ({
36
41
  } else {
37
42
  onLog?.(`[connect-kit] switch chain failed: ${normalized.message}`, normalized);
38
43
  }
39
- setError(normalized);
44
+ if (isMountedRef.current) setError(normalized);
40
45
  });
41
46
  };
42
47
 
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: { index: 'src/index.ts' },
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',
@@ -22,7 +26,7 @@ export default defineConfig({
22
26
  banner: {
23
27
  js: 'import React from "react";',
24
28
  },
25
- esbuildPlugins: [sassPlugin({ type: 'style' })],
29
+ esbuildPlugins: [sassPlugin({ type: 'css' })],
26
30
  esbuildOptions(options) {
27
31
  options.loader = { ...options.loader, '.png': 'dataurl' };
28
32
  },