@xdefi/wallets-connector
v2.4.1
Published
Cross chain wallets connector with react hooks
Downloads
398
Keywords
Readme
@xdefi/wallets-connector
Example: https://xdefi-tech.github.io/walletconnect/
Please, look at the example application in folder example
Install
yarn add @xdefi/wallets-connector
Introduction
@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.
Usage/Custom Providers Display
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
}
}
}
Using in vanilla JavaScript
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)
})
Events
Provider Events
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
Hooks for multi connections (library allows to connect more then 1 provider per session)
| 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 for multichain methods
| 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])
Custom Theme
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>
)}
/>
Provider Options
These are all the providers available with library and how to configure their provider options:
Full list is at ./docs/providers
Adding a new provider
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
Add new injected provider
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)
}
)
})
}
}
},
...
}
}
Contributions
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.
License
MIT