Skip to content
Star

For OpenTelemetry engineers

View as MarkdownOpen in ClaudeOpen in ChatGPT

You know OpenTelemetry. This page gives you hashspan in OTel terms, and the few blockchain words its spans use.

A library, not a service: it uses your SDK, your exporter and your backend. Inside whatever span is active, such as a tool call, it records:

Span Kind Ends when
send {blockchain.chain.id} CLIENT the node returns a transaction hash, or the send fails
confirm {blockchain.chain.id} CLIENT the receipt arrives, or a timeout or error; linked to send or payment
payment {blockchain.chain.id} CLIENT a paid request settles or fails (x402, MPP)

It also records histograms for send duration, confirmation duration and fees, for every transaction, whatever a sampler decides. Span names stay low-cardinality: the chain id, never a hash.

Not yet. Every attribute is marked development, in schema 0.5.0-dev (semantic conventions).

OpenTelemetry has no blockchain conventions, and had no open proposal when hashspan started (ADR 0003). So hashspan uses its own blockchain.* namespace, shaped like db.* and rpc.*. Where upstream names exist it reuses them: error.type, rpc.*, jsonrpc.* and gen_ai.agent.*. The plan is to propose the schema upstream once it has real users. Renames follow a written change policy. The one rename so far records both names, and drops the old one at 1.0.

On a local chain, a traced send plus receipt took 0.25 to 0.5 ms more at p50 than plain viem. Tracing can add JSON-RPC requests: one for a transfer where viem picks the nonce, three for a reverted transaction. The tracing overhead benchmark has the method and every number.

  • Sampling: keep head sampling at 100% and decide in a Collector. A reverted transaction only shows on the confirm span, which can end after the Collector decides. A policy on blockchain.* keeps those traces: Collector recipe, tested.
  • Privacy: addresses are recorded by default, in lower case. Hash or drop them in the SDK or in the Collector. Calldata arguments and error messages are opt-in (privacy).
  • Backends: any OTLP backend. Backends has dated notes for Jaeger, Grafana, Langfuse, Honeycomb and others.
  • Security and stability: keys, defaults, vulnerability reports and what 1.0 keeps stable are on one page.
  • Short-lived processes: call flush() before exit, or confirmations still open end as timeout.

TypeScript on Node.js 22.3 or later, with viem, the Coinbase CDP SDK, x402 or MPP. There is no Go, Python or Java version.

Not on TypeScript? Much of it still applies, because it is plain OpenTelemetry:

  • The names: the semantic conventions define the spans, attributes and metrics. You can record the same names from any OpenTelemetry SDK, such as Python’s around web3.py.
  • The Collector: the Collector recipe works on any spans that carry blockchain.operation.name.
  • Queries and dashboards: the TraceQL queries on Backends and the Grafana dashboards match on those names.
Word Meaning
Transaction hash The id of a sent transaction. Like a trace id: known at send, used to look it up later
Nonce A per-account counter. Each transaction uses the next one, once
Gas The work a transaction does, in units. Units times a price per unit is the fee
Receipt The node’s record that a transaction ran: block, gas used, success or reverted
Revert The contract stopped on purpose and undid its changes. The fee is still paid
Wei The smallest unit of ETH, 10^-18. Too big for int64, so hashspan records it as a decimal string
L1 data fee On chains built on top of Ethereum, such as Base, a second fee for posting the transaction to Ethereum itself

Transaction lifecycle walks a transaction from send to receipt. The architecture page shows the packages and every extra request.

An open-source project under Apache-2.0, maintained on GitHub. @hashspan/viem has had 23 releases since its first, on 2026-09-29. Releases are listed in the changelog.