2017-08-08 03:45:08 +00:00
|
|
|
// @flow
|
|
|
|
import { randomBytes } from 'crypto';
|
2017-08-23 06:57:18 +00:00
|
|
|
import ERC20 from 'libs/erc20';
|
2017-08-08 03:45:08 +00:00
|
|
|
import { hexEncodeData } from './utils';
|
|
|
|
import type {
|
|
|
|
RPCRequest,
|
|
|
|
JsonRpcResponse,
|
|
|
|
CallRequest,
|
|
|
|
GetBalanceRequest,
|
2017-08-23 06:57:18 +00:00
|
|
|
GetTokenBalanceRequest,
|
2017-08-11 21:54:10 +00:00
|
|
|
EstimateGasRequest,
|
|
|
|
GetTransactionCountRequest
|
2017-08-08 03:45:08 +00:00
|
|
|
} from './types';
|
2017-08-23 06:57:18 +00:00
|
|
|
import type { Token } from 'config/data';
|
2017-08-08 03:45:08 +00:00
|
|
|
|
|
|
|
// FIXME is it safe to generate that much entropy?
|
|
|
|
function id(): string {
|
|
|
|
return randomBytes(16).toString('hex');
|
|
|
|
}
|
|
|
|
|
|
|
|
export function estimateGas<T: *>(transaction: T): EstimateGasRequest {
|
|
|
|
return {
|
|
|
|
id: id(),
|
|
|
|
jsonrpc: '2.0',
|
|
|
|
method: 'eth_estimateGas',
|
|
|
|
params: [transaction]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getBalance(address: string): GetBalanceRequest {
|
|
|
|
return {
|
|
|
|
id: id(),
|
|
|
|
jsonrpc: '2.0',
|
|
|
|
method: 'eth_getBalance',
|
|
|
|
params: [hexEncodeData(address), 'pending']
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function ethCall<T: *>(transaction: T): CallRequest {
|
|
|
|
return {
|
|
|
|
id: id(),
|
|
|
|
jsonrpc: '2.0',
|
|
|
|
method: 'eth_call',
|
|
|
|
params: [transaction, 'pending']
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-08-11 21:54:10 +00:00
|
|
|
export function getTransactionCount(
|
|
|
|
address: string
|
|
|
|
): GetTransactionCountRequest {
|
|
|
|
return {
|
|
|
|
id: id(),
|
|
|
|
jsonrpc: '2.0',
|
|
|
|
method: 'eth_getTransactionCount',
|
|
|
|
params: [address, 'pending']
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-08-23 06:57:18 +00:00
|
|
|
export function getTokenBalance(
|
|
|
|
address: string,
|
|
|
|
token: Token
|
|
|
|
): GetTokenBalanceRequest {
|
|
|
|
return {
|
|
|
|
id: id(),
|
|
|
|
jsonrpc: '2.0',
|
|
|
|
method: 'eth_call',
|
|
|
|
params: [
|
|
|
|
{
|
|
|
|
to: token.address,
|
|
|
|
data: ERC20.balanceOf(address)
|
|
|
|
},
|
|
|
|
'pending'
|
|
|
|
]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-08-08 03:45:08 +00:00
|
|
|
export default class RPCClient {
|
|
|
|
endpoint: string;
|
|
|
|
constructor(endpoint: string) {
|
|
|
|
this.endpoint = endpoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
async call(request: RPCRequest): Promise<JsonRpcResponse> {
|
|
|
|
return fetch(this.endpoint, {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
},
|
|
|
|
body: JSON.stringify(request)
|
|
|
|
}).then(r => r.json());
|
|
|
|
}
|
|
|
|
|
|
|
|
async batch(requests: RPCRequest[]): Promise<JsonRpcResponse[]> {
|
|
|
|
return fetch(this.endpoint, {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
},
|
|
|
|
body: JSON.stringify(requests)
|
|
|
|
}).then(r => r.json());
|
|
|
|
}
|
|
|
|
}
|