-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add sequence and web3auth wallets
- Loading branch information
1 parent
1688934
commit 3f6f94b
Showing
31 changed files
with
33,020 additions
and
5,440 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { Connector } from '@wagmi/core'; | ||
|
||
import { CustodyType } from '../../types'; | ||
|
||
export interface ExtendedConnector extends Connector { | ||
name: string; | ||
available: boolean; | ||
ready: boolean; | ||
custodyType: CustodyType; | ||
icon?: string | ((props: any) => JSX.Element); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './extended-connector'; | ||
export * from './onboard-base-connector'; | ||
export * from './onboard-injected-base'; |
202 changes: 202 additions & 0 deletions
202
packages/common/src/connectors/base/onboard-base-connector.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
import { Web3Provider } from '@ethersproject/providers'; | ||
import { | ||
Chain, | ||
Connector, | ||
ConnectorNotFoundError, | ||
ProviderRpcError, | ||
SwitchChainError, | ||
UserRejectedRequestError, | ||
} from '@wagmi/core'; | ||
import type { EIP1193Provider, WalletModule } from '@web3-onboard/common'; | ||
import { BigNumber, utils } from 'ethers'; | ||
import EventEmitter from 'eventemitter3'; | ||
|
||
import { CustodyType } from '../../types'; | ||
import { ExtendedConnector } from './extended-connector'; | ||
|
||
function normalizeChainId(chainId: string | number) { | ||
if (typeof chainId === 'string') { | ||
const isHex = chainId.trim().substring(0, 2); | ||
|
||
return Number.parseInt(chainId, isHex === '0x' ? 16 : 10); | ||
} | ||
return chainId; | ||
} | ||
|
||
export type BaseOptions = { | ||
appName: string; | ||
appLogo: string; | ||
}; | ||
|
||
abstract class Web3OnboardConnectorBase<TOptions extends BaseOptions> | ||
extends Connector<any, TOptions> | ||
implements ExtendedConnector | ||
{ | ||
name: string = ''; | ||
icon?: ExtendedConnector['icon']; | ||
ready: boolean = false; | ||
available: boolean = true; | ||
custodyType: CustodyType = CustodyType.UNKNOWN; | ||
|
||
provider!: EIP1193Provider; | ||
|
||
constructor(config: { chains?: Chain[]; options: TOptions }) { | ||
super({ ...config, options: config.options }); | ||
|
||
this.getWalletModule() | ||
.then((m) => { | ||
if (!this.name) { | ||
this.name = m.label; | ||
} | ||
this.ready = true; | ||
this.available = true; | ||
|
||
if (!this.icon) { | ||
m.getIcon().then((icon) => { | ||
this.icon = icon; | ||
}); | ||
} | ||
}) | ||
.catch((e) => { | ||
this.ready = false; | ||
this.available = false; | ||
this.emit('error', e); | ||
}); | ||
} | ||
|
||
abstract getWalletModule(): Promise<WalletModule>; | ||
|
||
async connect() { | ||
const provider = await this.getProvider(); | ||
|
||
if (provider?.on) { | ||
provider.on('accountsChanged', this.onAccountsChanged.bind(this)); | ||
provider.on('chainChanged', this.onChainChanged.bind(this)); | ||
provider.on('disconnect', this.onDisconnect.bind(this)); | ||
} | ||
|
||
const account = await this.getAccount(); | ||
const id = await this.getChainId(); | ||
|
||
return { | ||
account, | ||
provider, | ||
chain: { id, unsupported: await this.isChainUnsupported(id) }, | ||
}; | ||
} | ||
|
||
async disconnect() { | ||
const provider = await this.getProvider(); | ||
if (!provider?.removeListener) return; | ||
|
||
provider.removeListener('accountsChanged', this.onAccountsChanged); | ||
provider.removeListener('chainChanged', this.onChainChanged); | ||
provider.removeListener('disconnect', this.onDisconnect); | ||
} | ||
|
||
async getAccount() { | ||
const accounts = await ( | ||
await this.getProvider() | ||
).request({ method: 'eth_requestAccounts' }); | ||
|
||
if (!accounts.length) { | ||
throw new Error('No accounts found'); | ||
} | ||
|
||
return accounts[0].toString(); | ||
} | ||
|
||
async getChainId() { | ||
if (!this.provider) { | ||
throw new ConnectorNotFoundError(); | ||
} | ||
|
||
return normalizeChainId( | ||
await this.provider.request({ method: 'eth_chainId' }), | ||
); | ||
} | ||
|
||
async getProvider() { | ||
const walletModule = await this.getWalletModule(); | ||
|
||
if (!this.provider) { | ||
this.provider = ( | ||
await walletModule.getInterface({ | ||
chains: this.chains.map((x) => ({ | ||
id: x.id.toString(), | ||
label: x.name, | ||
rpcUrl: x.rpcUrls.default, | ||
token: x.nativeCurrency?.symbol || 'Token', | ||
})), | ||
BigNumber, | ||
EventEmitter, | ||
appMetadata: { | ||
name: this.options?.appName || 'Flair', | ||
icon: this.options?.appLogo || 'https://wagmi.io/favicon.ico', | ||
}, | ||
}) | ||
).provider; | ||
} | ||
|
||
return this.provider; | ||
} | ||
|
||
async getSigner() { | ||
const provider = await this.getProvider(); | ||
const account = await this.getAccount(); | ||
return new Web3Provider(provider, 'any').getSigner(account); | ||
} | ||
|
||
async isAuthorized() { | ||
return false; | ||
} | ||
|
||
switchChain: undefined | any = async (chainId: number) => { | ||
const provider = await this.getProvider(); | ||
const id = normalizeChainId(chainId); | ||
|
||
try { | ||
await provider.request({ | ||
method: 'wallet_switchEthereumChain', | ||
params: [{ chainId: id.toString() }], | ||
}); | ||
return ( | ||
this.chains.find((x) => x.id === chainId) ?? { | ||
id: chainId, | ||
name: `Chain ${id}`, | ||
network: `${id}`, | ||
rpcUrls: { default: '' }, | ||
} | ||
); | ||
} catch (error) { | ||
const message = | ||
typeof error === 'string' | ||
? error | ||
: (error as ProviderRpcError)?.message; | ||
if (/user rejected request/i.test(message)) | ||
throw new UserRejectedRequestError(error); | ||
throw new SwitchChainError(error); | ||
} | ||
}; | ||
|
||
protected onAccountsChanged(accounts: string[]) { | ||
if (accounts.length === 0) this.emit('disconnect'); | ||
else this.emit('change', { account: utils.getAddress(accounts[0]) }); | ||
} | ||
|
||
protected isChainUnsupported(chainId: number) { | ||
return !this.chains.some((x) => x.id === chainId); | ||
} | ||
|
||
protected onChainChanged(chainId: string | number) { | ||
const id = normalizeChainId(chainId); | ||
const unsupported = this.isChainUnsupported(id); | ||
this.emit('change', { chain: { id, unsupported } }); | ||
} | ||
|
||
protected onDisconnect() { | ||
this.emit('disconnect'); | ||
} | ||
} | ||
|
||
export { Web3OnboardConnectorBase }; |
66 changes: 66 additions & 0 deletions
66
packages/common/src/connectors/base/onboard-injected-base.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { Chain } from '@wagmi/core'; | ||
import injectedModule from '@web3-onboard/injected-wallets'; | ||
import { InjectedWalletModule } from '@web3-onboard/injected-wallets/dist/types'; | ||
import injectedModuleWallets from '@web3-onboard/injected-wallets/dist/wallets'; | ||
|
||
import { getDevice } from '../../utils'; | ||
import { | ||
BaseOptions, | ||
Web3OnboardConnectorBase, | ||
} from './onboard-base-connector'; | ||
|
||
export type InjectedBaseOptions = BaseOptions & {}; | ||
|
||
let availableInjectedWallets: InjectedWalletModule[] | undefined; | ||
|
||
const getAvailableInjectedWallets = () => { | ||
if (!availableInjectedWallets) { | ||
availableInjectedWallets = injectedModule({})({ | ||
device: getDevice() as any, | ||
}) as InjectedWalletModule[]; | ||
} | ||
|
||
return availableInjectedWallets; | ||
}; | ||
|
||
abstract class Web3OnboardInjectedConnectorBase< | ||
Options extends InjectedBaseOptions = any, | ||
> extends Web3OnboardConnectorBase<Options> { | ||
walletModule!: InjectedWalletModule; | ||
|
||
constructor(config: { chains?: Chain[]; options: Options }) { | ||
super({ ...config, options: config.options }); | ||
|
||
this.getWalletModule().then((module) => { | ||
this.walletModule = module; | ||
this.name = module.label; | ||
|
||
if (getAvailableInjectedWallets().find((w) => w.label === module.label)) { | ||
this.available = true; | ||
} | ||
}); | ||
} | ||
|
||
abstract selectModule( | ||
wallets: InjectedWalletModule[], | ||
): Promise<InjectedWalletModule | undefined>; | ||
|
||
async getWalletModule(): Promise<InjectedWalletModule> { | ||
if (!this.walletModule) { | ||
const mod = await this.selectModule(injectedModuleWallets); | ||
|
||
if (!mod) { | ||
debugger; | ||
throw new Error( | ||
'No injected module returned from options.selectModule', | ||
); | ||
} | ||
|
||
this.walletModule = mod; | ||
} | ||
|
||
return this.walletModule; | ||
} | ||
} | ||
|
||
export { Web3OnboardInjectedConnectorBase }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { InjectedWalletModule } from '@web3-onboard/injected-wallets/dist/types'; | ||
|
||
import { CustodyType } from '../types'; | ||
import { Web3OnboardInjectedConnectorBase } from './base/onboard-injected-base'; | ||
|
||
class Web3OnboardBinanceConnector extends Web3OnboardInjectedConnectorBase { | ||
readonly id = 'web3onboard-binance'; | ||
custodyType = CustodyType.SELF_CUSTODY; | ||
|
||
async selectModule(wallets: InjectedWalletModule[]) { | ||
return wallets.find((w) => w.label.toLowerCase().includes('binance')); | ||
} | ||
|
||
switchChain = undefined; | ||
} | ||
|
||
export { Web3OnboardBinanceConnector }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { InjectedWalletModule } from '@web3-onboard/injected-wallets/dist/types'; | ||
|
||
import { CustodyType } from '../types'; | ||
import { Web3OnboardInjectedConnectorBase } from './base/onboard-injected-base'; | ||
|
||
class Web3OnboardBraveConnector extends Web3OnboardInjectedConnectorBase { | ||
readonly id = 'web3onboard-brave'; | ||
custodyType = CustodyType.SELF_CUSTODY; | ||
|
||
async selectModule(wallets: InjectedWalletModule[]) { | ||
return wallets.find((w) => w.label.toLowerCase().includes('brave')); | ||
} | ||
} | ||
|
||
export { Web3OnboardBraveConnector }; |
Oops, something went wrong.