Skip to content

Commit

Permalink
feat: improve Wagmi config sync (#261)
Browse files Browse the repository at this point in the history
  • Loading branch information
chybisov authored Jun 6, 2024
1 parent cf0de31 commit e2c6004
Show file tree
Hide file tree
Showing 15 changed files with 1,320 additions and 1,302 deletions.
6 changes: 4 additions & 2 deletions packages/wallet-management/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,17 @@
"@lifi/sdk": "^3.0.0-alpha.63",
"@solana/wallet-adapter-base": "^0.9.23",
"react": "^18.3.1",
"wagmi": "^2.9.6"
"viem": "^2.13.7",
"wagmi": "^2.9.9"
},
"devDependencies": {
"cpy-cli": "^5.0.0",
"typescript": "^5.4.5"
},
"peerDependencies": {
"@tanstack/react-query": "^5.0.0",
"viem": "^2.0.0"
"viem": "^2.12.0",
"wagmi": "^2.9.0"
},
"eslintConfig": {
"extends": "../../.eslintrc"
Expand Down
121 changes: 121 additions & 0 deletions packages/wallet-management/src/createDefaultWagmiConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import type {
CoinbaseWalletParameters,
WalletConnectParameters,
} from '@wagmi/connectors';
import type { Chain, Transport } from 'viem';
import { createClient, http } from 'viem';
import { mainnet } from 'viem/chains';
import type { Config, CreateConnectorFn } from 'wagmi';
import { createConfig } from 'wagmi';
import { createCoinbaseConnector } from './connectors/coinbase.js';
import {
alpha,
binance,
bitget,
bitpie,
block,
brave,
dcent,
exodus,
frame,
frontier,
gate,
hyperpay,
imtoken,
liquality,
okx,
oneinch,
ownbit,
safepal,
status,
taho,
tokenary,
tokenpocket,
trust,
xdefi,
} from './connectors/connectors.js';
import { createWalletConnectConnector } from './connectors/walletConnect.js';

export type _chains = readonly [Chain, ...Chain[]];
export type _transports = Record<_chains[number]['id'], Transport>;

export interface DefaultWagmiConfigProps {
walletConnect?: WalletConnectParameters;
coinbase?: CoinbaseWalletParameters;
wagmiConfig?: {
ssr?: boolean;
};
}

export interface DefaultWagmiConfigResult {
config: Config;
connectors: CreateConnectorFn[];
}

/**
* Creates default Wagmi config that can be later synced (via useSyncWagmiConfig) with chains fetched from LI.FI API.
* @param props Properties to setup connectors. {@link DefaultWagmiConfigProps}
* @returns Wagmi config and connectors. {@link DefaultWagmiConfigResult}
* @example
* const { config, connectors } = createDefaultWagmiConfig({
* walletConnect: {
* projectId: import.meta.env.VITE_WALLET_CONNECT,
* },
* coinbase: { appName: 'LI.FI Demo' },
* });
* export const WalletProvider: FC<PropsWithChildren> = ({ children }) => {
* const { chains } = useAvailableChains();
* useSyncWagmiConfig(config, connectors, chains);
* return <WagmiProvider config={config}>{children}</WagmiProvider>;
* };
*/
export function createDefaultWagmiConfig(
props?: DefaultWagmiConfigProps,
): DefaultWagmiConfigResult {
const connectors: CreateConnectorFn[] = [
bitget,
gate,
exodus,
taho,
binance,
frontier,
okx,
trust,
status,
alpha,
block,
bitpie,
brave,
dcent,
frame,
hyperpay,
imtoken,
liquality,
ownbit,
tokenpocket,
xdefi,
oneinch,
tokenary,
safepal,
];

if (props?.coinbase) {
connectors.unshift(createCoinbaseConnector(props.coinbase));
}
if (props?.walletConnect) {
connectors.unshift(createWalletConnectConnector(props.walletConnect));
}

const config = createConfig({
chains: [mainnet],
client({ chain }) {
return createClient({ chain, transport: http() });
},
...props?.wagmiConfig,
});

return {
config,
connectors,
};
}
4 changes: 4 additions & 0 deletions packages/wallet-management/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ export * from './connectors/coinbase.js';
export * from './connectors/connectors.js';
export * from './connectors/safe.js';
export * from './connectors/walletConnect.js';
export * from './createDefaultWagmiConfig.js';
export * from './icons.js';
export * from './syncWagmiConfig.js';
export * from './useSyncWagmiConfig.js';
export * from './utils/convertExtendedChain.js';
export * from './utils/getConnectorIcon.js';
export * from './utils/getWalletPriority.js';
export * from './utils/isWalletInstalled.js';
Expand Down
23 changes: 23 additions & 0 deletions packages/wallet-management/src/syncWagmiConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { ExtendedChain } from '@lifi/sdk';
import type { Chain } from 'viem';
import type { Config, CreateConnectorFn } from 'wagmi';
import { reconnect } from 'wagmi/actions';
import { convertExtendedChain } from './utils/convertExtendedChain.js';

export const syncWagmiConfig = (
wagmiConfig: Config,
connectors: CreateConnectorFn[],
chains: ExtendedChain[],
) => {
const _chains = chains.map(convertExtendedChain) as [Chain, ...Chain[]];
wagmiConfig._internal.chains.setState(_chains);
wagmiConfig._internal.connectors.setState(() =>
[
...connectors,
...(wagmiConfig._internal.mipd
?.getProviders()
.map(wagmiConfig._internal.connectors.providerDetailToConnector) ?? []),
].map(wagmiConfig._internal.connectors.setup),
);
reconnect(wagmiConfig);
};
16 changes: 16 additions & 0 deletions packages/wallet-management/src/useSyncWagmiConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { ExtendedChain } from '@lifi/sdk';
import { useEffect } from 'react';
import type { Config, CreateConnectorFn } from 'wagmi';
import { syncWagmiConfig } from './syncWagmiConfig.js';

export const useSyncWagmiConfig = (
wagmiConfig: Config,
connectors: CreateConnectorFn[],
chains?: ExtendedChain[],
) => {
useEffect(() => {
if (chains?.length) {
syncWagmiConfig(wagmiConfig, connectors, chains);
}
}, [chains, connectors, wagmiConfig]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ChainBlockExplorers = {
default: ChainBlockExplorer;
};

export const formatChain = (chain: ExtendedChain): Chain => ({
export const convertExtendedChain = (chain: ExtendedChain): Chain => ({
...chain,
...chain.metamask,
blockExplorers: chain.metamask.blockExplorerUrls.reduce(
Expand Down
2 changes: 1 addition & 1 deletion packages/widget-embedded/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.23.1",
"wagmi": "^2.9.6"
"wagmi": "^2.9.9"
},
"devDependencies": {
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
Expand Down
97 changes: 12 additions & 85 deletions packages/widget-embedded/src/providers/WalletProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,95 +1,22 @@
import {
alpha,
binance,
bitget,
bitpie,
block,
brave,
createCoinbaseConnector,
createWalletConnectConnector,
dcent,
exodus,
frame,
frontier,
gate,
hyperpay,
imtoken,
liquality,
metaMask,
okx,
oneinch,
ownbit,
safepal,
status,
taho,
tokenary,
tokenpocket,
trust,
xdefi,
createDefaultWagmiConfig,
useSyncWagmiConfig,
} from '@lifi/wallet-management';
import { formatChain, useAvailableChains } from '@lifi/widget';
import { useMemo, type FC, type PropsWithChildren } from 'react';
import type { Chain } from 'viem';
import { createClient } from 'viem';
import { WagmiProvider, createConfig, http } from 'wagmi';
import { mainnet } from 'wagmi/chains';
import { useAvailableChains } from '@lifi/widget';
import { type FC, type PropsWithChildren } from 'react';
import { WagmiProvider } from 'wagmi';

const connectors = [
metaMask,
createWalletConnectConnector({
const { config, connectors } = createDefaultWagmiConfig({
walletConnect: {
projectId: import.meta.env.VITE_WALLET_CONNECT,
}),
createCoinbaseConnector({ appName: 'LI.FI NFT Demo' }),
bitget,
gate,
exodus,
taho,
binance,
frontier,
okx,
trust,
status,
alpha,
block,
bitpie,
brave,
dcent,
frame,
hyperpay,
imtoken,
liquality,
ownbit,
tokenpocket,
xdefi,
oneinch,
tokenary,
safepal,
];
},
coinbase: { appName: 'LI.FI NFT Demo' },
});

export const WalletProvider: FC<PropsWithChildren> = ({ children }) => {
const { chains } = useAvailableChains();

const wagmiConfig = useMemo(() => {
const _chains: [Chain, ...Chain[]] = chains?.length
? (chains.map(formatChain) as [Chain, ...Chain[]])
: [mainnet];
const wagmiConfig = createConfig({
chains: _chains,
connectors: connectors,
client({ chain }) {
return createClient({ chain, transport: http() });
},
});
useSyncWagmiConfig(config, connectors, chains);

return wagmiConfig;
}, [chains]);

return (
<WagmiProvider
config={wagmiConfig}
reconnectOnMount={Boolean(chains?.length)}
>
{children}
</WagmiProvider>
);
return <WagmiProvider config={config}>{children}</WagmiProvider>;
};
4 changes: 2 additions & 2 deletions packages/widget-playground-next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
"next": "14.2.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"viem": "^2.12.1",
"wagmi": "^2.9.6",
"viem": "^2.13.7",
"wagmi": "^2.9.9",
"zustand": "^4.5.2"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions packages/widget-playground-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.23.1",
"viem": "^2.12.1",
"wagmi": "^2.9.6",
"viem": "^2.13.7",
"wagmi": "^2.9.9",
"zustand": "^4.5.2"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { formatChain, useAvailableChains } from '@lifi/widget';
import { convertExtendedChain } from '@lifi/wallet-management';
import { useAvailableChains } from '@lifi/widget';
import {
RainbowKitProvider,
darkTheme,
Expand Down Expand Up @@ -52,7 +53,7 @@ export const EVMProvider: FC<PropsWithChildren> = ({ children }) => {

const wagmiConfig = useMemo(() => {
const _chains: [Chain, ...Chain[]] = chains?.length
? (chains.map(formatChain) as [Chain, ...Chain[]])
? (chains.map(convertExtendedChain) as [Chain, ...Chain[]])
: [mainnet];

const wagmiConfig = getDefaultConfig({
Expand Down
7 changes: 4 additions & 3 deletions packages/widget/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@
"react-router-dom": "^6.23.1",
"react-timer-hook": "^3.0.7",
"uuid": "^9.0.1",
"viem": "^2.12.1",
"wagmi": "^2.9.6",
"viem": "^2.13.7",
"wagmi": "^2.9.9",
"zustand": "^4.5.2"
},
"devDependencies": {
Expand All @@ -96,7 +96,8 @@
"react-dom": "^18.2.0",
"react-i18next": "^14.1.0",
"react-router-dom": "^6.22.0",
"wagmi": "^2.2.0",
"viem": "^2.12.0",
"wagmi": "^2.9.0",
"zustand": "^4.5.0"
},
"peerDependenciesMeta": {
Expand Down
1 change: 0 additions & 1 deletion packages/widget/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export * from './config/version.js';
export { useAccount } from './hooks/useAccount.js';
export { useAvailableChains } from './hooks/useAvailableChains.js';
export { useWidgetEvents, widgetEvents } from './hooks/useWidgetEvents.js';
export { formatChain } from './providers/WalletProvider/utils.js';
export * from './stores/form/types.js';
export { useFieldActions } from './stores/form/useFieldActions.js';
export { useFieldValues } from './stores/form/useFieldValues.js';
Expand Down
Loading

0 comments on commit e2c6004

Please sign in to comment.