L1 client development: how to trigger eth_getBalance update?

I am developing a new L1 client and working on being able to send transactions through MetaMask. My system has transactions but otherwise it’s rather different from Ethereum, e.g. it doesn’t have blocks, so I have to make a few tweaks. I’ve basically tried to reverse-engineer the API implementation, currently I’ve implemented the following JSON RPC methods:

eth_blockNumber, eth_chainId, eth_estimateGas, eth_gasPrice, eth_getBalance, eth_getBlockByHash, eth_getBlockByNumber, eth_getCode, eth_getTransactionCount, eth_getTransactionReceipt, eth_sendRawTransaction, net_version, web3_clientVersion

The returned blocks consist mostly of dummy data, but I can still get a transaction to show up as confirmed in MetaMask. The issue that I’m having is that the balances don’t update after a succesful transaction. Basically, the issue is that no eth_getBalance are triggered. I tried to trick MetaMask into performing eth_getBalance queries by incrementing the block number, but it doesn’t seem to trigger new requests even if I increment the block number on every eth_getBalance query. I’m logging all requests, including failed ones, so I’m fairly sure that I would see if there were failed calls to eth_getBalance or any JSON RPC methods I hadn’t implemented yet.

As far as I can tell, the call chain for submitting a transaction seems to be: eth_sendRawTransaction > eth_getTransactionReceipt > eth_getBlockByHash. My transaction receipt object currently looks like this:

{"blockHash": String("0x1"), "blockNumber": String("0x5"), "contractAddress": 
Null, "cumulativeGasUsed": String("0x186A0"), "from": String("0x768D18226FB63Aa1A782357A1796A9D89f7dBB8e"), "gasUsed": String("0x186A0"), "logs": Array [], "status": String("0x1"), "to": String("0x21DD7e6361A8eDFD251ee3188B800F2A9F5C1541"), "transactionHash": Object {"transaction": String("0x45bba2071f7747624734c745b73b01b40c20e9c41da0d6d9a499c4ef8ad7110d")}, "transactionIndex": String("0x0"), "type": String("0x2")}

and the block returned by eth_getBlockByHash like this:

{"difficulty": String("0x1"), "extraData": String("0x0"), "gasLimit": String("0x2386F26FC10000"), "gasUsed": String("0x0"), "hash": String("0x1"), "logsBloom": String("0x0"), "miner": String("0x2E51295eac313D95CD1871Cc8a2d95c4d4959f8E"), "nonce": String("0x1"), "number": String("0x5"), "parentHash": String("0x0"), "receiptsRoot": String("0x0"), "sha3Uncles": String("0x0"), "size": String("0x0"), "stateRoot": String("0x0"), "timestamp": String("0x0x65a5363b"), "totalDifficulty": String("0x1"), "transactions": Array [String("0x45bba2071f7747624734c745b73b01b40c20e9c41da0d6d9a499c4ef8ad7110d")], "transactionsRoot": String("0x0"), "uncles": Array []}

I’ve taken care that the hash in the transactions array matches the hash from the transaction receipt at the specified transactionIndex. As you can see, most of the other information is dummy data given that my system isn’t a blockchain. Some complications I’ve already tried addressing:

  • It seems that MetaMask is caching the last known block number for a given network (nor sure what it’s using to identify them, though, chain ID or something else) and I couldn’t find a good way of removing that information, so I’m uninstalling the extension and clearing the browser cache before each test
  • Even after waiting for several minutes the eth_getBalance update won’t get triggered, the only thing that consistently does it is connecting to a different network and then back to mine (but that’s not a solution for my users)
  • I’ve tried various ways to “trick” MetaMask into updating the balances, by incrementing the block number at various stages, but nothing seemed to work consistently.

Observed MetaMask behavior is a bit inconsistent, sometimes (rarely) the eth_getBalance will get triggered, but I can’t reproduce it consistently - I’m already trying to create as consistent conditions as possible (see above), I don’t know what else I could do. I’m a bit stuck where else I could look, my guess is that the issue is either that some crucial data is still missing from the dummy receipt / block or something else I haven’t figured out yet. I couldn’t really find much documentation for this either. The most closely related thing I could find in the forums was a feature request by someone with a similar problem (unfortuantely I don’t have permissions to post links yet), but there’s no discussion and it seems it’s not been implemented. Any help would be appreciated.

1 Like

hi thanks for sharing all the details about the issue you are experiencing. Are you working with any node provider by any chance you could try eth_getBalance | INFURA

1 Like

Hi, thanks for the response. No, I’m not working with any node providers yet, I’m currently testing on localhost.

I see you might have more flexibility with the RPC calls when using node provider this is just an example of gas api MetaMask’s Gas API is now available to any developer via Infura | MetaMask News check the link I shared earlier for ``eth_getbalance`