Imagine having an automated bookie that could systematically find interesting things to bet on, create the market, and manage everything without the need for humans. With Ritual, we can create such a system that uses native, on-chain AI to power the entire process.

In this tutorial, we will:

  1. Execute a TEE image to research data for a prediction market
  2. Use an LLM to consume the research data to generate a succinct market prompt
  3. Create a new market consuming the prompt, via a prediction market interface abstraction
  4. Automate 1-3 via a scheduled transaction to create new prediction markets automatically

1

Initial assumptions

For sake of example, assume that:

  1. A Python program is uploaded to and accessible via the Ritual TEE precompile
  2. This program calls out to external news sources (NYT, X.com) to fetch event data
  3. We have an abstracted prediction market interface to make new markets
  4. We will use an LLM model already cached on the Ritual Network (huggingface/Ritual-Net/Meta-Llama-3.1-8B-Instruct_Q4_KM)

In practice, you will likely want to use your own fine-tuned models purpose-built for this use case, rather than the default LLM models cached on Ritual.

2

Setup scheduler and prediction market interface

We begin with preliminary setup, using our familiar IScheduler interface and a IExamplePredictionProtocol stub interface:

// Declare interfaces
IScheduler public scheduler;
IExamplePredictionProtocol public predictionProtocol;

// Initialize interfaces
constructor(..., address schedulerAddress, address predictionProtocolAddress) {
    // ...
    scheduler = IScheduler(schedulerAddress);
    predictionProtocol = IExamplePredictionProtocol(predictionProtocolAddress);
    // ...
}
3

Setup market creation pipeline

Next, we will setup our core function, marketCreationPipeline() that will orchestrate three steps:

  1. Call our TEE precompile with our researcher-program image
  2. Pipe our research results into an LLM inference call
  3. Take our inference call output and create a new prediction market
import "./RitualLib.sol";

// ...

function marketCreationPipeline() public {
    // Step 1: Execute TEE to collect research data
    (bool teeSuccess, bytes memory teeOutput) = RitualLib.requestTEE(
        0,
        1,
        "researcher-program",
        "",
        ""
    );
    require(teeSuccess, "tee precompile call failed");
    string memory researchData = abi.decode(teeOutput, [string]);

    // Step 2: Parse TEE researchData output via LLM
    RitualLib.ModelId memory modelId = RitualLib.ModelId({
        storageId: 2,
        owner: "Ritual-Net",
        name: "Meta-Llama-3.1-8B-Instruct_Q4_KM",
        version: "",
        files: "Meta-Llama-3.1-8B-Instruct_Q4_KM.gguf"
    });
    string memory llmPrompt = string.concat("Generate a new prediction market using the provided research data:", researchData);
    (bool llmSuccess, bytes memory llmOutput) = RitualLib.requestLLM(
        modelId
        llmPrompt,
        50,
        0,
        1000000000,
        0
    );
    require(llmSuccess, "llm precompile call failed");

    // Step 3: use LLM output to create a new prediction market
    string memory newMarket = abi.decode(llmOutput, [string]);
    predictionProtocol.createMarket(newMarket);
}
4

Automate market creation at fixed schedule

Now that we have setup our one-time marketCreationPipeline() function, we can use scheduled transactions to invoke this function automatically:

function scheduleMarketCreationPipeline(
    uint32 gasLimit,
    uint48 gasPrice,
    uint32 frequency,
    uint32 numBlocks
) public payable {
    uint256 amount = uint256(gasLimit) * uint256(gasPrice) * uint256(numBlocks / frequency);
    require(msg.value >= amount, "Insufficient funds");

    uint32 deadline = uint32(block.number + numBlocks);

    scheduler.schedule{value: msg.value}(
        // Notice how we encode a function call to `marketCreationPipeline()`
        bytes4(abi.encodeCall(this.marketCreationPipeline, ())),
        gasLimit, // max gas limit
        gasPrice, // max gas price
        deadline, // max block number
        frequency // frequency
    );
}