0xweb
Version:
Contract package manager and other web3 tools
116 lines (92 loc) • 3.7 kB
text/typescript
import di from 'a-di';
import { TEth } from '@dequanto/models/TEth';
import { Rpc, RpcTypes } from '@dequanto/rpc/Rpc';
import { $require } from '@dequanto/utils/$require';
import { DataLike } from '@dequanto/utils/types';
import { EIP6963ProviderDetail, EIP6963ProviderFactory } from '@dequanto/wallets/EIP6963ProviderFactory';
import { WClient } from './ClientPool';
import { $hex } from '@dequanto/utils/$hex';
/** Wallet actions only. For all Node (Chain) related actions - Web3Client should be used */
export class WalletClient {
public factory: EIP6963ProviderFactory;
constructor (factory?: EIP6963ProviderFactory) {
this.factory = factory ?? di.resolve(EIP6963ProviderFactory);
}
// Client abstract methods
//Set the provider by UUID as the default one for eth_** methods
async useProvider (uuid: string) {
this.factory.useProvider(uuid);
}
async getProvider (uuid?: string): Promise<EIP6963ProviderDetail> {
return this.factory.getProvider(uuid, true);
}
async getProviders (): Promise<EIP6963ProviderDetail[]> {
let { providers } = this.factory;
return providers;
}
async getAccounts (uuid?: string): Promise<TEth.Address[]> {
let rpc = this.getRpc(uuid);
return rpc.eth_accounts();
}
/** Find the provider by UUID or use the first one to connect to and to requestAccounts */
async connect (uuid?: string): Promise<TEth.Address[]> {
return this.factory.connect(uuid);
}
async disconnect () {
this.factory.disconnect();
}
isConnected (address?: TEth.Address): boolean {
return this.factory.isConnected(address);
}
// RPC methods
eth_accounts () {
let rpc = this.getRpc();
return rpc.eth_accounts();
}
eth_requestAccounts () {
let rpc = this.getRpc();
return rpc.eth_requestAccounts();
}
eth_sign (address: TEth.Address, message: string): Promise<string> {
let rpc = this.getRpc();
return rpc.eth_sign(address, message);
}
eth_signTypedData_v4 (address: TEth.Address, typedData: DataLike<RpcTypes.TypedData>) {
let rpc = this.getRpc();
return rpc.eth_signTypedData_v4(address, typedData);
}
eth_sendTransaction (...args: Parameters<Rpc['eth_sendTransaction']>) {
let rpc = this.getRpc();
return rpc.eth_sendTransaction(...args);
}
eth_chainId (...args: Parameters<Rpc['eth_chainId']>) {
let rpc = this.getRpc();
return rpc.eth_chainId(...args);
}
wallet_addEthereumChain (...args: Parameters<Rpc['wallet_addEthereumChain']>) {
let rpc = this.getRpc();
return rpc.wallet_addEthereumChain(...args);
}
wallet_switchEthereumChain (...args: Parameters<Rpc['wallet_switchEthereumChain']>) {
let rpc = this.getRpc();
return rpc.wallet_switchEthereumChain(...args);
}
async getClientFor (chainId: number) {
let { selected } = this.factory;
$require.notNull(selected, 'No selected EIP6963 provider');
let client = new WClient({ web3: selected.provider as any });
let providerChainId = await client.rpc.eth_chainId();
if (providerChainId !== chainId) {
await client.rpc.wallet_switchEthereumChain({
chainId: $hex.ensure(chainId)
});
providerChainId = await client.rpc.eth_chainId();
$require.eq(providerChainId, chainId, 'Chain ID mismatch');
}
return client;
}
private getRpc (uuid?: string) {
let p = this.factory.getProvider(uuid, false);
return new Rpc(p.provider)
}
}