Skip to content

Commit

Permalink
feat: Use behavior configuration to control different connection beha…
Browse files Browse the repository at this point in the history
…viors on different platform
  • Loading branch information
wenty22 committed Jan 9, 2025
1 parent fcb224c commit b6cbb8d
Show file tree
Hide file tree
Showing 46 changed files with 827 additions and 737 deletions.
5 changes: 5 additions & 0 deletions .changeset/cuddly-dragons-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@node-real/walletkit': minor
---

Use behavior configuration to control different connection behaviors on different platform
59 changes: 52 additions & 7 deletions examples/nextjs/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,20 @@ import '@node-real/walletkit/styles.css';
import '@/styles/globals.css';
import { mainnet } from 'wagmi/chains';

import { trustWallet, metaMask, walletConnect, defaultEvmConfig } from '@node-real/walletkit/evm';
import {
trustWallet,
metaMask,
walletConnect,
defaultEvmConfig,
binanceWallet,
bitgetWallet,
codexFieldWallet,
coinbaseWallet,
mathWallet,
okxWallet,
tokenPocket,
uxuyWallet,
} from '@node-real/walletkit/evm';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import {
WalletKitProvider,
Expand All @@ -11,7 +24,8 @@ import {
WalletKitConfig,
} from '@node-real/walletkit';
import { AppProps } from 'next/app';
import { useAccount, useDisconnect } from 'wagmi';
import { useAccount, useDisconnect, useSignMessage } from 'wagmi';
import { useState } from 'react';

const queryClient = new QueryClient();

Expand All @@ -23,7 +37,22 @@ const config: WalletKitConfig = {
autoConnect: true,
initialChainId: 1,
walletConnectProjectId: '518ee55b46bc23b5b496b03b1322aa13',
wallets: [metaMask(), trustWallet(), walletConnect()],
wallets: [
binanceWallet(),
trustWallet(),
walletConnect(),
uxuyWallet(),
codexFieldWallet(),
metaMask(),

bitgetWallet(),
coinbaseWallet(),

tokenPocket(),
okxWallet(),

mathWallet(),
],
chains: [mainnet],
}),
};
Expand All @@ -42,15 +71,31 @@ export default function App({ Component, pageProps }: AppProps) {

function ConnectButton() {
const { onOpen } = useConnectModal();
const [signResult, setSignResult] = useState('');

const { address, isConnected } = useAccount();
const { address } = useAccount();
const { disconnect } = useDisconnect();
const { signMessageAsync } = useSignMessage();

if (isConnected) {
if (address) {
return (
<>
<div>address:{address}</div>
<button onClick={() => disconnect()}>disconnect</button>
<div>
<button onClick={() => disconnect()}>disconnect</button>
<div>address:{address}</div>
</div>
<div>
<button
onClick={async () => {
const res = await signMessageAsync({ message: 'hello world' });
setSignResult(res);
}}
>
sign
</button>

<div>signed message:{signResult}</div>
</div>
</>
);
}
Expand Down
23 changes: 20 additions & 3 deletions examples/vite/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
} from '@node-real/walletkit/evm';
import { mainnet } from 'viem/chains';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useAccount, useDisconnect } from 'wagmi';
import { useAccount, useDisconnect, useSignMessage } from 'wagmi';
import { useState } from 'react';

const queryClient = new QueryClient();

Expand Down Expand Up @@ -44,15 +45,31 @@ export default function App() {

function ConnectButton() {
const { onOpen } = useConnectModal();
const [signResult, setSignResult] = useState('');

const { address } = useAccount();
const { disconnect } = useDisconnect();
const { signMessageAsync } = useSignMessage();

if (address) {
return (
<>
<div>address:{address}</div>
<button onClick={() => disconnect()}>disconnect</button>
<div>
<button onClick={() => disconnect()}>disconnect</button>
<div>address:{address}</div>
</div>
<div>
<button
onClick={async () => {
const res = await signMessageAsync({ message: 'hello world' });
setSignResult(res);
}}
>
sign
</button>

<div>signed message:{signResult}</div>
</div>
</>
);
}
Expand Down
43 changes: 1 addition & 42 deletions packages/walletkit/__dev__/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import './style.css';
import {
ConnectModal,
isMobile,
useConnectModal,
WalletKitConfig,
WalletKitProvider,
} from '@/core/index';
import { ConnectModal, useConnectModal, WalletKitConfig, WalletKitProvider } from '@/core/index';
import VConsole from 'vconsole';
import {
binanceWallet,
Expand Down Expand Up @@ -93,41 +87,6 @@ export default function App() {
);
}

export const getIsAndroid = () => {
const ua = navigator.userAgent;
const android = Boolean(ua.match(/Android/i));
return android;
};

export const getHref = (isAndroid: boolean, wc?: string) => {
const appID = 'xoqXxUSMRccLCrZNRebmzj';
const startPagePath = 'L3BhZ2VzL2Rhc2hib2FyZC1uZXcvaW5kZXg=';

let qs = `appId=${appID}&startPagePath=${startPagePath}`;
if (wc) {
const startPageQuery = encodeURI(
`wc=${encodeURIComponent(wc)}&isDeepLink=true&id=${+new Date()}`,
);
qs = `${qs}&startPageQuery=${startPageQuery}`;
}
const host = '//app.binance.com';
if (isAndroid) {
return `bnc:${host}/mp/app?${qs}`;
}
return `https:${host}/?_dp=${encodeURI(`/mp/app?${qs}`)}`;
};

export const openBinanceDeepLink = (wc?: string) => {
const href = getHref(true, wc);
if (!isMobile()) return;

const a = document.createElement('a');
a.href = href;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};

function ConnectButton() {
const { onOpen } = useConnectModal();

Expand Down
17 changes: 13 additions & 4 deletions packages/walletkit/src/core/configs/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ColorMode } from '@/core/providers/ThemeProvider/context';

export type WalletType = 'evm' | 'solana' | 'tron';

export type PlatformType =
| 'tg-android'
| 'tg-ios'
Expand All @@ -9,6 +10,16 @@ export type PlatformType =
| 'browser-ios'
| 'browser-pc';

export type ConnectType = 'default' | 'sdk' | 'uri' | 'qrcode' | 'walletConnect';

export interface BaseBehavior {
platforms: PlatformType[];
connectType: ConnectType;
isInstalled?: () => boolean | undefined;
getAppLink?: () => string | undefined;
getUri?: (uri: string) => string | undefined;
}

export interface WalletConfig {
name: string;
logos: {
Expand All @@ -21,15 +32,13 @@ export interface WalletConfig {
spinnerColor?: string;
}

export interface BaseWallet extends WalletConfig {
export interface BaseWallet<T extends BaseBehavior = BaseBehavior> extends WalletConfig {
id: string;
walletType: WalletType;
isDisabled?: boolean;
isVisible?: boolean;
render?: (props: WalletRenderProps) => React.ReactNode;
showQRCode?: boolean;
isInstalled: () => boolean | undefined;
platforms: PlatformType[];
behaviors: T[];
}

export interface WalletRenderProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,19 @@ import { GridLayout } from './GridLayout';
import { ListLayout } from './ListLayout';
import { clsDisclaimer } from './styles.css';
import { useWalletKit } from '@/core/providers/WalletKitProvider/context';
import { isAndroid, isBrowser, isIOS, isPC, isTMA } from '@/core/base/utils/mobile';
import { useMemo } from 'react';
import { getPlatform } from '@/core/utils/common';

export function HomeView() {
const { wallets, options } = useWalletKit();
const { isMobileLayout } = useResponsive();

const visibleWallets = useMemo(() => {
const platform = getPlatform();
const visibleWallets = wallets.filter((wallet) => {
const isVisible =
wallet.isVisible !== false &&
((isBrowser() && isAndroid() && wallet.platforms.includes('browser-android')) ||
(isBrowser() && isIOS() && wallet.platforms.includes('browser-ios')) ||
(isBrowser() && isPC() && wallet.platforms.includes('browser-pc')) ||
(isTMA() && isAndroid() && wallet.platforms.includes('tg-android')) ||
(isTMA() && isIOS() && wallet.platforms.includes('tg-ios')) ||
(isTMA() && isPC() && wallet.platforms.includes('tg-pc')));
!!wallet.behaviors.find((e) => e.platforms.includes(platform));
return isVisible;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export function ThemeProvider(props: ThemeProviderProps) {

return (
<ThemeContext.Provider value={value}>
<style>{styleContent}</style>
<style suppressHydrationWarning>{styleContent}</style>
{children}
</ThemeContext.Provider>
);
Expand Down
28 changes: 27 additions & 1 deletion packages/walletkit/src/core/utils/common.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isTMA } from '../base/utils/mobile';
import { isAndroid, isIOS, isPC, isTMA } from '../base/utils/mobile';
import { PlatformType } from '../configs/types';

export function mergeList(list1: any[] = [], list2: any[] = []) {
const result: any[] = [...list1];
Expand Down Expand Up @@ -34,3 +35,28 @@ export async function openLink(uri?: string, target = '_self') {
const finalTarget = isTMA() ? '_blank' : target;
window.open(uri, finalTarget, 'noopener noreferrer');
}

export function getPlatform(): PlatformType {
if (isTMA()) {
if (isPC()) {
return 'tg-pc';
}
if (isAndroid()) {
return 'tg-android';
}
if (isIOS()) {
return 'tg-ios';
}
} else {
if (isPC()) {
return 'browser-pc';
}
if (isAndroid()) {
return 'browser-android';
}
if (isIOS()) {
return 'browser-ios';
}
}
return 'browser-pc';
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,27 @@ import { useWalletConnector } from '@/evm/hooks/useWalletConnector';
import { useCallback } from 'react';
import { useConnectingStatus } from '@/evm/hooks/useConnectingStatus';
import { useAccount } from 'wagmi';
import { getEvmWalletPlatformBehavior } from '@/evm/utils/getEvmWalletPlatformBehavior';

export function EvmConnectingView() {
const { selectedWallet } = useWalletKit();
const isConnected = useIsConnected();
const selectedConnector = useWalletConnector(selectedWallet.id);

const behavior = getEvmWalletPlatformBehavior(selectedWallet);
const { connect, status, setStatus } = useConnectingStatus();
const { address } = useAccount();

const runConnect = useCallback(() => {
if (!selectedWallet.isInstalled()) return;
if (!behavior?.isInstalled?.()) return;

if (selectedConnector) {
setStatus(CONNECT_STATUS.CONNECTING);
connect({ connector: selectedConnector });
} else {
setStatus(CONNECT_STATUS.UNAVAILABLE);
}
}, [connect, selectedConnector, selectedWallet, setStatus]);
}, [behavior, connect, selectedConnector, setStatus]);

return (
<TemplateConnectingView
Expand Down
6 changes: 4 additions & 2 deletions packages/walletkit/src/evm/components/EvmQRCodeView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { useWalletKit } from '@/core/providers/WalletKitProvider/context';
import { useIsConnected } from '@/evm/hooks/useIsConnected';
import { useWalletConnectUri } from '@/evm/hooks/useWalletConnectUri';
import { useWalletConnectModal } from '@/evm/hooks/useWalletConnectModal';
import { EvmWallet, isWalletConnect, metaMask } from '@/evm/wallets';
import { isWalletConnect, metaMask } from '@/evm/wallets';
import { useMetaMaskUri } from '@/evm/hooks/userMetaMaskUri';
import { useMemo } from 'react';
import { useAccount } from 'wagmi';
import { getEvmWalletPlatformBehavior } from '@/evm/utils/getEvmWalletPlatformBehavior';

export function EvmQRCodeView() {
const { selectedWallet } = useWalletKit();
Expand All @@ -23,7 +24,8 @@ export function EvmQRCodeView() {
return metaMaskUri;
}

return wcUri ? (selectedWallet as EvmWallet).getUri?.(wcUri) : wcUri;
const behavior = getEvmWalletPlatformBehavior(selectedWallet);
return wcUri ? behavior?.getUri?.(wcUri) : wcUri;
}, [metaMaskUri, selectedWallet, wcUri]);

const wcModal = useWalletConnectModal();
Expand Down
Loading

0 comments on commit b6cbb8d

Please sign in to comment.