Portal Community
Two separate config layers: static application configuration (appsettings.json — which RPC endpoint backs each network name) and per-node-instance configuration (the workflow JSON — which resource/operation/network a given step calls). Don't confuse them.

appsettings.json — the RPC endpoint catalogue

The node reads its network catalogue from an Ethereum section in application settings, bound via IOptions<EthereumNetworkOptions>:

"Ethereum": {
  "DefaultNetwork": "ethereum",
  "RpcTimeoutSeconds": 30,
  "Networks": {
    "ethereum": { "RpcUrl": "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY", "ChainId": 1,   "BlockExplorer": "https://etherscan.io" },
    "polygon":  { "RpcUrl": "https://polygon-mainnet.g.alchemy.com/v2/YOUR_KEY", "ChainId": 137, "BlockExplorer": "https://polygonscan.com" }
  }
}
KeyTypeRequiredDescription
DefaultNetworktext✓ YesNetwork name used when an operation doesn't set its own network field. Must match a key under Networks.
RpcTimeoutSecondsnumberNo (default 30)HTTP timeout applied to the shared JSON-RPC client.
Networksobject✓ YesMap of network name → RPC endpoint configuration. See Networks.

Per-Network Fields

Each entry under Ethereum:Networks is an EthereumNetworkConfig:

FieldTypeRequiredDescription
RpcUrltextOne of RpcUrl/RpcUrlCredentialIdPlain JSON-RPC URL. Only appropriate for endpoints that don't embed a provider API key — local Anvil/Hardhat/Ganache, self-hosted nodes, or public rate-limited endpoints.
RpcUrlCredentialIdnumberOne of RpcUrl/RpcUrlCredentialIdVault credential ID (SERVICE_URL type) whose Service URL field holds the full RPC URL, including the embedded API key. Required for Alchemy/Infura/QuickNode-style endpoints — keeps the key out of appsettings and source control. Takes precedence over RpcUrl when both are set.
ChainIdnumber✓ YesThe EVM chain ID (e.g. 1 for Ethereum mainnet, 137 for Polygon). Returned by utility.chainId and used internally by Nethereum's signer.
BlockExplorertextNoBase URL of a block explorer for this network (e.g. Etherscan, Polygonscan) — informational only, not called by the node.
Unknown network: if an operation's resolved network value has no matching entry under Ethereum:Networks, the node throws EthereumNetworkNotConfiguredException before any RPC call is attempted. See Troubleshooting.

Per-Operation network Field

Every operation accepts an optional network config key. When omitted, it falls back to Ethereum:DefaultNetwork:

FieldTypeRequiredDescription
networkselectNoAny key configured under Ethereum:Networks — e.g. ethereum, polygon, or a custom EVM chain you've added. Defaults to Ethereum:DefaultNetwork when unset.

Wallet Credentials (Write Operations)

Every write operation (transaction.send, token.transfer, contract.write, NFT transfers, wallet signing, etc.) needs a signing key. The private key is never a config field — it's resolved from the platform credential vault via the standard credentialID config key (auto-wired by BaseNodeExecutor) and read with ReadCredentialRawPrimaryAsync.

FieldTypeRequiredDescription
credentialIDcredential reference✓ Yes, for writesVault entry of type CRYPTO_WALLET. Its PrivateKey is used directly if present; otherwise its SeedPhrase (plus DerivationPath) is used to derive account 0's private key.
No signing credential configured: a write operation without a usable credentialID fails immediately with "No signing credential configured. Set 'credentialID' on this node to a vault entry (CRYPTO_WALLET type) containing a private key or seed phrase." — no RPC call is attempted.
Never logged or output: the resolved private key is never included in ToDictionary() or node output data, and the platform's SensitiveDataScrubber already redacts any config key containing private.

Registration

EthereumDependency.RegisterDefaults(services) registers everything the node needs:

Host apps must also add an explicit registration call: a ProjectReference alone is not sufficient in this codebase's plugin-loading mechanism — an assembly that is only referenced but never force-loaded is not guaranteed to appear in AppDomain.CurrentDomain.GetAssemblies() when assembly-scanning runs. Add new EthereumDependency().RegisterDefaults(services); to Plugins_RegisterAllNodes(...) in ServiceCollectionExtensionsForAI.cs. Without this line the node type won't appear in the workflow designer even though the package is referenced — the same reason Slack's own registration is currently commented out there.

Project Layout

The node ships as three .NET 9 projects (plus a test project):

ProjectResponsibility
BizFirst.Integration.Ethereum.DomainPure types — result records, network configuration model. Zero project references.
BizFirst.Integration.Ethereum.ServicesNethereum-backed business logic — one service class per resource, the shared RPC connection provider, a 429-retry HTTP handler.
BizFirst.Ai.ExecutionNodes.Blockchain.EthereumThe ExecutionNode itself — config parsing, operation routing, result mapping, DI registration.

Built on Nethereum over JSON-RPC — talks to Ethereum mainnet and any EVM-compatible network (Polygon, Arbitrum, Optimism, Base, local dev chains, etc.) that you point an RPC URL at.