William O'Beirne a043334685 Node Refactor (#1603)
* Initial work on refactoring node definitions to reduce number of places theyre defined, amount of copy pasting.

* Use makeAutoNodeNAme instead of manually appending _auto

* Add getNetVersion to list of unsupported methods

* PR feedback

* Rework web template node selector to be a network selector. Refactor some types to help with that. Better handle removing custom nodes.

* Remove color dropdown.

* Fix selecting custom networks. Show notification if change network intent fails.

* Use selectors for current node / network instead of intuiting from nodeSelection

* Add id key to all networks, simplify add and remove custom node and network functions.

* Fix a lot of uses of network.name to use network.id instead.

* Dont allow network chainid conflicts

* Fix web3 network by chainid

* Add testnet badge to network selector

* Change nomenclature from change(Node|Network)(Intent)? to change(Node|Network)(Requested|Succeeded)

* tscheck

* Better code for chainid collision

* Remove console logs

* Fix tests

* Network selector becomes self contained component used both by web header and electron nav.

* Dont select node again

* Additional title text

* tscheck

* Custom node behavior in Electron

* Close panel too

* Convert node label data into selector function

* tscheck

* Parens & space
2018-05-29 09:51:42 -05:00

89 lines
2.3 KiB
TypeScript

import { IHexStrWeb3Transaction } from 'libs/transaction';
import RPCNode from '../rpc';
import Web3Client from './client';
import Web3Requests from './requests';
import { INode } from 'libs/nodes/INode';
import {
isValidSendTransaction,
isValidSignMessage,
isValidGetAccounts,
isValidGetNetVersion
} from 'libs/validators';
export default class Web3Node extends RPCNode {
public client: Web3Client;
public requests: Web3Requests;
constructor() {
super('web3'); // initialized with fake endpoint
this.client = new Web3Client();
this.requests = new Web3Requests();
}
public getNetVersion(): Promise<string> {
return this.client
.call(this.requests.getNetVersion())
.then(isValidGetNetVersion)
.then(({ result }) => result);
}
public sendTransaction(web3Tx: IHexStrWeb3Transaction): Promise<string> {
return this.client
.call(this.requests.sendTransaction(web3Tx))
.then(isValidSendTransaction)
.then(({ result }) => result);
}
public signMessage(msgHex: string, fromAddr: string): Promise<string> {
return this.client
.call(this.requests.signMessage(msgHex, fromAddr))
.then(isValidSignMessage)
.then(({ result }) => result);
}
public getAccounts(): Promise<string> {
return this.client
.call(this.requests.getAccounts())
.then(isValidGetAccounts)
.then(({ result }) => result);
}
}
export function isWeb3Node(nodeLib: INode | Web3Node): nodeLib is Web3Node {
return nodeLib instanceof Web3Node;
}
export const Web3Service = 'MetaMask / Mist';
export async function setupWeb3Node() {
const { web3 } = window as any;
if (!web3 || !web3.currentProvider || !web3.currentProvider.sendAsync) {
throw new Error('Web3 not found. Please check that MetaMask is installed');
}
const lib = new Web3Node();
const chainId = await lib.getNetVersion();
const accounts = await lib.getAccounts();
if (!accounts.length) {
throw new Error('No accounts found in MetaMask / Mist.');
}
if (chainId === 'loading') {
throw new Error('MetaMask / Mist is still loading. Please refresh the page and try again.');
}
return { chainId, lib };
}
export async function isWeb3NodeAvailable(): Promise<boolean> {
try {
await setupWeb3Node();
return true;
} catch (e) {
return false;
}
}