Intersection with Somnia Reactivity

How to build applications that react to data being streamed to the Somnia chain by creating subscriptions

Reactivity background

For detailed information about reactivity please visit the Reactivity docs:

Writing data, events and reacting

When an ERC20 transfer takes place, balance state is updated and an event is emitted. The ERC20 transfer scenario is very common in smart contracts i.e. publishing state and emitting an event (also known as a log). Somnia Data Streams offers you the tooling to do this without the requirements of having to write your own custom Solidity contract. It also allows you to take advantage of existing schemas for publishing data yielding composibility benefits for applications. Example:

import { SDK } from "@somnia-chain/streams"
import { zeroAddress, erc721Abi } from "viem"

// Use WebSocket transport in the public client for subscription tasks
// For the SDK instance that executes transactions, stick with htttp
const sdk = new SDK({
    public: getPublicClient(),
    wallet: getWalletClient(),
})

// Encode view function calls to be executed when an event takes place
const ethCalls = [{
    to: "0x23B66B772AE29708a884cca2f9dec0e0c278bA2c",
    data: encodeFunctionData({
        abi: erc721Abi,
        functionName: "balanceOf",
        args: ["0x3dC360e0389683cA0341a11Fc3bC26252b5AF9bA"]
    })
}]

// Start a subsciption
const subscription = await sdk.streams.subscribe({

    ethCalls,
    onData: (data) => {
        const decodedLog = decodeEventLog({
            abi: fireworkABI,
            topics: data.result.topics,
            data: data.result.data,
        });

        const decodedFunctionResult = decodeFunctionResult({
            abi: erc721Abi,
            functionName: 'balanceOf',
            data: data.result.simulationResults[0],
        });

        console.log("Decoded event", decodedLog);
        console.log("Decoded function call result", decodedFunctionResult);
    }
})

// Write data and emit events that will trigger the above callback!
const dataStreams = [{
    id,
    schemaId: driverSchemaId,
    data: encodedData
}]

const eventStreams = [{
    id: somniaStreamsEventId,
    argumentTopics,
    data
}]

const setAndEmitEventsTxHash = await sdk.streams.setAndEmitEvents(
    dataStreams,
    eventStreams
)

Writing data and emitting events will trigger a call back to subscribers that care about a specified event emitted from the Somnia Data Streams protocol (or any contract for that matter) without having the need to poll the chain. It follows the observer pattern meaning push rather than pull which is always a more efficient paradigm.

Last updated