@davidzwfu/wagmi-connector
Version:
Venly integration for wagmi
124 lines (123 loc) • 5.04 kB
JavaScript
import { ChainNotConfiguredError, createConnector, } from '@wagmi/core';
import {
// type ProviderRpcError,
SwitchChainError, UserRejectedRequestError, getAddress, numberToHex, } from 'viem';
import { VenlyProvider, CHAIN_CONFIGS, } from '@venly/web3-provider';
venly.type = 'venly';
export function venly(parameters) {
let sdk = new VenlyProvider();
let walletProvider;
return createConnector((config) => ({
id: 'venly',
name: 'Venly',
type: venly.type,
async connect({ chainId } = {}) {
try {
const provider = await this.getProvider();
const accounts = (await provider.request({
method: 'eth_requestAccounts',
})).map((x) => getAddress(x));
provider.on('accountsChanged', this.onAccountsChanged);
provider.on('chainChanged', this.onChainChanged);
provider.on('disconnect', this.onDisconnect.bind(this));
// Switch to chain if provided
let currentChainId = await this.getChainId();
if (chainId && currentChainId !== chainId) {
const chain = await this.switchChain({ chainId });
currentChainId = chain?.id ?? currentChainId;
}
return { accounts, chainId: currentChainId };
}
catch (error) {
if (/(user closed modal|accounts received is empty|user denied account)/i.test(error.message))
throw new UserRejectedRequestError(error);
throw error;
}
},
async disconnect() {
const provider = await this.getProvider();
if (!provider)
return;
provider.removeListener('accountsChanged', this.onAccountsChanged);
provider.removeListener('chainChanged', this.onChainChanged);
provider.removeListener('disconnect', this.onDisconnect.bind(this));
await sdk.logout();
},
async getAccounts() {
const provider = await this.getProvider();
return (await provider.request({
method: 'eth_accounts',
})).map((x) => getAddress(x));
},
async getChainId() {
const provider = await this.getProvider();
const chainId = await provider.request({
method: 'eth_chainId',
});
return Number(chainId);
},
async getProvider() {
if (!walletProvider) {
const chain = config.chains.find((chain) => chain.id === parameters.chainId) || config.chains[0];
const chainId = parameters.chainId || chain?.id;
const options = CHAIN_CONFIGS[chainId];
walletProvider = await sdk.createProvider({
...parameters,
skipAuthentication: true,
environment: options.env,
secretType: options.secretType,
});
}
return walletProvider;
},
async isAuthorized() {
try {
walletProvider = await sdk.createProvider({
...parameters,
skipAuthentication: true,
});
const authResult = await sdk.checkAuthenticated();
return authResult.isAuthenticated;
}
catch {
return false;
}
},
async switchChain({ chainId }) {
const chain = config.chains.find((chain) => chain.id === chainId);
if (!chain)
throw new SwitchChainError(new ChainNotConfiguredError());
const provider = await this.getProvider();
const chainId_ = numberToHex(chain.id);
try {
await provider.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: chainId_ }],
});
return chain;
}
catch (error) {
throw new SwitchChainError(error);
}
},
onAccountsChanged(accounts) {
if (accounts.length === 0)
config.emitter.emit('disconnect');
else
config.emitter.emit('change', {
accounts: accounts.map((x) => getAddress(x)),
});
},
onChainChanged(chain) {
const chainId = Number(chain);
config.emitter.emit('change', { chainId });
},
async onDisconnect(_error) {
config.emitter.emit('disconnect');
const provider = await this.getProvider();
provider.removeListener('accountsChanged', this.onAccountsChanged);
provider.removeListener('chainChanged', this.onChainChanged);
provider.removeListener('disconnect', this.onDisconnect.bind(this));
},
}));
}