Bloomr Documentation

website·Indexed 31 days ago

https://docs.bloomr.io

Bloomr allows you to stream real-time data directly from the blockchain using JavaScript/TypeScript scripts. The platform provides tools for EVM interaction, including Solidity calls, ABI encoding/decoding, internal transaction traversal, and event log access. Data can be exported via Webhooks, Websockets, or polling. It features a compute-based pricing model using Compute Units (CUs) and supports custom script databases and address lists for tracking large numbers of contracts.

Tokens
7.7K
Snippets
32
Records
52
Agent score
50%

What's inside Bloomr

  1. Introduction to Bloomr Scripting

    Bloomr streams are created by writing JavaScript (specifically TypeScript) scripts that define the information you want to extract. These scripts are hosted and executed directly on Bloomr's infrastructure, removing the need for local development tools, server deployments, or DevOps configuration. Once a script is defined, the resulting data can be consumed via Bloomr's data streaming methods.
  2. Overview of Bloomr for real-time blockchain data streaming

    Bloomr is a service that allows developers to stream real-time data directly from EVM-compatible blockchains. Its architecture is designed to simplify the creation of real-time decentralized applications (dApps), often eliminating the need for a dedicated back-end even when implementing complex logic.
  3. Access Bloomr script runtime utility functions

    Bloomr scripts are executed in a specific runtime environment that provides built-in utility functions. For developers using TypeScript, the environment's type definitions are provided in the bloomr-script.d.ts file, which allows for type-safe development and autocompletion of the available runtime utilities.
  4. Understand the relationship between Solidity and the EVM

    The Ethereum Virtual Machine (EVM) is a virtual machine that executes bytecode. While Solidity is the most common language used to write smart contracts, it is not the EVM itself; it is one of several languages (including Vyper and Huff) that compile into EVM bytecode. The EVM is agnostic to the source language. Solidity defines widely adopted conventions for calldata layout, return data layout, and log/event data and topics.
  5. Understand Bloomr script execution and filtering

    Bloomr executes scripts in response to blockchain events. While scripts can be configured to run for all transactions across all blockchains, using filters allows you to specify the exact conditions under which a script should trigger. Because users pay for script execution time, implementing precise filters is critical for maintaining cost-efficient operations.
  6. Choose a method to consume Bloomr data streams

    After setting up Bloomr scripts, you can retrieve the emitted data stream using one of three subscription methods: WebSockets for real-time streaming, Webhooks for push notifications, or manual polling for on-demand data retrieval.
  7. Interact with smart contracts via transactions

    Calling a smart contract is done by sending a transaction to its address. A call can include a quantity of the native token (e.g., Ether) and calldata. The contract returns returndata and a boolean indicating success or failure (failed calls revert all state changes).

    To call a specific Solidity function, the calldata must contain:

    1. The function signature (first 5 bytes).
    2. The function arguments encoded according to the ABI specification.
  8. Identify function calls using decodeCall

    Interfaces defined in an ABI expose a decodeCall() method. This is used to analyze calldata to determine which function is being called. It returns null if no match is found, or an object containing the method name, signature, and decoded args.
    const { MyInterface: { decodeCall } } = abi<MyAbi>`
        interface MyInterface {
            function myFn(uint256 fnArg) external returns (uint256);
        }
    `;
    
    const result = decodeCall('0xc92e77d2000000000000000000000000000000000000000000000000000000000000002a');
    // Result: { name: "myFn", signature: "myFn(uint256)", args: { fnArg : 42n } }
  9. Call a smart contract interface

    You can define an interface using the abi tag and then instantiate it for a specific address using the .at() method to perform Solidity calls from within handlers.
    const { IERC20 } = abi<MyAbi>`
        interface IERC20 {
            function balanceOf(address owner) external view returns (uint256)
        }
    `;
    
    onTx(tx => {
        const token = IERC20.at(tx.to);
        console.log('balance of sender', token.balanceOf(tx.from));
    })
    
  10. Define and call non-deployed utility contracts in Bloomr

    Use the solidity tag to define a Solidity contract and interfaces directly within a Bloomr script. Bloomr dynamically compiles these contracts, making them usable as if they were deployed on all blockchains. This is particularly useful for creating helpers that fetch complex on-chain information in the context of the current block.
    const {
        IERC20: { Transfer },
        Main: { getTokenDetails },
    } = solidity<GetTokenData>`
    pragma solidity ^0.8.15;
    
    interface IERC20 {
        event Transfer(address indexed from, address indexed to, uint256 value);
        function decimals() external view returns (uint256);
        function name() external view returns (string memory);
    }
    contract Main {
        function getTokenDetails(IERC20 token) public view returns (uint256 decimals, string memory name) {
            decimals = token.decimals();
            name = token.name();
        }
    }
    `
    
    // The function getTokenDetails is now callable directly from JS
    const details = getTokenDetails(tokenAddress);
  11. Verify Bloomr webhook signatures

    Bloomr signs every webhook message with a private key to ensure authenticity. To verify that an incoming HTTP POST request originated from Bloomr, you should check the message against the public key available in your webhook settings. The signature is provided in the x-signature request header.
    // Define the public key (replace with the actual public key from your webhook settings)
    const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
    THE KEY HERE
    -----END PUBLIC KEY-----`;
    
    import express from "express";
    import { createVerify } from "crypto";
    
    const app = express();
    app.use(express.json()); // To parse requests
    
    app.post("/", (req, res) => {
      const signature = req.headers["x-signature"];
      if (!signature || typeof signature !== "string") {
        return res.status(400).send("Signature required");
      }
    
      const verifier = createVerify("sha256");
      verifier.update(JSON.stringify(req.body));
    
      const isVerified = verifier.verify(PUBLIC_KEY, signature, "base64");
    
      if (isVerified) {
        console.log("Verified");
        // Process the webhook body
      } else {
        console.log("Verification failed");
        return res.status(401).send("Invalid signature");
      }
    });
    
    const port = 8080;
    app.listen(port, () => {
      console.log(`Server listening on port ${port}`);
    });
  12. Manage and use Address Lists in Bloomr scripts

    Address lists are collections of addresses or hashes that can be managed via the Bloomr admin panel and accessed within scripts. They are shared across all scripts and filters, allowing for inter-script communication. A key performance benefit is that checking if an address list contains a specific address is free (no cost/gas equivalent), even for lists containing millions of entries.
    const myList = getAddressList('my list name');
    
    onTx(tx => {
        // Add an address to the list
        myList.add(tx.to);
        
        // Remove an address from the list
        myList.delete(tx.to);
    
        // Check if an address exists in the list (Free operation)
        if (myList.has(tx.to)) {
            // Execute logic
        }
    })