Example: https://xdefi-tech.github.io/walletconnect/
Please, look at the example application in folder example
yarn add @xdefi/wallets-connector
@xdefi/wallets-connector is an easy-to-use library to help developers add support for multiple providers in their apps with a simple customizable configuration.
By default Library supports injected providers like ( Metamask,Brave Wallet, Dapper, Frame, Gnosis Safe, Tally, Web3 Browsers, etc) and WalletConnect. You can also easily configure the library to support Coinbase Wallet, Torus, Portis, Fortmatic and many more.
It's possible to customize the display of each provider to change the name, description and logo. These options are available as part of the provider options as following
const getProviderOptions = (): IProviderOptions => {
const providerOptions = {
xdefi: {},
injected: {
display: {
...injected.INJECTED,
logo: 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Circle-icons-gamecontroller.svg/2048px-Circle-icons-gamecontroller.svg.png'
}
},
walletconnect: {
package: EthereumProvider,
options: {
projectId: <projectId>,
}
},
coinbasewallet: {
package: CoinbaseWalletSDK,
},
torus: {
package: Torus
}
}
return providerOptions
}
function App() {
const [options] = useState(() => getProviderOptions())
return (
<NetworkManager options={options}>
<MyApp />
</NetworkManager>
)
}
Using with ethers.js
import { ethers } from "ethers";
...
const walletRequest = useWalletRequest();
const signTransaction = useCallback(
async (transaction: RouteTransactionType) => {
const { chain, unsignedStdTx } = transaction;
const unSignedTx =
typeof unsignedStdTx === 'string'
? JSON.parse(unsignedStdTx)
: unsignedStdTx;
if (
[
IChainType.bitcoin,
IChainType.litecoin,
IChainType.bitcoincash,
IChainType.dogecoin,
].includes(chainId)
) {
const result = await walletRequest({
chainId,
method: 'transfer',
params: [
YOUR_TX_PARAMS,
],
});
return result;
} else if (chainId === IChainType.thorchain) {
const result = await walletRequest({
chainId,
method: 'deposit',
params: [
YOUR_TX_PARAMS,
],
});
return result;
} else if (chainId === IChainType.binance) {
const result = await walletRequest({
chainId,
method: 'transfer',
params: [
YOUR_TX_PARAMS,
],
});
return result;
} else {
throw new Error(`${chain} is not yet supported 🥺`);
}
},
[walletRequest]
);
const web3Provider = useMemo(() => {
if (provider) {
const web3 = new ethers.providers.Web3Provider(provider);
return web3;
}
return null;
}, [provider]);
const etherSigner = useMemo(() => {
if (!web3Provider) return null;
return web3Provider.getSigner();
}, [web3Provider]);
Using with Vite
//vite.config.js
import nodePolyfills from 'rollup-plugin-polyfill-node'
const production = process.env.NODE_ENV === 'production'
export default {
plugins: [
// ↓ Needed for development mode
!production &&
nodePolyfills({
include: ['node_modules/**/*.js', new RegExp('node_modules/.vite/.*js')]
})
],
build: {
rollupOptions: {
plugins: [
// ↓ Needed for build
nodePolyfills()
]
},
// ↓ Needed for build if using WalletConnect and other providers
commonjsOptions: {
transformMixedEsModules: true
}
}
}
You can use the modal from the old fashioned web page JavaScript as well.
First get a library bundled JavaScript from Releases.
After including the bundle in your HTML, you can use it on your web page:
// You have to refer to default since it was bundled for ESModules // but after that the documentation will be the same
const providerOptions = {
/* See Provider Options Section */
};
const connector = new WalletsConnector(
options, // from getProviderOptions
cacheEnabled, // true
);
await connector.connect();
connector.on(WALLETS_EVENTS.ACCOUNTS, (newList: IProviderWithAccounts) => {
doSmthWithAccounts(newList)
})
You can subscribe to provider events compatible with EIP-1193 standard.
// Subscribe to accounts change
provider.on('accountsChanged', (accounts: string[]) => {
console.log(accounts)
})
// Subscribe to chainId change
provider.on('chainChanged', (chainId: number) => {
console.log(chainId)
})
// Subscribe to provider connection
provider.on('connect', (info: { chainId: number }) => {
console.log(info)
})
// Subscribe to provider disconnection
provider.on('disconnect', (error: { code: number; message: string }) => {
console.log(error)
})
React example of usage with custom hooks (but we recommend to use this Hooks)
const context = useContext(WalletsContext)
const [current, setCurrentProvider] = useState<IProviderInfo>()
const [accounts, setAccounts] = useState<IProviderWithAccounts>({})
useEffect(() => {
if (context) {
context.on(WALLETS_EVENTS.ACCOUNTS, (newList: IProviderWithAccounts) => {
setAccounts(newList)
})
}
}, [context])
| Hooks | Description |
| -------------------------- | ----------------------------------------------------------------------------------- | --- | --- |
| useConnectorActiveIds | Returns list of connected providers (Metamask, XDeFi, WalletConnect, etc) |
| useConnectorMultiConfigs | Return configs per provider (chain, network, address - just for web3/EVM providers) | | --> |
| useConnectorMultiProviders | Returns list of providers for using with Web3
or Ether.js
library |
| useConnectorMultiChains | Returns list of connected chains per provider |
| useWalletsOptions | Returns list of providers (provided by user application) and method to disconnect |
Hooks | Description |
---|---|
useWalletRequest | Allows to send custom txs/request into connected wallet |
const accounts = useConnectedAccounts()
const isConnected = useStore((state) => state.connected)
const setIsConnected = useStore((state) => state.setConnected)
const onConnectHandler = useCallback(() => {
setIsConnected(true)
}, [setIsConnected])
const onErrorHandler = useCallback(() => {
setIsConnected(false)
}, [setIsConnected])
const onCloseHandler = useCallback(() => {
setIsConnected(false)
}, [setIsConnected])
const CUSTOM_THEME_BUILDER = (darkMode: boolean): any => ({
white: darkMode ? '#0969da' : '#9a6700',
black: darkMode ? '#9a6700' : '#0969da',
modal: {
bg: darkMode ? '#2b2b2b' : '#E5E5E5',
layoutBg: darkMode ? '#000000' : '#000000'
},
wallet: {
name: darkMode ? '#9a6700' : '#333333',
descColor: darkMode ? '#c4c4c4' : '#979797',
titleColor: darkMode ? '#f2f1f1' : '#333333',
bg: darkMode ? '#333333' : '#F2F1F1',
activeBg: darkMode ? 'lightslategrey' : 'darkseagreen'
}
})
...
<WalletsModal
themeBuilder={CUSTOM_THEME_BUILDER}
isDark={true} // true/false
trigger={(props: any) => (
<BtnOpen {...props}>Connect Styled Modal</BtnOpen>
)}
/>
These are all the providers available with library and how to configure their provider options:
Full list is at ./docs/providers
Do you want to add your provider to Web3Modal? All logic for supported providers lives inside the src/providers
directory. To add a new follow the following steps here
Custom browser extension example inside the src/providers/injected
file
export const XDEFI: IProviderInfo = {
id: WALLETS.xdefi,
name: 'XDEFI',
logo: XDEFILogo,
type: 'injected',
check: '__XDEFI',
installationLink: 'https://xdefi.io',
getEthereumProvider: () => {
return window.xfi ? window.xfi.ethereum : undefined
},
chains: {
[IChainType.bitcoin]: {
methods: {
getAccounts: () => {
return new Promise((resolve, reject) => {
window.xfi.bitcoin.request(
{ method: 'request_accounts', params: [] },
(error: any, accounts: any) => {
if (error) {
reject(error)
}
resolve(accounts)
}
)
})
},
signTransaction: (hash: string) => {
return new Promise((resolve, reject) => {
window.xfi.bitcoin.request(
{ method: 'sign_transaction', params: [hash] },
(error: any, result: any) => {
if (error) {
reject(error)
}
resolve(result)
}
)
})
},
request: (method: string, data: any) => {
return new Promise((resolve, reject) => {
window.xfi.bitcoin.request(
{ method: method, params: data },
(error: any, result: any) => {
if (error) {
reject(error)
}
resolve(result)
}
)
})
}
}
},
[IChainType.binance]: {
methods: {
getAccounts: () => {
return new Promise((resolve, reject) => {
window.xfi.binance.request(
{ method: 'request_accounts', params: [] },
(error: any, accounts: any) => {
if (error) {
reject(error)
}
resolve(accounts)
}
)
})
},
signTransaction: (hash: string) => {
return new Promise((resolve, reject) => {
window.xfi.binance.request(
{ method: 'sign_transaction', params: [hash] },
(error: any, result: any) => {
if (error) {
reject(error)
}
resolve(result)
}
)
})
},
request: (method: string, data: any) => {
return new Promise((resolve, reject) => {
window.xfi.binance.request(
{ method: method, params: data },
(error: any, result: any) => {
if (error) {
reject(error)
}
resolve(result)
}
)
})
}
}
},
...
}
}
Code contributions are welcome ❤️❤️❤️!
If you wish to support a new provider submit a issue to the repo or fork this repo and create a pull request.
MIT