LCOV - code coverage report
Current view: top level - lib/src - ethereum.dart (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 349 420 83.1 %
Date: 2018-01-19 11:13:13 Functions: 0 0 -

          Line data    Source code
       1             : /*
       2             :  * Package : Ethereum
       3             :  * Author : S. Hamblett <steve.hamblett@linux.com>
       4             :  * Date   : 06/011/2017
       5             :  * Copyright :  S.Hamblett
       6             :  *
       7             :  * The Ethereum client package
       8             :  */
       9             : 
      10             : part of ethereum;
      11             : 
      12             : /// The Ethereum JSON-RPC client class.
      13             : /// Further details of this interface and its API specification can be found at
      14             : /// https://github.com/ethereum/wiki/wiki/JSON-RPC#web3_clientversion.
      15             : /// The API calls return null if an ethereum error occurred.
      16             : class Ethereum {
      17           1 :   Ethereum(this._networkAdapter) {
      18           3 :     rpcClient = new EthereumRpcClient(_networkAdapter);
      19             :   }
      20             : 
      21             :   Ethereum.withConnectionParameters(EthereumINetworkAdapter adapter,
      22             :       String hostname, String scheme,
      23             :       [port = defaultHttpPort])
      24           1 :       : _networkAdapter = adapter {
      25           3 :     rpcClient = new EthereumRpcClient(_networkAdapter);
      26           1 :     connectParameters(scheme, hostname, port);
      27             :   }
      28             : 
      29             :   /// Constants
      30             :   static const String rpcHttpScheme = 'http';
      31             :   static const String rpcWsScheme = 'ws';
      32             : 
      33             :   /// Defaults
      34             :   static const int defaultHttpPort = 8545;
      35             :   static const int defaultWsPort = 8546;
      36             : 
      37             :   /// Connection parameters
      38             :   int port = defaultHttpPort;
      39             :   String host;
      40             :   Uri _uri;
      41             : 
      42           0 :   Uri get uri => _uri;
      43             : 
      44             :   /// HTTP Adapter
      45             :   EthereumINetworkAdapter _networkAdapter;
      46             : 
      47           0 :   set httpAdapter(EthereumINetworkAdapter adapter) => _networkAdapter = adapter;
      48             : 
      49             :   /// Json RPC client
      50             :   EthereumRpcClient rpcClient;
      51             : 
      52             :   /// Last error
      53             :   EthereumError lastError = new EthereumError();
      54             : 
      55             :   /// Transmission id
      56           2 :   set id(int value) => rpcClient.resetTransmissionId(value);
      57             : 
      58           4 :   int get id => rpcClient.id;
      59             : 
      60             :   /// Connection methods
      61             : 
      62             :   //// Connect using a host string of the form http://thehost.com:1234,
      63             :   /// port is optional. Scheme must be http or ws
      64             :   void connectString(String hostname) {
      65             :     if (hostname == null) {
      66           1 :       throw new ArgumentError.notNull("Ethereum::connectString - hostname");
      67             :     }
      68           1 :     final Uri uri = Uri.parse(hostname);
      69           1 :     _validateUri(uri);
      70             :   }
      71             : 
      72             :   /// Connect using a URI, port is optional
      73             :   void connectUri(Uri uri) {
      74             :     if (uri == null) {
      75           1 :       throw new ArgumentError.notNull("Ethereum::connectUri - uri");
      76             :     }
      77           1 :     _validateUri(uri);
      78             :   }
      79             : 
      80             :   /// Connect by explicitly setting the connection parameters.
      81             :   /// Scheme must be either rpcScheme or rpcWsScheme
      82             :   void connectParameters(String scheme, String hostname, [int port]) {
      83             :     if (hostname == null) {
      84           1 :       throw new ArgumentError.notNull("Ethereum::connectParameters - hostname");
      85             :     }
      86           3 :     if ((scheme != rpcHttpScheme) && (scheme != rpcWsScheme)) {
      87           1 :       throw new FormatException(
      88           1 :           "Ethereum::connectParameters - invalid scheme $scheme");
      89             :     }
      90             :     int uriPort;
      91             :     if (port != null) {
      92             :       uriPort = port;
      93             :     }
      94           2 :     final Uri uri = new Uri(scheme: scheme, host: hostname, port: uriPort);
      95           2 :     _validateUri(uri);
      96             :   }
      97             : 
      98             :   void _validateUri(Uri puri) {
      99             :     // Must have a valid scheme which must be http, host and port
     100           6 :     if (puri.hasAuthority && (puri.host.isNotEmpty)) {
     101           4 :       host = puri.host;
     102             :     } else {
     103           0 :       throw new ArgumentError.value(
     104           0 :           puri.host, "Ethereum::_validateUri - invalid host");
     105             :     }
     106             :     Uri newUri = puri;
     107           2 :     if (!puri.hasPort) {
     108           4 :       if (puri.scheme == rpcHttpScheme) {
     109           2 :         newUri = puri.replace(port: defaultHttpPort);
     110             :       } else {
     111           1 :         newUri = puri.replace(port: defaultWsPort);
     112             :       }
     113             :     }
     114           4 :     port = newUri.port;
     115           2 :     _uri = newUri;
     116           6 :     rpcClient.uri = _uri;
     117             :   }
     118             : 
     119             :   /// Print errors, default is off
     120             :   bool printError = false;
     121             : 
     122             :   /// Error processing helper
     123             :   void _processError(String method, Map res) {
     124           1 :     final Map error = res[ethErrorKey];
     125           6 :     lastError.updateError(error['code'], error['message'], rpcClient.id);
     126           1 :     if (printError) {
     127           4 :       print("ERROR::$method - ${lastError.toString()}");
     128             :     }
     129             :   }
     130             : 
     131             :   /// API methods
     132             : 
     133             :   //// Client version
     134             :   Future<String> clientVersion() async {
     135             :     final String method = EthereumRpcMethods.web3ClientVersion;
     136           3 :     final res = await rpcClient.request(method);
     137           1 :     if (res.containsKey(ethResultKey)) {
     138           1 :       return res[ethResultKey];
     139             :     }
     140           0 :     _processError(method, res);
     141             :     return null;
     142           0 :   }
     143             : 
     144             :   /// Returns Keccak-256 (not the standardized SHA3-256) of the given data.
     145             :   Future<BigInteger> sha3(BigInteger data) async {
     146             :     if (data == null) {
     147           1 :       throw new ArgumentError.notNull("Ethereum::sha3 - data");
     148             :     }
     149             :     final String method = EthereumRpcMethods.web3Sha3;
     150           2 :     final List params = [EthereumUtilities.bigIntegerToHex(data)];
     151           3 :     final res = await rpcClient.request(method, params);
     152           1 :     if (res.containsKey(ethResultKey)) {
     153           2 :       return new BigInteger(res[ethResultKey]);
     154             :     }
     155           0 :     _processError(method, res);
     156             :     return null;
     157           1 :   }
     158             : 
     159             :   /// Net version
     160             :   Future<String> netVersion() async {
     161             :     final String method = EthereumRpcMethods.netVersion;
     162           3 :     final res = await rpcClient.request(method);
     163           1 :     if (res.containsKey(ethResultKey)) {
     164           1 :       return res[ethResultKey];
     165             :     }
     166           0 :     _processError(method, res);
     167             :     return null;
     168           0 :   }
     169             : 
     170             :   /// Net listening, true when listening
     171             :   Future<bool> netListening() async {
     172             :     final String method = EthereumRpcMethods.netListening;
     173           3 :     final res = await rpcClient.request(method);
     174           1 :     if (res.containsKey(ethResultKey)) {
     175           1 :       return res[ethResultKey];
     176             :     }
     177           0 :     _processError(method, res);
     178             :     return null;
     179           0 :   }
     180             : 
     181             :   /// Net peer count,
     182             :   Future<int> netPeerCount() async {
     183             :     final String method = EthereumRpcMethods.netPeerCount;
     184           3 :     final res = await rpcClient.request(method);
     185           1 :     if (res.containsKey(ethResultKey)) {
     186           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     187             :     }
     188           0 :     _processError(method, res);
     189             :     return null;
     190           0 :   }
     191             : 
     192             :   /// Protocol version
     193             :   Future<String> protocolVersion() async {
     194             :     final String method = EthereumRpcMethods.protocolVersion;
     195           3 :     final res = await rpcClient.request(method);
     196           1 :     if (res.containsKey(ethResultKey)) {
     197           1 :       return res[ethResultKey];
     198             :     }
     199           0 :     _processError(method, res);
     200             :     return null;
     201           0 :   }
     202             : 
     203             :   /// Sync status, an object with data about the sync status if syncing or false if not.
     204             :   Future<EthereumSyncStatus> syncStatus() async {
     205             :     final String method = EthereumRpcMethods.syncing;
     206           3 :     final res = await rpcClient.request(method);
     207           1 :     if (res.containsKey(ethResultKey)) {
     208           1 :       return new EthereumSyncStatus.fromMap(res);
     209             :     }
     210           0 :     _processError(method, res);
     211             :     return null;
     212           0 :   }
     213             : 
     214             :   /// The client coinbase address.
     215             :   Future<BigInteger> coinbaseAddress() async {
     216             :     final String method = EthereumRpcMethods.coinbaseAddress;
     217           3 :     final res = await rpcClient.request(method);
     218           1 :     if (res.containsKey(ethResultKey)) {
     219           2 :       return new BigInteger(res[ethResultKey]);
     220             :     }
     221           0 :     _processError(method, res);
     222             :     return null;
     223           0 :   }
     224             : 
     225             :   /// Mining, true when mining
     226             :   Future<bool> mining() async {
     227             :     final String method = EthereumRpcMethods.mining;
     228           3 :     final res = await rpcClient.request(method);
     229           1 :     if (res.containsKey(ethResultKey)) {
     230           1 :       return res[ethResultKey];
     231             :     }
     232           0 :     _processError(method, res);
     233             :     return null;
     234           0 :   }
     235             : 
     236             :   /// Hashrate, returns the number of hashes per second that the node is mining with.
     237             :   Future<int> hashrate() async {
     238             :     final String method = EthereumRpcMethods.hashrate;
     239           3 :     final res = await rpcClient.request(method);
     240           1 :     if (res.containsKey(ethResultKey)) {
     241           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     242             :     }
     243           0 :     _processError(method, res);
     244             :     return null;
     245           0 :   }
     246             : 
     247             :   /// The current price per gas in wei.
     248             :   Future<int> gasPrice() async {
     249             :     final String method = EthereumRpcMethods.gasPrice;
     250           3 :     final res = await rpcClient.request(method);
     251           1 :     if (res.containsKey(ethResultKey)) {
     252           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     253             :     }
     254           0 :     _processError(method, res);
     255             :     return null;
     256           0 :   }
     257             : 
     258             :   /// Accounts,  a list of addresses owned by client.
     259             :   Future<List<BigInteger>> accounts() async {
     260             :     final String method = EthereumRpcMethods.accounts;
     261           3 :     final res = await rpcClient.request(method);
     262           1 :     if (res.containsKey(ethResultKey)) {
     263           2 :       return EthereumUtilities.hexToBigIntegerList(res[ethResultKey]);
     264             :     }
     265           0 :     _processError(method, res);
     266             :     return null;
     267           0 :   }
     268             : 
     269             :   /// Block number, the number of most recent block.
     270             :   Future<int> blockNumber() async {
     271             :     final String method = EthereumRpcMethods.blockNumber;
     272           3 :     final res = await rpcClient.request(method);
     273           1 :     if (res.containsKey(ethResultKey)) {
     274           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     275             :     }
     276           0 :     _processError(method, res);
     277             :     return null;
     278           0 :   }
     279             : 
     280             :   /// Get balance, the balance of the account of the given address.
     281             :   Future<int> getBalance(BigInteger accountNumber,
     282             :       EthereumDefaultBlock block) async {
     283             :     if (accountNumber == null) {
     284           1 :       throw new ArgumentError.notNull("Ethereum::getBalance - accountNumber");
     285             :     }
     286             :     if (block == null) {
     287           1 :       throw new ArgumentError.notNull("Ethereum::getBalance - block");
     288             :     }
     289             :     final String method = EthereumRpcMethods.balance;
     290           1 :     final String blockString = block.getSelection();
     291           1 :     final List params = [
     292           1 :       EthereumUtilities.bigIntegerToHex(accountNumber),
     293             :       blockString
     294             :     ];
     295           3 :     final res = await rpcClient.request(method, params);
     296           1 :     if (res.containsKey(ethResultKey)) {
     297           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     298             :     }
     299           0 :     _processError(method, res);
     300             :     return null;
     301           1 :   }
     302             : 
     303             :   /// Get Storage at, the value from a storage position at a given address.
     304             :   /// Parameters are the address of the storage, the integer position of the storage and
     305             :   // the default block parameter.
     306             :   Future<BigInteger> getStorageAt(BigInteger address, int pos,
     307             :       EthereumDefaultBlock block) async {
     308             :     if (address == null) {
     309           1 :       throw new ArgumentError.notNull("Ethereum::getStorageAt - address");
     310             :     }
     311             :     if (pos == null) {
     312           1 :       throw new ArgumentError.notNull("Ethereum::getStorageAt - pos");
     313             :     }
     314             :     if (block == null) {
     315           1 :       throw new ArgumentError.notNull("Ethereum::getStorageAt - block");
     316             :     }
     317             :     final String method = EthereumRpcMethods.storageAt;
     318           1 :     final String blockString = block.getSelection();
     319           1 :     final List params = [
     320           1 :       EthereumUtilities.bigIntegerToHex(address),
     321           1 :       EthereumUtilities.intToHex(pos),
     322             :       blockString
     323             :     ];
     324           3 :     final res = await rpcClient.request(method, params);
     325           1 :     if (res.containsKey(ethResultKey)) {
     326           2 :       return new BigInteger(res[ethResultKey]);
     327             :     }
     328           1 :     _processError(method, res);
     329             :     return null;
     330           1 :   }
     331             : 
     332             :   /// Transaction count, returns the number of transactions sent from an address.
     333             :   Future<int> getTransactionCount(int address,
     334             :       EthereumDefaultBlock block) async {
     335             :     if (address == null) {
     336           1 :       throw new ArgumentError.notNull(
     337             :           "Ethereum::getTransactionCount - address");
     338             :     }
     339             :     if (block == null) {
     340           1 :       throw new ArgumentError.notNull("Ethereum::getTransactionCount - block");
     341             :     }
     342             :     final String method = EthereumRpcMethods.transactionCount;
     343           1 :     final String blockString = block.getSelection();
     344           2 :     final List params = [EthereumUtilities.intToHex(address), blockString];
     345           3 :     final res = await rpcClient.request(method, params);
     346           1 :     if (res.containsKey(ethResultKey)) {
     347           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     348             :     }
     349           0 :     _processError(method, res);
     350             :     return null;
     351           1 :   }
     352             : 
     353             :   /// Block Transaction Count By Hash
     354             :   /// The number of transactions in a block from a block matching the given block hash.
     355             :   /// If the method returns null a count of 0 is returned, this is to distinguish between
     356             :   /// this and an error.
     357             :   Future<int> getBlockTransactionCountByHash(int blockHash) async {
     358             :     if (blockHash == null) {
     359           1 :       throw new ArgumentError.notNull(
     360             :           "Ethereum::getBlockTransactionCountByHash - blockHash");
     361             :     }
     362             :     final String method = EthereumRpcMethods.blockTransactionCountByHash;
     363           2 :     final List params = [EthereumUtilities.intToHex(blockHash)];
     364           3 :     final res = await rpcClient.request(method, params);
     365           1 :     if (res.containsKey(ethResultKey)) {
     366           1 :       if (res[ethResultKey] != null) {
     367           0 :         return EthereumUtilities.hexToInt(res[ethResultKey]);
     368             :       } else {
     369             :         return 0;
     370             :       }
     371             :     }
     372           0 :     _processError(method, res);
     373             :     return null;
     374           1 :   }
     375             : 
     376             :   /// Block Transaction Count By Number
     377             :   /// The number of transactions in a block matching the given block number.
     378             :   /// If the method returns null a count of 0 is returned, this is to distinguish between
     379             :   /// this and an error.
     380             :   Future<int> getBlockTransactionCountByNumber(
     381             :       EthereumDefaultBlock blockNumber) async {
     382             :     if (blockNumber == null) {
     383           1 :       throw new ArgumentError.notNull(
     384             :           "Ethereum::getBlockTransactionCountByNumber - blockNumber");
     385             :     }
     386             :     final String method = EthereumRpcMethods.blockTransactionCountByNumber;
     387           1 :     final String blockString = blockNumber.getSelection();
     388           1 :     final List params = [blockString];
     389           3 :     final res = await rpcClient.request(method, params);
     390           1 :     if (res.containsKey(ethResultKey)) {
     391           1 :       if (res[ethResultKey] != null) {
     392           2 :         return EthereumUtilities.hexToInt(res[ethResultKey]);
     393             :       } else {
     394             :         return 0;
     395             :       }
     396             :     }
     397           0 :     _processError(method, res);
     398             :     return null;
     399           1 :   }
     400             : 
     401             :   /// Block Uncle Count By Hash
     402             :   /// The number of uncles in a block from a block matching the given block hash.
     403             :   /// If the method returns null a count of 0 is returned, this is to distinguish between
     404             :   /// this and an error.
     405             :   Future<int> getUncleCountByHash(int blockHash) async {
     406             :     if (blockHash == null) {
     407           1 :       throw new ArgumentError.notNull(
     408             :           "Ethereum::getUncleCountByHash - blockHash");
     409             :     }
     410             :     final String method = EthereumRpcMethods.blockUncleCountByBlockHash;
     411           2 :     final List params = [EthereumUtilities.intToHex(blockHash)];
     412           3 :     final res = await rpcClient.request(method, params);
     413           1 :     if (res.containsKey(ethResultKey)) {
     414           1 :       if (res[ethResultKey] != null) {
     415           0 :         return EthereumUtilities.hexToInt(res[ethResultKey]);
     416             :       } else {
     417             :         return 0;
     418             :       }
     419             :     }
     420           0 :     _processError(method, res);
     421             :     return null;
     422           1 :   }
     423             : 
     424             :   /// Block Uncle Count By Number
     425             :   /// The number of uncles in a block matching the given block number.
     426             :   /// If the method returns null a count of 0 is returned, this is to distinguish between
     427             :   /// this and an error.
     428             :   Future<int> getUncleCountByNumber(EthereumDefaultBlock blockNumber) async {
     429             :     if (blockNumber == null) {
     430           1 :       throw new ArgumentError.notNull(
     431             :           "Ethereum::getUncleCountByNumber - blockNumber");
     432             :     }
     433             :     final String method = EthereumRpcMethods.blockUncleCountByBlockNumber;
     434           1 :     final String blockString = blockNumber.getSelection();
     435           1 :     final List params = [blockString];
     436           3 :     final res = await rpcClient.request(method, params);
     437           1 :     if (res.containsKey(ethResultKey)) {
     438           1 :       if (res[ethResultKey] != null) {
     439           2 :         return EthereumUtilities.hexToInt(res[ethResultKey]);
     440             :       } else {
     441             :         return 0;
     442             :       }
     443             :     }
     444           0 :     _processError(method, res);
     445             :     return null;
     446           1 :   }
     447             : 
     448             :   /// Get code, the code at the given address.
     449             :   Future<int> getCode(int address, EthereumDefaultBlock block) async {
     450             :     if (address == null) {
     451           1 :       throw new ArgumentError.notNull("Ethereum::getCode - address");
     452             :     }
     453             :     if (block == null) {
     454           1 :       throw new ArgumentError.notNull("Ethereum::getCode - block");
     455             :     }
     456             :     final String method = EthereumRpcMethods.code;
     457           1 :     final String blockString = block.getSelection();
     458           2 :     final List params = [EthereumUtilities.intToHex(address), blockString];
     459           3 :     final res = await rpcClient.request(method, params);
     460           1 :     if (res.containsKey(ethResultKey)) {
     461           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     462             :     }
     463           0 :     _processError(method, res);
     464             :     return null;
     465           1 :   }
     466             : 
     467             :   /// Sign
     468             :   /// The sign method calculates an Ethereum specific signature with:
     469             :   /// sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))).
     470             :   /// Note the address to sign with must be unlocked.
     471             :   Future<int> sign(int account, int message) async {
     472             :     if (account == null) {
     473           1 :       throw new ArgumentError.notNull("Ethereum::sign - account");
     474             :     }
     475             :     if (message == null) {
     476           1 :       throw new ArgumentError.notNull("Ethereum::sign - message");
     477             :     }
     478             :     final String method = EthereumRpcMethods.sign;
     479           1 :     final List params = [
     480           1 :       EthereumUtilities.intToHex(account),
     481           1 :       EthereumUtilities.intToHex(message)
     482             :     ];
     483           3 :     final res = await rpcClient.request(method, params);
     484           1 :     if (res.containsKey(ethResultKey)) {
     485           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     486             :     }
     487           0 :     _processError(method, res);
     488             :     return null;
     489           1 :   }
     490             : 
     491             :   /// Send transaction
     492             :   /// Creates new message call transaction or a contract creation, if the data field contains code.
     493             :   /// address: The address the transaction is sent from.
     494             :   /// to: (optional when creating new contract) The address the transaction is directed to.
     495             :   /// gas: (optional, default: 90000) Integer of the gas provided for the transaction execution. It will return unused gas.
     496             :   /// gasPrice: (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas
     497             :   /// value: (optional) Integer of the value send with this transaction
     498             :   /// data: The compiled code of a contract OR the hash of the invoked method signature and encoded parameters. For details see Ethereum Contract ABI
     499             :   /// nonce: optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.
     500             :   /// Returns the transaction hash, or the zero hash if the transaction is not yet available.
     501             :   Future<int> sendTransaction(int address, int data,
     502             :       {int to, int gas: 9000, int gasPrice, int value, int nonce}) async {
     503             :     if (address == null) {
     504           1 :       throw new ArgumentError.notNull("Ethereum::sendTransaction - address");
     505             :     }
     506             :     if (data == null) {
     507           1 :       throw new ArgumentError.notNull("Ethereum::sendTransaction - data");
     508             :     }
     509             :     final String method = EthereumRpcMethods.sendTransaction;
     510           1 :     Map<String, String> paramBlock = {
     511           1 :       "from": EthereumUtilities.intToHex(address),
     512           1 :       "to": to == null ? null : EthereumUtilities.intToHex(to),
     513           1 :       "gas": EthereumUtilities.intToHex(gas),
     514             :       "gasPrice":
     515           1 :       gasPrice == null ? null : EthereumUtilities.intToHex(gasPrice),
     516           1 :       "value": value == null ? null : EthereumUtilities.intToHex(value),
     517           1 :       "data": EthereumUtilities.intToHex(data),
     518           1 :       "nonce": nonce == null ? null : EthereumUtilities.intToHex(nonce)
     519             :     };
     520           1 :     paramBlock = EthereumUtilities.removeNull(paramBlock);
     521           1 :     final dynamic params = [paramBlock];
     522           3 :     final res = await rpcClient.request(method, params);
     523           1 :     if (res.containsKey(ethResultKey)) {
     524           0 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     525             :     }
     526           1 :     _processError(method, res);
     527             :     return null;
     528           1 :   }
     529             : 
     530             :   /// Send raw transaction
     531             :   /// Creates new message call transaction or a contract creation for signed transactions.
     532             :   /// Takes the signed transaction data.
     533             :   /// Returns the transaction hash, or the zero hash if the transaction is not yet available.
     534             :   Future<int> sendRawTransaction(int signedTransaction) async {
     535             :     if (signedTransaction == null) {
     536           1 :       throw new ArgumentError.notNull(
     537             :           "Ethereum::sendRawTransaction - signedTransaction");
     538             :     }
     539             :     final String method = EthereumRpcMethods.sendRawTransaction;
     540           2 :     final dynamic params = [EthereumUtilities.intToHex(signedTransaction)];
     541           3 :     final res = await rpcClient.request(method, params);
     542           1 :     if (res.containsKey(ethResultKey)) {
     543           0 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     544             :     }
     545           1 :     _processError(method, res);
     546             :     return null;
     547           1 :   }
     548             : 
     549             :   /// Call
     550             :   /// Executes a new message call immediately without creating a transaction on the block chain.
     551             :   /// address: The address the transaction is sent to.
     552             :   /// from: (optional) The address the transaction is sent from.
     553             :   /// gas: (optional) Integer of the gas provided for the transaction execution. eth_call consumes zero gas,
     554             :   /// but this parameter may be needed by some executions.
     555             :   /// gasPrice: (optional) Integer of the gasPrice used for each paid gas
     556             :   /// value: (optional) Integer of the value send with this transaction
     557             :   /// data: (optional) Hash of the method signature and encoded parameters. For details see Ethereum Contract ABI
     558             :   /// block: default block parameter
     559             :   /// Returns the return value of executed contract.
     560             :   Future<int> call(int address, EthereumDefaultBlock block,
     561             :       {int from, int gas, int gasPrice, int value, int data}) async {
     562             :     if (address == null) {
     563           1 :       throw new ArgumentError.notNull("Ethereum::call - address");
     564             :     }
     565             :     if (block == null) {
     566           1 :       throw new ArgumentError.notNull("Ethereum::call - block");
     567             :     }
     568             :     final String method = EthereumRpcMethods.call;
     569           1 :     final String blockString = block.getSelection();
     570           1 :     Map<String, String> paramBlock = {
     571           1 :       "from": from == null ? null : EthereumUtilities.intToHex(from),
     572           1 :       "to": EthereumUtilities.intToHex(address),
     573           1 :       "gas": gas == null ? null : EthereumUtilities.intToHex(gas),
     574             :       "gasPrice":
     575           1 :       gasPrice == null ? null : EthereumUtilities.intToHex(gasPrice),
     576           1 :       "value": value == null ? null : EthereumUtilities.intToHex(value),
     577           1 :       "data": data == null ? null : EthereumUtilities.intToHex(data)
     578             :     };
     579           1 :     paramBlock = EthereumUtilities.removeNull(paramBlock);
     580           1 :     final dynamic params = [paramBlock, blockString];
     581           3 :     final res = await rpcClient.request(method, params);
     582           1 :     if (res.containsKey(ethResultKey)) {
     583           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     584             :     }
     585           1 :     _processError(method, res);
     586             :     return null;
     587           1 :   }
     588             : 
     589             :   /// Estimate gas
     590             :   /// Makes a call or transaction, which won't be added to the blockchain and returns the used gas,
     591             :   /// which can be used for estimating the used gas.
     592             :   /// See eth_call parameters, expect that all properties are optional. If no gas limit is specified geth
     593             :   /// uses the block gas limit from the pending block as an upper bound. As a result the returned estimate
     594             :   /// might not be enough to executed the call/transaction when the amount of gas is higher than the
     595             :   /// pending block gas limit.
     596             :   /// Returns the amount of gas used.
     597             :   Future<int> estimateGas({int address,
     598             :     int from,
     599             :     int gas,
     600             :     int gasPrice,
     601             :     int value,
     602             :     int data}) async {
     603           1 :     Map<String, String> paramBlock = {
     604           1 :       "from": from == null ? null : EthereumUtilities.intToHex(from),
     605           1 :       "to": address == null ? null : EthereumUtilities.intToHex(address),
     606           1 :       "gas": gas == null ? null : EthereumUtilities.intToHex(gas),
     607             :       "gasPrice":
     608           1 :       gasPrice == null ? null : EthereumUtilities.intToHex(gasPrice),
     609           1 :       "value": value == null ? null : EthereumUtilities.intToHex(value),
     610           1 :       "data": data == null ? null : EthereumUtilities.intToHex(data)
     611             :     };
     612           1 :     paramBlock = EthereumUtilities.removeNull(paramBlock);
     613           1 :     final dynamic params = [paramBlock];
     614             :     final String method = EthereumRpcMethods.estimateGas;
     615           3 :     final res = await rpcClient.request(method, params);
     616           1 :     if (res.containsKey(ethResultKey)) {
     617           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     618             :     }
     619           0 :     _processError(method, res);
     620             :     return null;
     621           0 :   }
     622             : 
     623             :   /// Get block by hash
     624             :   /// Returns information about a block by hash
     625             :   /// Hash of a block and a boolean, if true it returns the full transaction objects,
     626             :   /// if false only the hashes of the transactions, defaults to true.
     627             :   /// Returns A block object, or null when no block was found :
     628             :   Future<EthereumBlock> getBlockByHash(BigInteger blockHash,
     629             :       [bool full = true]) async {
     630             :     if (blockHash == null) {
     631           1 :       throw new ArgumentError.notNull("Ethereum::getBlockByHash - blockHash");
     632             :     }
     633           2 :     final dynamic params = [EthereumUtilities.bigIntegerToHex(blockHash), full];
     634             :     final String method = EthereumRpcMethods.getBlockByHash;
     635           3 :     final res = await rpcClient.request(method, params);
     636           1 :     if (res.containsKey(ethResultKey)) {
     637           2 :       return new EthereumBlock.fromMap(res[ethResultKey]);
     638             :     }
     639           0 :     _processError(method, res);
     640             :     return null;
     641           1 :   }
     642             : 
     643             :   /// Get block by number
     644             :   /// Returns information about a block by block number.
     645             :   /// blockNumber - defualt block parameter
     646             :   /// as in the default block parameter.
     647             :   /// A boolean, if true it returns the full transaction objects,
     648             :   /// if false only the hashes of the transactions, defaults to true.
     649             :   /// Returns See getBlockByHash
     650             :   Future<EthereumBlock> getBlockByNumber(EthereumDefaultBlock blockNumber,
     651             :       [bool full = true]) async {
     652             :     if (blockNumber == null) {
     653           1 :       throw new ArgumentError.notNull(
     654             :           "Ethereum::getBlockByNumber - blockNumber");
     655             :     }
     656           1 :     final String blockString = blockNumber.getSelection();
     657           1 :     final dynamic params = [blockString, full];
     658             :     final String method = EthereumRpcMethods.getBlockByNumber;
     659           3 :     final res = await rpcClient.request(method, params);
     660           1 :     if (res.containsKey(ethResultKey)) {
     661           2 :       return new EthereumBlock.fromMap(res[ethResultKey]);
     662             :     }
     663           0 :     _processError(method, res);
     664             :     return null;
     665           1 :   }
     666             : 
     667             :   /// Get transaction by hash
     668             :   /// Returns the information about a transaction requested by transaction hash.
     669             :   /// Hash of a transaction
     670             :   /// Returns a transaction object, or null when no transaction was found:
     671             :   Future<EthereumTransaction> getTransactionByHash(BigInteger hash) async {
     672             :     if (hash == null) {
     673           1 :       throw new ArgumentError.notNull("Ethereum::getTransactionByHash - hash");
     674             :     }
     675           2 :     final dynamic params = [EthereumUtilities.bigIntegerToHex(hash)];
     676             :     final String method = EthereumRpcMethods.getTransactionByHash;
     677           3 :     final res = await rpcClient.request(method, params);
     678           1 :     if (res.containsKey(ethResultKey)) {
     679           2 :       return new EthereumTransaction.fromMap(res[ethResultKey]);
     680             :     }
     681           0 :     _processError(method, res);
     682             :     return null;
     683           1 :   }
     684             : 
     685             :   /// Get transaction by block hash and index.
     686             :   /// Returns information about a transaction by block hash and transaction index position.
     687             :   /// Hash of a block and integer of the transaction index position.
     688             :   /// Returns see getTransactionByHash.
     689             :   Future<EthereumTransaction> getTransactionByBlockHashAndIndex(
     690             :       BigInteger blockHash, int index) async {
     691             :     if (blockHash == null) {
     692           1 :       throw new ArgumentError.notNull(
     693             :           "Ethereum::getTransactionByBlockHashAndIndex - blockHash");
     694             :     }
     695             :     if (index == null) {
     696           1 :       throw new ArgumentError.notNull(
     697             :           "Ethereum::getTransactionByBlockHashAndIndex - index");
     698             :     }
     699           1 :     final dynamic params = [
     700           1 :       EthereumUtilities.bigIntegerToHex(blockHash),
     701           1 :       EthereumUtilities.intToHex(index)
     702             :     ];
     703             :     final String method = EthereumRpcMethods.getTransactionByBlockHashAndIndex;
     704           3 :     final res = await rpcClient.request(method, params);
     705           1 :     if (res.containsKey(ethResultKey)) {
     706           2 :       return new EthereumTransaction.fromMap(res[ethResultKey]);
     707             :     }
     708           0 :     _processError(method, res);
     709             :     return null;
     710           1 :   }
     711             : 
     712             :   /// Get transaction by block number and index.
     713             :   /// Returns information about a transaction by block number and transaction index position.
     714             :   /// A block number as in the default block parameter.
     715             :   /// Returns see getTransactionByHash.
     716             :   Future<EthereumTransaction> getTransactionByBlockNumberAndIndex(
     717             :       EthereumDefaultBlock blockNumber, int index) async {
     718             :     if (blockNumber == null) {
     719           1 :       throw new ArgumentError.notNull(
     720             :           "Ethereum::getTransactionByBlockNumberAndIndex - blockNumber");
     721             :     }
     722             :     if (index == null) {
     723           1 :       throw new ArgumentError.notNull(
     724             :           "Ethereum::getTransactionByBlockNumberAndIndex - index");
     725             :     }
     726           1 :     final String blockNumberString = blockNumber.getSelection();
     727           1 :     final dynamic params = [
     728             :       blockNumberString,
     729           1 :       EthereumUtilities.intToHex(index)
     730             :     ];
     731             :     final String method =
     732             :         EthereumRpcMethods.getTransactionByBlockNumberAndIndex;
     733           3 :     final res = await rpcClient.request(method, params);
     734           1 :     if (res.containsKey(ethResultKey)) {
     735           2 :       return new EthereumTransaction.fromMap(res[ethResultKey]);
     736             :     }
     737           0 :     _processError(method, res);
     738             :     return null;
     739           1 :   }
     740             : 
     741             :   /// Get transaction receipt
     742             :   /// Returns the receipt of a transaction by transaction hash.
     743             :   /// Note That the receipt is not available for pending transactions.
     744             :   /// Hash of a transaction
     745             :   /// Returns a transaction receipt object, or null when no receipt was found:
     746             :   Future<EthereumTransactionReceipt> getTransactionReceipt(
     747             :       BigInteger transactionHash) async {
     748             :     if (transactionHash == null) {
     749           1 :       throw new ArgumentError.notNull(
     750             :           "Ethereum::getTransactionReceipt - transactionHash");
     751             :     }
     752           2 :     final dynamic params = [EthereumUtilities.bigIntegerToHex(transactionHash)];
     753             :     final String method = EthereumRpcMethods.getTransactionReceipt;
     754           3 :     final res = await rpcClient.request(method, params);
     755           1 :     if (res.containsKey(ethResultKey)) {
     756           2 :       return new EthereumTransactionReceipt.fromMap(res[ethResultKey]);
     757             :     }
     758           0 :     _processError(method, res);
     759             :     return null;
     760           1 :   }
     761             : 
     762             :   /// Get uncle by block hash and index.
     763             :   /// Returns information about an uncle by block hash and uncle index position.
     764             :   /// Note: An uncle doesn't contain individual transactions.
     765             :   /// Hash of a block and integer of the uncle index position.
     766             :   /// Returns see getBlockByHash.
     767             :   Future<EthereumBlock> getUncleByBlockHashAndIndex(BigInteger blockHash,
     768             :       int index) async {
     769             :     if (blockHash == null) {
     770           1 :       throw new ArgumentError.notNull(
     771             :           "Ethereum::getUncleByBlockHashAndIndex - blockHash");
     772             :     }
     773             :     if (index == null) {
     774           1 :       throw new ArgumentError.notNull(
     775             :           "Ethereum::getUncleByBlockHashAndIndex - index");
     776             :     }
     777           1 :     final dynamic params = [
     778           1 :       EthereumUtilities.bigIntegerToHex(blockHash),
     779           1 :       EthereumUtilities.intToHex(index)
     780             :     ];
     781             :     final String method = EthereumRpcMethods.getUncleByBlockHashAndIndex;
     782           3 :     final res = await rpcClient.request(method, params);
     783           1 :     if (res.containsKey(ethResultKey)) {
     784           2 :       return new EthereumBlock.fromMap(res[ethResultKey]);
     785             :     }
     786           0 :     _processError(method, res);
     787             :     return null;
     788           1 :   }
     789             : 
     790             :   /// Get uncle by block number and index.
     791             :   /// Returns information about an uncle by block number and uncle index position.
     792             :   /// Note: An uncle doesn't contain individual transactions.
     793             :   /// A block number as in the default block parameter.
     794             :   /// Returns see getBlockByHash.
     795             :   Future<EthereumBlock> getUncleByBlockNumberAndIndex(
     796             :       EthereumDefaultBlock blockNumber,
     797             :       int index) async {
     798             :     if (blockNumber == null) {
     799           1 :       throw new ArgumentError.notNull(
     800             :           "Ethereum::getUncleByBlockNumberAndIndex - blockNumber");
     801             :     }
     802             :     if (index == null) {
     803           1 :       throw new ArgumentError.notNull(
     804             :           "Ethereum::getUncleByBlockNumberAndIndex - index");
     805             :     }
     806           1 :     final String blockNumberString = blockNumber.getSelection();
     807           1 :     final dynamic params = [
     808             :       blockNumberString,
     809           1 :       EthereumUtilities.intToHex(index)
     810             :     ];
     811             :     final String method = EthereumRpcMethods.getUncleByBlockNumberAndIndex;
     812           3 :     final res = await rpcClient.request(method, params);
     813           1 :     if (res.containsKey(ethResultKey)) {
     814           2 :       return new EthereumBlock.fromMap(res[ethResultKey]);
     815             :     }
     816           0 :     _processError(method, res);
     817             :     return null;
     818           1 :   }
     819             : 
     820             :   /// New filter
     821             :   /// Creates a filter object, based on filter options, to notify when the state changes (logs).
     822             :   /// To check if the state has changed, call getFilterChanges.
     823             :   /// note on specifying topic filters:
     824             :   /// Topics are order-dependent. A transaction with a log with topics [A, B] will be matched by the following topic filters:
     825             :   /// [] "anything"
     826             :   /// ['A'] "A in first position (and anything after)"
     827             :   /// [null, B] "anything in first position AND B in second position (and anything after)"
     828             :   /// [A, B] "A in first position AND B in second position (and anything after)"
     829             :   /// [[A, B], [A, B]] "(A OR B) in first position AND (A OR B) in second position (and anything after)"
     830             :   /// fromBlock: - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending",
     831             :   /// "earliest" for not yet mined transactions.
     832             :   /// toBlock: - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending", "earliest" for not
     833             :   /// yet mined transactions.
     834             :   /// address: - (optional) Contract address or a list of addresses from which logs should originate.
     835             :   /// topics: - (optional) topics. Topics are order-dependent.
     836             :   /// Note: the user must build this structure using the utilities in the EthereumUtilities class. See the Ethereum
     837             :   /// Wiki RPC page for examples.
     838             :   /// Returns a filter id.
     839             :   Future<int> newFilter({EthereumDefaultBlock fromBlock,
     840             :     EthereumDefaultBlock toBlock,
     841             :     dynamic address,
     842             :     List<BigInteger> topics}) async {
     843           1 :     final String fromBlockString = fromBlock.getSelection();
     844           1 :     final String toBlockString = toBlock.getSelection();
     845           1 :     final Map params = {"toBlock": toBlockString, "fromBlock": fromBlockString};
     846             :     if (address != null) {
     847           1 :       if (address is List) {
     848             :         final List<String> addresses =
     849           1 :         EthereumUtilities.bigIntegerToHexList(address);
     850           1 :         params["address"] = addresses;
     851             :       } else {
     852           2 :         params["address"] = (EthereumUtilities.bigIntegerToHex(address));
     853             :       }
     854             :     }
     855             :     if (topics != null) {
     856           2 :       params["topics"] = EthereumUtilities.bigIntegerToHexList(topics);
     857             :     }
     858           1 :     final List paramBlock = [params];
     859             :     final String method = EthereumRpcMethods.newFilter;
     860           3 :     final res = await rpcClient.request(method, paramBlock);
     861           1 :     if (res.containsKey(ethResultKey)) {
     862           0 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     863             :     }
     864           1 :     _processError(method, res);
     865             :     return null;
     866           0 :   }
     867             : 
     868             :   /// New block filter
     869             :   /// Creates a filter in the node, to notify when a new block arrives.
     870             :   /// To check if the state has changed, call getFilterChanges.
     871             :   /// Returns a filter id.
     872             :   Future<int> newBlockFilter() async {
     873           1 :     final List params = [];
     874             :     final String method = EthereumRpcMethods.newBlockFilter;
     875           3 :     final res = await rpcClient.request(method, params);
     876           1 :     if (res.containsKey(ethResultKey)) {
     877           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     878             :     }
     879           0 :     _processError(method, res);
     880             :     return null;
     881           0 :   }
     882             : 
     883             :   /// New pending transaction filter
     884             :   /// Creates a filter in the node, to notify when a new pending transaction arrives.
     885             :   /// To check if the state has changed, call getFilterChanges.
     886             :   /// Returns a filter id.
     887             :   Future<int> newPendingTransactionFilter() async {
     888           1 :     final List params = [];
     889             :     final String method = EthereumRpcMethods.newPendingTransactionFilter;
     890           3 :     final res = await rpcClient.request(method, params);
     891           1 :     if (res.containsKey(ethResultKey)) {
     892           2 :       return EthereumUtilities.hexToInt(res[ethResultKey]);
     893             :     }
     894           0 :     _processError(method, res);
     895             :     return null;
     896           0 :   }
     897             : 
     898             :   /// Uninstall filter
     899             :   /// Uninstalls a filter with given id. Should always be called when watch is no longer needed.
     900             :   /// Additionally Filters timeout when they aren't requested with getFilterChanges for a period of time.
     901             :   /// Filter id
     902             :   /// Returns true if the filter was successfully uninstalled, otherwise false.
     903             :   Future<bool> uninstallFilter(int filterId) async {
     904             :     if (filterId == null) {
     905           1 :       throw new ArgumentError.notNull("Ethereum::uninstallFilter - filterId");
     906             :     }
     907           2 :     final List params = [EthereumUtilities.intToHex(filterId)];
     908             :     final String method = EthereumRpcMethods.uninstallFilter;
     909           3 :     final res = await rpcClient.request(method, params);
     910           1 :     if (res.containsKey(ethResultKey)) {
     911           1 :       return res[ethResultKey];
     912             :     }
     913           0 :     _processError(method, res);
     914             :     return null;
     915           1 :   }
     916             : 
     917             :   /// Get filter changes
     918             :   /// Polling method for a filter, which returns an list of logs which occurred since last poll.
     919             :   /// Filter Id
     920             :   /// Returns an EthereumFilter object or null
     921             :   Future<EthereumFilter> getFilterChanges(int filterId) async {
     922             :     if (filterId == null) {
     923           1 :       throw new ArgumentError.notNull("Ethereum::getFilterChanges - filterId");
     924             :     }
     925           2 :     final List params = [EthereumUtilities.intToHex(filterId)];
     926             :     final String method = EthereumRpcMethods.getFilterChanges;
     927           3 :     final res = await rpcClient.request(method, params);
     928           1 :     if (res.containsKey(ethResultKey)) {
     929           0 :       return new EthereumFilter.fromMap(res[ethResultKey]);
     930             :     }
     931           1 :     _processError(method, res);
     932             :     return null;
     933           1 :   }
     934             : 
     935             :   /// Get filter logs
     936             :   /// Filter Id
     937             :   /// Returns see getFilterChanges
     938             :   Future<EthereumFilter> getFilterLogs(int filterId) async {
     939             :     if (filterId == null) {
     940           1 :       throw new ArgumentError.notNull("Ethereum::getFilterLogs - filterId");
     941             :     }
     942           2 :     final List params = [EthereumUtilities.intToHex(filterId)];
     943             :     final String method = EthereumRpcMethods.getFilterLogs;
     944           3 :     final res = await rpcClient.request(method, params);
     945           1 :     if (res.containsKey(ethResultKey)) {
     946           0 :       return new EthereumFilter.fromMap(res[ethResultKey]);
     947             :     }
     948           1 :     _processError(method, res);
     949             :     return null;
     950           1 :   }
     951             : 
     952             :   /// Get logs
     953             :   /// The filter definition, see newFilter parameters.
     954             :   /// Returns see getFilterChanges
     955             :   Future<EthereumFilter> getLogs({EthereumDefaultBlock fromBlock,
     956             :     EthereumDefaultBlock toBlock,
     957             :     dynamic address,
     958             :     List topics}) async {
     959           1 :     final String fromBlockString = fromBlock.getSelection();
     960           1 :     final String toBlockString = toBlock.getSelection();
     961           1 :     final Map params = {"toBlock": toBlockString, "fromBlock": fromBlockString};
     962             :     if (address != null) {
     963           1 :       if (address is List) {
     964             :         final List<String> addresses =
     965           0 :         EthereumUtilities.bigIntegerToHexList(address);
     966           0 :         params["address"] = addresses;
     967             :       } else {
     968           2 :         params["address"] = (EthereumUtilities.bigIntegerToHex(address));
     969             :       }
     970             :     }
     971             :     if (topics != null) {
     972           2 :       params["topics"] = EthereumUtilities.bigIntegerToHexList(topics);
     973             :     }
     974           1 :     final List paramBlock = [params];
     975             :     final String method = EthereumRpcMethods.getLogs;
     976           3 :     final res = await rpcClient.request(method, paramBlock);
     977           1 :     if (res.containsKey(ethResultKey)) {
     978           0 :       return new EthereumFilter.fromMap(res[ethResultKey]);
     979             :     }
     980           1 :     _processError(method, res);
     981             :     return null;
     982           0 :   }
     983             : 
     984             :   /// Get work
     985             :   /// Returns the hash of the current block, the seedHash, and the boundary condition to be met ("target").
     986             :   /// Returns an EthereumWork object or null
     987             :   Future<EthereumWork> getWork() async {
     988           1 :     final List paramBlock = [];
     989             :     final String method = EthereumRpcMethods.getWork;
     990           3 :     final res = await rpcClient.request(method, paramBlock);
     991           1 :     if (res.containsKey(ethResultKey)) {
     992           2 :       return new EthereumWork.fromList(res[ethResultKey]);
     993             :     }
     994           0 :     _processError(method, res);
     995             :     return null;
     996           0 :   }
     997             : 
     998             :   /// Submit work
     999             :   /// Used for submitting a proof-of-work solution.
    1000             :   /// The nonce found
    1001             :   /// The header's pow-hash
    1002             :   /// The mix digest
    1003             :   /// Returns  true if the provided solution is valid, otherwise false.
    1004             :   Future<bool> submitWork(BigInteger nonce, BigInteger powHash,
    1005             :       BigInteger digest) async {
    1006             :     if (nonce == null) {
    1007           1 :       throw new ArgumentError.notNull("Ethereum::submitWork - nonce");
    1008             :     }
    1009             :     if (powHash == null) {
    1010           1 :       throw new ArgumentError.notNull("Ethereum::submitWork - powHash");
    1011             :     }
    1012             :     if (digest == null) {
    1013           1 :       throw new ArgumentError.notNull("Ethereum::submitWork - digest");
    1014             :     }
    1015           1 :     final List params = [
    1016           1 :       EthereumUtilities.bigIntegerToHex(nonce),
    1017           1 :       EthereumUtilities.bigIntegerToHex(powHash),
    1018           1 :       EthereumUtilities.bigIntegerToHex(digest)
    1019             :     ];
    1020             :     final String method = EthereumRpcMethods.submitWork;
    1021           3 :     final res = await rpcClient.request(method, params);
    1022           1 :     if (res.containsKey(ethResultKey)) {
    1023           1 :       return res[ethResultKey];
    1024             :     }
    1025           0 :     _processError(method, res);
    1026             :     return null;
    1027           1 :   }
    1028             : 
    1029             :   /// Submit hash rate
    1030             :   /// Used for submitting mining hashrate.
    1031             :   /// Hash rate
    1032             :   /// Id, a random hexadecimal(32 bytes) string identifying the client
    1033             :   /// Returns true if submitting went through successfully and false otherwise.
    1034             :   Future<bool> submitHashrate(BigInteger hashRate, String id) async {
    1035             :     if (hashRate == null) {
    1036           1 :       throw new ArgumentError.notNull("Ethereum::submitHashRate - hashRate");
    1037             :     }
    1038             :     if (id == null) {
    1039           1 :       throw new ArgumentError.notNull("Ethereum::submitHashRate - id");
    1040             :     }
    1041           2 :     final List params = [EthereumUtilities.bigIntegerToHex(hashRate), id];
    1042             :     final String method = EthereumRpcMethods.submitHashrate;
    1043           3 :     final res = await rpcClient.request(method, params);
    1044           1 :     if (res.containsKey(ethResultKey)) {
    1045           1 :       return res[ethResultKey];
    1046             :     }
    1047           0 :     _processError(method, res);
    1048             :     return null;
    1049           1 :   }
    1050             : 
    1051             :   /// SHH version
    1052             :   /// Returns the current whisper protocol version.
    1053             :   Future<String> shhVersion() async {
    1054           1 :     final List params = [];
    1055             :     final String method = EthereumRpcMethods.shhVersion;
    1056           3 :     final res = await rpcClient.request(method, params);
    1057           1 :     if (res.containsKey(ethResultKey)) {
    1058           1 :       return res[ethResultKey];
    1059             :     }
    1060           0 :     _processError(method, res);
    1061             :     return null;
    1062           0 :   }
    1063             : 
    1064             :   /// SHH post
    1065             :   /// Sends a whisper message
    1066             :   /// from: - (optional) The identity of the sender.
    1067             :   /// to: - (optional) The identity of the receiver. When present whisper will encrypt the message so that only
    1068             :   ///  the receiver can decrypt it.
    1069             :   /// topics: - List of topics, for the receiver to identify messages.
    1070             :   /// payload: - The payload of the message.
    1071             :   /// priority: - The integer of the priority in a range from ... (?).
    1072             :   /// ttl: - integer of the time to live in seconds.
    1073             :   /// Returns true if the message was send, otherwise false.
    1074             :   Future<bool> shhPost(List<BigInteger> topics, BigInteger payload,
    1075             :       int priority, int ttl,
    1076             :       {BigInteger to, BigInteger from}) async {
    1077             :     if (topics == null) {
    1078           1 :       throw new ArgumentError.notNull("Ethereum::shhPost - topics");
    1079             :     }
    1080             :     if (payload == null) {
    1081           1 :       throw new ArgumentError.notNull("Ethereum::shhPost - payload");
    1082             :     }
    1083             :     if (priority == null) {
    1084           1 :       throw new ArgumentError.notNull("Ethereum::shhPost - priority");
    1085             :     }
    1086             :     if (ttl == null) {
    1087           1 :       throw new ArgumentError.notNull("Ethereum::shhPost - ttl");
    1088             :     }
    1089           1 :     Map<String, dynamic> params = {
    1090           1 :       "topics": EthereumUtilities.bigIntegerToHexList(topics),
    1091           1 :       "payload": EthereumUtilities.bigIntegerToHex(payload),
    1092           1 :       "priority": EthereumUtilities.intToHex(priority),
    1093             :       "ttl": ttl,
    1094           1 :       "to": EthereumUtilities.bigIntegerToHex(to),
    1095           1 :       "from": EthereumUtilities.bigIntegerToHex(from)
    1096             :     };
    1097           1 :     params = EthereumUtilities.removeNull(params);
    1098           1 :     final List paramBlock = [params];
    1099             :     final String method = EthereumRpcMethods.shhPost;
    1100           3 :     final res = await rpcClient.request(method, paramBlock);
    1101           1 :     if (res.containsKey(ethResultKey)) {
    1102           0 :       return res[ethResultKey];
    1103             :     }
    1104           1 :     _processError(method, res);
    1105             :     return null;
    1106           1 :   }
    1107             : }

Generated by: LCOV version 1.12