Skip to content
AnnouncementSomnia Oracle settles event contracts onchain, in minutes, with receipts.

Reactivity explained: contracts that respond on their own

Somnia Reactivity runs contract handlers in the same block as the events they react to, and pushes events to apps over WebSocket. A practical guide to both modes.

· 6 min readDevelopersInfrastructure

On most EVM chains, a contract cannot act unless someone sends it a transaction. Anything that should happen after an event (liquidations, settlements, rebalancing, scheduled upkeep) needs an off-chain bot or keeper network that watches the chain and pays to send a follow-up transaction. That adds an operator, latency and a failure mode.

Somnia Reactivity removes that step. It has been live on mainnet since the Ingot release of 15 April 2026 and comes in two forms that can be used independently or together.

Onchain reactivity

A contract creates a subscription by calling the Somnia reactivity precompile at address 0x0100. The subscription is stored in chain state and holds:

  • A filter: event topics, the emitting contract, and the transaction origin.
  • A handler contract and function selector.
  • Gas parameters for the handler.

Every event log emitted in a block is checked against active subscriptions. Matches go into a per-block queue ordered by priority fee. After the block's user transactions have run, validators execute each pending handler as a synthetic transaction in the same block.

These reactive transactions are ordinary in every other respect. They appear on the explorer, have normal receipts, emit normal logs and pay normal gas. The subscription owner pays for them.

Subscriptions can also be scheduled for a specific block, epoch or timestamp, which covers cron-style jobs such as settlement at a deadline or upkeep at each epoch boundary. Somnia produces blocks every 100 milliseconds, so a handler responds within the same 100 ms block as the event that triggered it.

Writing a handler

The Solidity package @somnia-chain/reactivity-contracts provides a base contract. Inherit from SomniaEventHandler and override the _onEvent hook:

MyHandler.sol
solidity
import { SomniaEventHandler } from "@somnia-chain/reactivity-contracts/contracts/SomniaEventHandler.sol";

contract MyHandler is SomniaEventHandler {
    function _onEvent(
        address emitter,
        bytes32[] calldata eventTopics,
        bytes calldata data
    ) internal override {
        // react to the event here
    }
}

The contract then calls SomniaExtensions.subscribe(address(this), filter, options) to register itself and becomes the subscription owner. For a one-shot schedule, it uses scheduleSubscriptionAtBlock, scheduleSubscriptionAtEpoch or scheduleSubscriptionAtTimestamp. The owner must hold at least 32 SOMI, and a subscription runs until it is removed with unsubscribe(id) or the owner can no longer pay.

One caution from the documentation: logs emitted by a handler are themselves checked against subscriptions. A handler that triggers its own subscription can recurse and drain the owner's balance, so filters should be specific.

Off-chain reactivity

Some reactions belong in the application rather than on the chain: a UI that updates when a trade lands, an indexer writing to a database, a bot watching a pool. For these, a client opens a WebSocket to a Somnia node and subscribes with eth_subscribe using the somnia_watch method.

Events are pushed as they land. Each notification can also carry the results of read-only calls simulated against the same block, so the app receives the event and the resulting state together in one message, with no extra round trip and no risk of reading inconsistent state.

Off-chain subscriptions cost no SOMI and end when the client disconnects. The TypeScript package @somnia-chain/reactivity wraps the protocol with viem; sdk.watch() takes contract sources, topic filters and optional calls to run alongside each event.

Choosing between them

  • Use onchain reactivity when the reaction must be a guaranteed, public effect: settlement at expiry, automatic liquidation, a callback that fires even if its owner is offline.
  • Use off-chain reactivity when the reaction lives in your app: interfaces, analytics, monitoring and trading bots.

In production

The Somnia Oracle schedules every resolution with onchain reactivity, so no keeper is involved. Consumers can subscribe to its AnswerPosted event to settle as soon as an answer is posted. The April 2026 Reactivity hackathon drew more than 350 developers and 146 projects (Somnia blog, 6 April 2026), and several Event Contracts hackathon entries use the precompile for keeperless redemption.

Build your market on Somnia

Talk to our team about launching a venue, making markets, or bringing an asset onchain. Or start building today with the docs.