Refactor BaseNode to be an interface INode (#167)
This commit is contained in:
parent
b666d0e143
commit
e07eedb3ad
|
@ -0,0 +1,13 @@
|
||||||
|
// @flow
|
||||||
|
import Big from 'bignumber.js';
|
||||||
|
import type { TransactionWithoutGas } from 'libs/transaction';
|
||||||
|
import type { Token } from 'config/data';
|
||||||
|
|
||||||
|
export interface INode {
|
||||||
|
getBalance(_address: string): Promise<Big>,
|
||||||
|
getTokenBalance(_address: string, _token: Token): Promise<Big>,
|
||||||
|
getTokenBalances(_address: string, _tokens: Token[]): Promise<Big>,
|
||||||
|
estimateGas(_tx: TransactionWithoutGas): Promise<Big>,
|
||||||
|
getTransactionCount(_address: string): Promise<string>,
|
||||||
|
sendRawTx(_tx: string): Promise<string>
|
||||||
|
}
|
|
@ -1,30 +0,0 @@
|
||||||
// @flow
|
|
||||||
import Big from 'bignumber.js';
|
|
||||||
import type { TransactionWithoutGas } from 'libs/transaction';
|
|
||||||
import type { Token } from 'config/data';
|
|
||||||
|
|
||||||
export default class BaseNode {
|
|
||||||
async getBalance(_address: string): Promise<Big> {
|
|
||||||
throw new Error('Implement me');
|
|
||||||
}
|
|
||||||
|
|
||||||
async getTokenBalance(_address: string, _token: Token): Promise<Big> {
|
|
||||||
throw new Error('Implement me');
|
|
||||||
}
|
|
||||||
|
|
||||||
async getTokenBalances(_address: string, _tokens: Token[]): Promise<Big[]> {
|
|
||||||
throw new Error('Implement me');
|
|
||||||
}
|
|
||||||
|
|
||||||
async estimateGas(_tx: TransactionWithoutGas): Promise<Big> {
|
|
||||||
throw new Error('Implement me');
|
|
||||||
}
|
|
||||||
|
|
||||||
async getTransactionCount(_address: string): Promise<string> {
|
|
||||||
throw new Error('Implement me');
|
|
||||||
}
|
|
||||||
|
|
||||||
async sendRawTx(_tx: string): Promise<string> {
|
|
||||||
throw new Error('Implement me');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +1,2 @@
|
||||||
// @flow
|
// @flow
|
||||||
export { default as BaseNode } from './base';
|
|
||||||
export { default as RPCNode } from './rpc';
|
export { default as RPCNode } from './rpc';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import Big from 'bignumber.js';
|
import Big from 'bignumber.js';
|
||||||
import BaseNode from '../base';
|
import type { INode } from '../INode';
|
||||||
import type { TransactionWithoutGas } from 'libs/transaction';
|
import type { TransactionWithoutGas } from 'libs/transaction';
|
||||||
import RPCClient, {
|
import RPCClient, {
|
||||||
getBalance,
|
getBalance,
|
||||||
|
@ -11,14 +11,13 @@ import RPCClient, {
|
||||||
} from './client';
|
} from './client';
|
||||||
import type { Token } from 'config/data';
|
import type { Token } from 'config/data';
|
||||||
|
|
||||||
export default class RpcNode extends BaseNode {
|
export default class RpcNode implements INode {
|
||||||
client: RPCClient;
|
client: RPCClient;
|
||||||
constructor(endpoint: string) {
|
constructor(endpoint: string) {
|
||||||
super();
|
|
||||||
this.client = new RPCClient(endpoint);
|
this.client = new RPCClient(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBalance(address: string): Promise<Big> {
|
getBalance(address: string): Promise<Big> {
|
||||||
return this.client.call(getBalance(address)).then(response => {
|
return this.client.call(getBalance(address)).then(response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
throw new Error(response.error.message);
|
throw new Error(response.error.message);
|
||||||
|
@ -27,7 +26,7 @@ export default class RpcNode extends BaseNode {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async estimateGas(transaction: TransactionWithoutGas): Promise<Big> {
|
estimateGas(transaction: TransactionWithoutGas): Promise<Big> {
|
||||||
return this.client.call(estimateGas(transaction)).then(response => {
|
return this.client.call(estimateGas(transaction)).then(response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
throw new Error(response.error.message);
|
throw new Error(response.error.message);
|
||||||
|
@ -36,7 +35,7 @@ export default class RpcNode extends BaseNode {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTokenBalance(address: string, token: Token): Promise<Big> {
|
getTokenBalance(address: string, token: Token): Promise<Big> {
|
||||||
return this.client.call(getTokenBalance(address, token)).then(response => {
|
return this.client.call(getTokenBalance(address, token)).then(response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
// TODO - Error handling
|
// TODO - Error handling
|
||||||
|
@ -48,7 +47,7 @@ export default class RpcNode extends BaseNode {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTokenBalances(address: string, tokens: Token[]): Promise<Big[]> {
|
getTokenBalances(address: string, tokens: Token[]): Promise<Big[]> {
|
||||||
return this.client
|
return this.client
|
||||||
.batch(tokens.map(t => getTokenBalance(address, t)))
|
.batch(tokens.map(t => getTokenBalance(address, t)))
|
||||||
.then(response => {
|
.then(response => {
|
||||||
|
@ -65,7 +64,7 @@ export default class RpcNode extends BaseNode {
|
||||||
// TODO - Error handling
|
// TODO - Error handling
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTransactionCount(address: string): Promise<string> {
|
getTransactionCount(address: string): Promise<string> {
|
||||||
return this.client.call(getTransactionCount(address)).then(response => {
|
return this.client.call(getTransactionCount(address)).then(response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
throw new Error(response.error.message);
|
throw new Error(response.error.message);
|
||||||
|
@ -74,7 +73,7 @@ export default class RpcNode extends BaseNode {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendRawTx(signedTx: string): Promise<string> {
|
sendRawTx(signedTx: string): Promise<string> {
|
||||||
return this.client.call(sendRawTx(signedTx)).then(response => {
|
return this.client.call(sendRawTx(signedTx)).then(response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
throw new Error(response.error.message);
|
throw new Error(response.error.message);
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { isValidETHAddress } from 'libs/validators';
|
||||||
import ERC20 from 'libs/erc20';
|
import ERC20 from 'libs/erc20';
|
||||||
import { toTokenUnit } from 'libs/units';
|
import { toTokenUnit } from 'libs/units';
|
||||||
import { stripHex } from 'libs/values';
|
import { stripHex } from 'libs/values';
|
||||||
import type BaseNode from 'libs/nodes/base';
|
import type { INode } from 'libs/nodes/INode';
|
||||||
import type { BaseWallet } from 'libs/wallet';
|
import type { BaseWallet } from 'libs/wallet';
|
||||||
import type { Token } from 'config/data';
|
import type { Token } from 'config/data';
|
||||||
import type EthTx from 'ethereumjs-tx';
|
import type EthTx from 'ethereumjs-tx';
|
||||||
|
@ -72,7 +72,7 @@ export function getTransactionFields(tx: EthTx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateTransaction(
|
export async function generateTransaction(
|
||||||
node: BaseNode,
|
node: INode,
|
||||||
tx: Transaction,
|
tx: Transaction,
|
||||||
wallet: BaseWallet,
|
wallet: BaseWallet,
|
||||||
token: ?Token
|
token: ?Token
|
||||||
|
|
|
@ -27,7 +27,7 @@ import { getWallets, getDesiredToken } from 'selectors/deterministicWallets';
|
||||||
import { getNodeLib } from 'selectors/config';
|
import { getNodeLib } from 'selectors/config';
|
||||||
import { getTokens } from 'selectors/wallet';
|
import { getTokens } from 'selectors/wallet';
|
||||||
|
|
||||||
import type { BaseNode } from 'libs/nodes';
|
import type { INode } from 'libs/nodes/INode';
|
||||||
import type { Token } from 'config/data';
|
import type { Token } from 'config/data';
|
||||||
|
|
||||||
// TODO: BIP39 for mnemonic wallets?
|
// TODO: BIP39 for mnemonic wallets?
|
||||||
|
@ -60,7 +60,7 @@ function* getDeterministicWallets(
|
||||||
|
|
||||||
// Grab each wallet's main network token, and update it with it
|
// Grab each wallet's main network token, and update it with it
|
||||||
function* updateWalletValues(): Generator<Yield, Return, Next> {
|
function* updateWalletValues(): Generator<Yield, Return, Next> {
|
||||||
const node: BaseNode = yield select(getNodeLib);
|
const node: INode = yield select(getNodeLib);
|
||||||
const wallets: DeterministicWalletData[] = yield select(getWallets);
|
const wallets: DeterministicWalletData[] = yield select(getWallets);
|
||||||
const calls = wallets.map(w => apply(node, node.getBalance, [w.address]));
|
const calls = wallets.map(w => apply(node, node.getBalance, [w.address]));
|
||||||
const balances = yield all(calls);
|
const balances = yield all(calls);
|
||||||
|
@ -84,7 +84,7 @@ function* updateWalletTokenValues(): Generator<Yield, Return, Next> {
|
||||||
const token = tokens.find(t => t.symbol === desiredToken);
|
const token = tokens.find(t => t.symbol === desiredToken);
|
||||||
if (!token) return;
|
if (!token) return;
|
||||||
|
|
||||||
const node: BaseNode = yield select(getNodeLib);
|
const node: INode = yield select(getNodeLib);
|
||||||
const wallets: DeterministicWalletData[] = yield select(getWallets);
|
const wallets: DeterministicWalletData[] = yield select(getWallets);
|
||||||
const calls = wallets.map(w => {
|
const calls = wallets.map(w => {
|
||||||
return apply(node, node.getTokenBalance, [w.address, token]);
|
return apply(node, node.getTokenBalance, [w.address, token]);
|
||||||
|
|
|
@ -21,7 +21,7 @@ import {
|
||||||
PrivKeyWallet,
|
PrivKeyWallet,
|
||||||
BaseWallet
|
BaseWallet
|
||||||
} from 'libs/wallet';
|
} from 'libs/wallet';
|
||||||
import { BaseNode } from 'libs/nodes';
|
import { INode } from 'libs/nodes/INode';
|
||||||
import { determineKeystoreType } from 'libs/keystore';
|
import { determineKeystoreType } from 'libs/keystore';
|
||||||
|
|
||||||
import { getNodeLib } from 'selectors/config';
|
import { getNodeLib } from 'selectors/config';
|
||||||
|
@ -35,7 +35,7 @@ function* updateAccountBalance(): Generator<Yield, Return, Next> {
|
||||||
if (!wallet) {
|
if (!wallet) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const node: BaseNode = yield select(getNodeLib);
|
const node: INode = yield select(getNodeLib);
|
||||||
const address = yield wallet.getAddress();
|
const address = yield wallet.getAddress();
|
||||||
// network request
|
// network request
|
||||||
let balance = yield apply(node, node.getBalance, [address]);
|
let balance = yield apply(node, node.getBalance, [address]);
|
||||||
|
@ -47,7 +47,7 @@ function* updateAccountBalance(): Generator<Yield, Return, Next> {
|
||||||
|
|
||||||
function* updateTokenBalances(): Generator<Yield, Return, Next> {
|
function* updateTokenBalances(): Generator<Yield, Return, Next> {
|
||||||
try {
|
try {
|
||||||
const node: BaseNode = yield select(getNodeLib);
|
const node: INode = yield select(getNodeLib);
|
||||||
const wallet: ?BaseWallet = yield select(getWalletInst);
|
const wallet: ?BaseWallet = yield select(getWalletInst);
|
||||||
const tokens = yield select(getTokens);
|
const tokens = yield select(getTokens);
|
||||||
if (!wallet || !node) {
|
if (!wallet || !node) {
|
||||||
|
@ -146,7 +146,7 @@ function* broadcastTx(
|
||||||
): Generator<Yield, Return, Next> {
|
): Generator<Yield, Return, Next> {
|
||||||
const signedTx = action.payload.signedTx;
|
const signedTx = action.payload.signedTx;
|
||||||
try {
|
try {
|
||||||
const node: BaseNode = yield select(getNodeLib);
|
const node: INode = yield select(getNodeLib);
|
||||||
const txHash = yield apply(node, node.sendRawTx, [signedTx]);
|
const txHash = yield apply(node, node.sendRawTx, [signedTx]);
|
||||||
yield put(
|
yield put(
|
||||||
showNotification('success', <TransactionSucceeded txHash={txHash} />, 0)
|
showNotification('success', <TransactionSucceeded txHash={txHash} />, 0)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import type { State } from 'reducers';
|
import type { State } from 'reducers';
|
||||||
import { BaseNode } from 'libs/nodes';
|
import type { INode } from 'libs/nodes/INode';
|
||||||
import { NODES, NETWORKS } from 'config/data';
|
import { NODES, NETWORKS } from 'config/data';
|
||||||
import type { NodeConfig, NetworkConfig, NetworkContract } from 'config/data';
|
import type { NodeConfig, NetworkConfig, NetworkContract } from 'config/data';
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ export function getNodeConfig(state: State): NodeConfig {
|
||||||
return NODES[state.config.nodeSelection];
|
return NODES[state.config.nodeSelection];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNodeLib(state: State): BaseNode {
|
export function getNodeLib(state: State): INode {
|
||||||
return NODES[state.config.nodeSelection].lib;
|
return NODES[state.config.nodeSelection].lib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue