Skip to content

ogpu.chain

Shared chain infrastructure — the layer every other module imports from. Owns the chain selection state, the RPC URL configuration, the Web3 instance cache, the nonce management singleton, and the ABI loader.

The package is a leaf in the SDK dependency graph: ogpu.types, ogpu.protocol, ogpu.client, and friends all depend on ogpu.chain, but nothing in ogpu.chain imports from higher layers. This is why switching chains in ChainConfig transparently affects every other module without coordination.

Public surface is re-exported at the top level for ergonomics:

from ogpu import ChainConfig, ChainId
from ogpu import fix_nonce, reset_nonce_cache, clear_all_nonce_caches, get_nonce_info

You only need to import from ogpu.chain.* directly when you want the low-level classes (Web3Manager, NonceManager) or the per-chain RPC URL dict (CHAIN_RPC_URLS).


ChainId

ogpu.chain.config.ChainId

Supported OGPU networks.

The enum value is the actual chainId used in EIP-155 transaction signing. Used as a key in ChainConfig.CHAIN_CONTRACTS and CHAIN_RPC_URLS to look up network-specific configuration.

Members

OGPU_MAINNET: Production OGPU chain (chainId 1071). OGPU_TESTNET: Test OGPU chain (chainId 200820172034).

ChainConfig

ogpu.chain.config.ChainConfig.set_chain classmethod

set_chain(chain_id: ChainId) -> None

Switch the globally-active chain.

Every subsequent SDK call resolves contracts, RPC, and ABIs against this chain. Typically called once at program startup.

Parameters:

Name Type Description Default
chain_id ChainId

The target chain.

required

Raises:

Type Description
ChainNotSupportedError

If the given chain is not in CHAIN_CONTRACTS.

Example
from ogpu import ChainConfig, ChainId
ChainConfig.set_chain(ChainId.OGPU_TESTNET)

ogpu.chain.config.ChainConfig.get_current_chain classmethod

get_current_chain() -> ChainId

Return the globally-active chain.

Returns:

Type Description
ChainId

The currently selected ChainId.

Raises:

Type Description
ChainNotSupportedError

If set_chain was never called and no default is available (shouldn't happen in practice — the default is OGPU_MAINNET).

Example
ChainConfig.get_current_chain()
# <ChainId.OGPU_MAINNET: 1071>

ogpu.chain.config.ChainConfig.get_contract_address classmethod

get_contract_address(contract_name: str) -> str

Return the address of a singleton contract on the current chain.

Used internally by load_contract to resolve NEXUS / CONTROLLER / TERMINAL / VAULT addresses. You rarely need to call this directly unless you're doing low-level web3 work outside the SDK.

Parameters:

Name Type Description Default
contract_name str

One of "NEXUS", "CONTROLLER", "TERMINAL", "VAULT".

required

Returns:

Type Description
str

The 0x-prefixed checksummed address of the contract.

Raises:

Type Description
ChainNotSupportedError

If the current chain has no contract mapping.

ValueError

If the contract_name isn't configured for this chain.

Example
ChainConfig.get_contract_address("NEXUS")
# '0x2b0cC6058313801D5feb184a539e3a0C5A87a6a1'

ogpu.chain.config.ChainConfig.get_all_supported_chains classmethod

get_all_supported_chains() -> list[ChainId]

Return every ChainId the SDK knows how to talk to.

Returns:

Type Description
list[ChainId]

List of supported ChainId members.

ogpu.chain.config.ChainConfig.set_rpc classmethod

set_rpc(url: str, chain: ChainId | None = None) -> None

Override the RPC URL for a given chain.

Validates the URL by running Web3.is_connected() against it before committing the change. If the probe fails, raises InvalidRpcUrlError and leaves the existing URL unchanged.

After a successful override, invalidates any cached Web3 instance for the affected chain so the next SDK call reconnects with the new URL.

Parameters:

Name Type Description Default
url str

The new RPC endpoint URL (http or https).

required
chain ChainId | None

Which chain to override. Defaults to the currently active chain.

None

Raises:

Type Description
ChainNotSupportedError

If chain is not a recognized OGPU chain.

InvalidRpcUrlError

If the URL is unreachable or the probe connection fails.

Example
# Point at a local Anvil fork
ChainConfig.set_rpc("http://127.0.0.1:8545")

# Override a specific chain without switching
ChainConfig.set_rpc(
    "https://my-node.example",
    chain=ChainId.OGPU_TESTNET,
)

ogpu.chain.config.ChainConfig.get_rpc classmethod

get_rpc(chain: ChainId | None = None) -> str

Return the configured RPC URL for a chain.

Reflects any overrides done via set_rpc. Useful for logging, debugging, or passing the URL to an external library.

Parameters:

Name Type Description Default
chain ChainId | None

Which chain to query. Defaults to the currently active chain.

None

Returns:

Type Description
str

The current RPC URL for that chain.

Raises:

Type Description
ChainNotSupportedError

If chain is not a recognized OGPU chain.

Example
ChainConfig.get_rpc()
# 'https://mainnet-rpc.ogpuscan.io'

ogpu.chain.config.ChainConfig.reset_rpc classmethod

reset_rpc(chain: ChainId | None = None) -> None

Restore the built-in default RPC URL for a chain.

Undoes any earlier set_rpc overrides for the given chain and invalidates the cached Web3 instance so the next call reconnects against the default.

Parameters:

Name Type Description Default
chain ChainId | None

Which chain to reset. Defaults to the currently active chain.

None

Raises:

Type Description
ChainNotSupportedError

If chain is not a recognized OGPU chain.

Example
ChainConfig.set_rpc("http://127.0.0.1:8545")
# ... later ...
ChainConfig.reset_rpc()  # back to the OGPU default

ogpu.chain.config.ChainConfig.load_abi classmethod

load_abi(abi_name: str) -> object

Load a contract ABI JSON file for the current chain.

Caches the parsed result per chain — subsequent calls are free. The abi_name is the filename without extension, e.g. "NexusAbi" for NexusAbi.json.

Parameters:

Name Type Description Default
abi_name str

ABI file basename, e.g. "NexusAbi", "ControllerAbi", "TerminalAbi", "VaultAbi", "SourceAbi", "TaskAbi", "ResponseAbi".

required

Returns:

Type Description
object

The parsed ABI (typically a list of dicts).

Raises:

Type Description
FileNotFoundError

If no ABI file with that name exists for the current chain.

Nonce management

ogpu.chain.nonce.fix_nonce

fix_nonce(address: str | None = None, private_key: str | None = None) -> int

Detect stuck pending transactions and force-cancel them.

Sometimes a transaction gets stuck in the mempool — wrong gas price, a crashed signer process, an RPC hiccup that lost the broadcast. fix_nonce is the hammer: it compares the on-chain mined_nonce with the pending_nonce, and for every nonce in between, broadcasts a 0-value self-transfer at 1.2× the current gas price. These replacement transactions pre-empt the stuck ones and the mempool clears.

After the cancellations propagate (there's a 3-second sleep), the SDK-side nonce cache is reset and the function returns the next available nonce.

Requires gas — the cancellation transactions pay real gas, and every cancellation attempt is a separate tx.

Parameters:

Name Type Description Default
address str | None

The EOA to recover. Defaults to the address derived from private_key.

None
private_key str | None

Hex private key used to sign cancellation transactions. If omitted, reads CLIENT_PRIVATE_KEY from the environment.

None

Returns:

Type Description
int

The next available nonce after cancellation propagates.

Raises:

Type Description
ValueError

If neither private_key nor CLIENT_PRIVATE_KEY is available.

Example
from ogpu import fix_nonce
next_nonce = fix_nonce()
# 🔧 Fixing nonce for 0x...
#    📊 Mined nonce: 42
#    📊 Pending nonce: 45
#    ⚠️  3 pending transaction(s) detected!
#    ✅ Fixed! Next available nonce: 42

ogpu.chain.nonce.get_nonce_info

get_nonce_info(address: str | None = None, private_key: str | None = None) -> dict[str, Any]

Return a dict summarizing on-chain and cached nonce state.

Useful for diagnostics and dashboards. Reads both the latest and pending transaction counts from chain, plus the SDK-side cached value, and returns them together.

Parameters:

Name Type Description Default
address str | None

The EOA to inspect. Defaults to the address derived from private_key.

None
private_key str | None

Used to derive the address when address is omitted. Falls back to CLIENT_PRIVATE_KEY env var.

None

Returns:

Type Description
dict[str, Any]

Dict with keys:

dict[str, Any]
  • address: The checksummed address.
dict[str, Any]
  • mined_nonce: Nonce from latest block.
dict[str, Any]
  • pending_nonce: Nonce from pending block.
dict[str, Any]
  • cached_nonce: SDK cached nonce, or None if not cached.
dict[str, Any]
  • has_pending: True if pending_nonce > mined_nonce.
dict[str, Any]
  • pending_count: Number of pending transactions.
Example
from ogpu import get_nonce_info
get_nonce_info()
# {'address': '0x...', 'mined_nonce': 42, 'pending_nonce': 42,
#  'cached_nonce': 42, 'has_pending': False, 'pending_count': 0}

ogpu.chain.nonce.reset_nonce_cache

reset_nonce_cache(address: str | None = None, private_key: str | None = None) -> None

Drop the SDK-side cached nonce for one address.

Cheap, doesn't touch the chain. Use when you know the cache is stale but don't need to cancel stuck transactions — e.g. you just manually sent a transaction from an external wallet and want the SDK to re-read the on-chain nonce on the next call.

Parameters:

Name Type Description Default
address str | None

The EOA to clear. Defaults to the address derived from private_key.

None
private_key str | None

Used to derive the address when address is omitted. Falls back to CLIENT_PRIVATE_KEY env var.

None

Raises:

Type Description
ValueError

If no address can be determined.

Example
from ogpu import reset_nonce_cache
reset_nonce_cache()
# ✅ Nonce cache cleared for 0x...

ogpu.chain.nonce.clear_all_nonce_caches

clear_all_nonce_caches() -> None

Drop every cached nonce for every address in the process.

The nuclear option. Use in test teardown, or when you're doing something unusual and want to guarantee a clean slate.

Example

from ogpu import clear_all_nonce_caches
clear_all_nonce_caches()
✅ All nonce caches cleared

Web3 access

ogpu.chain.web3.Web3Manager

Cached Web3 instance pool, keyed by ChainId.

All methods are classmethods — there's only ever one instance pool per process.

The first get_web3_instance(chain) call for a given chain creates a fresh Web3 with Web3.HTTPProvider(rpc_url) and probes is_connected(). Subsequent calls return the cached instance.

update_rpc_url drops the cached instance so the next call reconnects — this is how ChainConfig.set_rpc propagates a new RPC URL without a process restart.

get_web3_instance classmethod

get_web3_instance(chain_id: ChainId | None = None) -> Web3

Return the cached Web3 for a chain, creating it on first use.

Parameters:

Name Type Description Default
chain_id ChainId | None

Which chain to get the instance for. Defaults to the currently active chain.

None

Returns:

Type Description
Web3

A connected Web3 instance.

Raises:

Type Description
ConnectionError

If the underlying HTTPProvider fails to connect on first creation.

ValueError

If no RPC URL is configured for the given chain.

Example
from ogpu.chain.web3 import Web3Manager
w3 = Web3Manager.get_web3_instance()
w3.eth.block_number
# 12345678

update_rpc_url classmethod

update_rpc_url(chain_id: ChainId, rpc_url: str) -> None

Set a new RPC URL for a chain and invalidate the cached instance.

Called by ChainConfig.set_rpc and ChainConfig.reset_rpc. After this runs, the next get_web3_instance(chain_id) creates a fresh connection against the new URL.

Parameters:

Name Type Description Default
chain_id ChainId

The chain to reconfigure.

required
rpc_url str

The new RPC URL. Not validated here — ChainConfig.set_rpc does the is_connected probe.

required