WARP
WARP.md
This file provides guidance to WARP (warp.dev) when working with code in this repository.
Project overview
Language / ecosystem: Raku module, published as
Net::Ethereum(seeMETA6.json).Purpose: Client-side interface to an Ethereum JSON-RPC node, including RPC wrappers, ABI encoding/decoding, contract deployment, and fee/gas helpers.
Primary entry point:
Net::Ethereumclass inlib/Net/Ethereum.rakumod.
Refer to README.md for usage examples and background context.
Common commands
Test suite
Tests talk to a live Ethereum node and expect Solidity tooling to be installed.
Run all tests with the Raku test harness:
prove6 ./tor
prove -ve 'raku -Ilib'
Run a single test file (useful while iterating):
prove6 ./t/01.tor
raku -Ilib t/02.t
Tests assume:
Ethereum JSON-RPC node reachable at
http://127.0.0.1:8501.Solidity compiler available at
/usr/local/bin/solc.Environment variable
TXHASHset to a valid contract transaction hash, e.g.:export TXHASH=0x244409bb2cced62a2b93b2688167438ef47f60f1b5aa8b6c64e9de460ddec604
Optional helper for port forwarding to the node (when the node is on a different port):
./hooks/forward.sh 8501 <actual_node_port>
Module build / install (Raku ecosystem)
Standard Raku module commands apply (driven by META6.json):
Run tests via zef:
zef test .
Install the module locally:
zef install .
These are useful when you want to validate or install the module in a fresh environment beyond prove6-driven tests.
CI pipeline
Continuous integration is defined in .gitlab-ci.yml and is Docker-heavy. Key points:
Spins up two containers:
ethereum-dev: provides a local geth-based Ethereum network.net-ethereum-test: Rakudo-based environment for running Raku tests.
Inside CI, the pipeline:
Compiles and tests Solidity contracts from an external smart-contracts repo.
Produces a
smart-contract.hashfile and exportsTXHASHfrom it.Runs
hooks/forward.shin the Rakudo container to forward port8501to the actual Ethereum node port.Clones
http-useragentandpheix-research/smart-contracts, then runs tests viatrove-cliusing.trove.conf.yamland writes artifactstestreport.*.
You typically do not need to reproduce the entire CI pipeline locally unless you are debugging integration with the smart-contracts test harness.
Code architecture
High-level structure
lib/Net/Ethereum.rakumodDefines the main
Net::Ethereumclass.Handles JSON-RPC transport, method wrappers for Ethereum APIs, ABI encoding/decoding logic, contract deployment helpers, and fee/gas calculations.
lib/Net/Ethereum/Utils.rakumodDefines
Net::Ethereum::Utilswith numeric helpers used in fee calculations (e.g. blob gas fee exponential approximation).
t/*.tTest bundle that exercises JSON-RPC calls against a live node, including account management, contract calls, and EIP-1559/EIP-4844-style fee paths.
t/data,t/solcoutput,t/solctargetTest fixtures, compiled Solidity artifacts (
*.abi/*.bin), and placeholder directories used by tests.
hooks/forward.shShell script to forward local TCP connections from an external port to the actual Ethereum node port using
socat.
Net::Ethereum responsibilities
Connection and JSON-RPC transport
Uses
HTTP::UserAgent,HTTP::Request, andHTTP::Cookiesto talk to an Ethereum node at$.api_url(defaulthttp://127.0.0.1:8501).Supports keep-alive connections via
check_ua_keepalive,store_connection, andclose_connectionwhen$!keepaliveis enabled.All RPC calls ultimately go through
node_request($query)which:Assigns unique JSON-RPC
ids.Encodes requests with
JSON::Fast::to-json.Validates HTTP status codes and parses JSON responses with robust error handling.
Throws typed exceptions for malformed responses, mismatched IDs, or HTTP errors.
Error and validation model
Custom exception hierarchy (
Net::Ethereum::Xand subclasses) for:ABI parsing errors (
X::ParseABI).Invalid blocks/tags/data/topics (
X::InvalidBlock,X::InvalidTag,X::InvalidData,X::InvalidTopics).Password issues (
X::InvalidPassword).JSON-RPC errors (
X::JSONAPIand nested subclasses).
Internal validators like
!check_blockand tag checks in methods such aseth_getBalanceandeth_getTransactionCountensure inputs conform to Ethereum semantics.
Ethereum JSON-RPC surface
Direct mappings for core APIs:
Network introspection:
web3_clientVersion,web3_sha3,net_version,net_listening,net_peerCount,eth_syncing,eth_coinbase,eth_mining,eth_hashrate,eth_gasPrice,eth_accounts,eth_blockNumber.State queries:
eth_getBalance,eth_getTransactionCount,eth_getTransactionByHash,eth_getBlockByNumber,eth_getBlockByHash,eth_getBlockTransactionCountByHash,eth_getCode,eth_getTransactionReceipt,eth_getLogs.Calls and transactions:
eth_call,eth_estimateGas,eth_sendTransaction,eth_signTransaction,eth_sendRawTransaction.Personal API:
personal_newAccount,personal_unlockAccount,personal_lockAccount,personal_listWallets,personal_sign,personal_ecRecover.Debug API:
debug_traceTransaction.Fee-related APIs:
eth_maxPriorityFeePerGas,eth_createAccessList.
A convenience
get_account(:$index)accessor caches and validates accounts returned byeth_accounts.
ABI handling and contract interaction
Maintains contract ABI JSON in
$.abiand contract address in$.contract_id.ABI introspection helpers:
get_function_abi($name)andget_constructor_abiparse the ABI JSON and select the corresponding entry.
Encoding/decoding:
marshal_int/unmarshal_intimplement 256-bit signed/unsigned integer encoding.string2hex,hex2string,buf2hex,hex2bufhandle non-integer payloads.getContractMethodId($signature)computes the 4-byte method selector via Keccak256 (web3_sha3).marshal($fname, $fparams)builds full call data for functions and constructors, including multi-pass handling of dynamic types (string,bytes) and offsets.unmarshal($fname, $raw_data)decodes returned ABI-encoded data into aHash, with optional inclusion of raw data via$.return_raw_data.
High-level contract helpers:
contract_method_call_estimate_gasandcontract_method_callconstruct the call, performeth_call, and decode the result using ABI metadata.
Contract deployment pipeline
compile_and_deploy_contractis the high-level workflow used both by users and tests:Invokes
solcviashellwith--binand--abi, honoring$.solidity,$.evmver, and:contract_path/:compile_output_path.Loads generated
*.binand*.abifiles and stores ABI in$.abi.Unlocks the source account via
personal_unlockAccountunless:skipunlockis set.Uses
deploy_contract_estimate_gasanddeploy_contractto submit the transaction with a configurable gas safety factor ($!gaspercent).Waits for the deployment transaction to be mined via
wait_for_transaction(:contract)which also sets$.contract_id.Polls
eth_getCodeto ensure the contract code is deployed.Optionally cleans up artifacts in
:compile_output_pathwhen$.cleanupis true.
retrieve_contract($hash)is a convenience wrapper overeth_getTransactionReceiptto retrievecontractAddress.
Fee and gas utilities (EIP-1559 and blob gas)
Constants and logic near the top of
Net::Ethereumimplement blob gas fee behavior inspired by EIP-4844/EIP-7892.get_fee_datacomputes a fee data structure combining:Legacy
gasPrice.EIP-1559 max base fee and priority fee (
maxFeePerGas,maxPriorityFeePerGas) usingeth_getBlockByNumber("latest")andeth_maxPriorityFeePerGas.Blob gas components (
baseFeePerBlobGas,maxFeePerBlobGas) whenexcessBlobGas/blobGasUsedare present.
get_base_fee_per_blob_gasusesNet::Ethereum::Utils.fake_exponentialto calculate blob base fees given block blob gas metrics.
Utility class: Net::Ethereum::Utils
Located in
lib/Net/Ethereum/Utils.rakumod.Exposes
fake_exponential(:$factor, :$numerator, :$denominator)which implements an integer-only exponential-style approximation used in blob gas fee calculations.This function is central to maintaining consistency with Ethereumโs fee update formulas in
get_base_fee_per_blob_gas.
Test bundle
t/01.tBasic connectivity and JSON-RPC coverage: node health (
node_ping), web3, net, and core eth endpoints.
t/02.tMore advanced behavioral tests:
Wallet and account management via
personal_*calls.Balance and transaction count queries across different tags (
latest,earliest,pending, specific blocks).Transaction/receipt retrieval and smart-contract interaction driven by
TXHASHand compiled artifacts int/solcoutput.Fee and gas-related calls (
eth_estimateGas,eth_maxPriorityFeePerGas,eth_createAccessList).
Other
t/*.tfiles continue coverage of additional methods and scenarios, generally assuming the same live-node and contract setup.
When modifying core behavior (RPC wrappers, ABI handling, fee calculations), adjust or extend the corresponding tests under t/ and ensure the live-node environment assumptions are kept in sync with README.md and the CI pipeline.