> For the complete documentation index, see [llms.txt](https://docs.somnia.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.somnia.network/developer/data-streams/tutorials/streams-case-study-formula-1.md).

# Streams Case Study: Formula 1

### Schemas

Driver schema

```
uint32 number, string name, string abbreviation, string teamName, string teamColor
```

Cartesian 3D coordinates schema

```
int256 x, int256 y, int256 z
```

The driver schema can extend the cartesian coordinates since the 3D coordinates will be used widely for other applications. Again this promotes re-usability of schemas.

### Schema registration and re-use

```javascript
const { SDK, zeroBytes32, SchemaEncoder } = require("@somnia-chain/streams");
const {
    createPublicClient,
    http,
    createWalletClient,
    toHex,
    defineChain,
} = require("viem");
const { privateKeyToAccount } = require("viem/accounts");

const dreamChain = defineChain({
  id: 50312,
  name: "Somnia Testnet",
  network: "testnet",
  nativeCurrency: {
    decimals: 18,
    name: "STT",
    symbol: "STT",
  },
  rpcUrls: {
    default: {
      http: [
        "https://dream-rpc.somnia.network",
      ],
    },
    public: {
      http: [
        "https://dream-rpc.somnia.network",
      ],
    },
  },
})

async function main() {
    // Connect to the blockchain to read data with the public client
    const publicClient = createPublicClient({
      chain: dreamChain,
      transport: http(),
    })

    const walletClient = createWalletClient({
      account: privateKeyToAccount(process.env.PRIVATE_KEY),
      chain: dreamChain,
      transport: http(),
    })

    // Connect to the SDK
    const sdk = new SDK({
      public: publicClient,
      wallet: walletClient,
    })

    // Setup the schemas
    const coordinatesSchema = `int256 x, int256 y, int256 z`
    const driverSchema = `uint32 number, string name, string abbreviation, string teamName, string teamColor`

    // Derive Etherbase schema metadata
    const coordinatesSchemaId = await sdk.streams.computeSchemaId(
      coordinatesSchema
    )
    if (!coordinatesSchemaId) {
      throw new Error("Unable to compute the schema ID for the coordinates schema")
    }

    const driverSchemaId = await sdk.streams.computeSchemaId(
      driverSchema
    )
    if (!driverSchemaId) {
      throw new Error("Unable to compute the schema ID for the driver schema")
    }

    const extendedSchema = `${driverSchema}, ${coordinatesSchema}`
    console.log("Schemas in use", {
      coordinatesSchemaId,
      driverSchemaId,
      coordinatesSchema,
      driverSchema,
      extendedSchema 
    })

    const isCoordinatesSchemaRegistered = await sdk.streams.isDataSchemaRegistered(coordinatesSchemaId)
    if (!isCoordinatesSchemaRegistered) {
      // We want to publish the driver schema but we need to publish the coordinates schema first before it can be extended
      const registerCoordinatesSchemaTxHash =
        await sdk.streams.registerDataSchemas([
          { schemaName: "coords", schema: coordinatesSchema }
        ])

      if (!registerCoordinatesSchemaTxHash) {
        throw new Error("Failed to register coordinates schema")
      }
      console.log("Registered coordinates schema on-chain", {
        registerCoordinatesSchemaTxHash
      })

      await publicClient.waitForTransactionReceipt({ 
        hash: registerCoordinatesSchemaTxHash
      })
    }

    const isDriverSchemaRegistered = await sdk.streams.isDataSchemaRegistered(driverSchemaId)
    if (!isDriverSchemaRegistered) {
      // Now, publish the driver schema but extend the coordinates schema!
      const registerDriverSchemaTxHash = sdk.streams.registerDataSchemas([
        { schemaName: "driver", schema: driverSchema, parentSchemaId: coordinatesSchemaId }
      ])
      if (!registerDriverSchemaTxHash) {
        throw new Error("Failed to register schema on-chain")
      }
      console.log("Registered driver schema on-chain", {
        registerDriverSchemaTxHash,
      })

      await publicClient.waitForTransactionReceipt({ 
        hash: registerDriverSchemaTxHash
      })
    }

    // Publish some data!! 
    const schemaEncoder = new SchemaEncoder(extendedSchema)
    const encodedData = schemaEncoder.encodeData([
        { name: "number", value: "44", type: "uint32" },
        { name: "name", value: "Lewis Hamilton", type: "string" },
        { name: "abbreviation", value: "HAM", type: "string" },
        { name: "teamName", value: "Ferrari", type: "string" },
        { name: "teamColor", value: "#F91536", type: "string" },
        { name: "x", value: "-1513", type: "int256" },
        { name: "y", value: "0", type: "int256" },
        { name: "z", value: "955", type: "int256" },
    ])
    console.log("encodedData", encodedData)

    const dataStreams = [{
      // Data id: DRIVER number - index will be a helpful lookup later and references ./data/f1-coordinates.js Cube 4 coordinates (driver 44) - F1 telemetry data
      id: toHex(`44-0`, { size: 32 }),
      schemaId: driverSchemaId,
      data: encodedData
    }]

    const publishTxHash = await sdk.streams.set(dataStreams)
    console.log("\nPublish Tx Hash", publishTxHash)
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.somnia.network/developer/data-streams/tutorials/streams-case-study-formula-1.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
