Act·two-phase async

Long-running HTTP

Polling + JQ extract

Long-poll workflows with built-in JQ extraction. Minutes to hours.

0x0000000000000000000000000000000000000805Explorer
Two-phase async. Three sub-requests: initial submit (returns task ID via JQ), poll until status JQ matches, then optional result fetch. Settles viaonLongRunningResult.
click 'auto' (capability = 7)
≤ 500
blocks
block #

submit & extract taskId

1 header(s)
JQ path
min escrow: 0.0500 RITUALyou have: RITUAL
Connect your wallet to submit a real transaction.
to: 0x0000000000000000000000000000000000000805chainId 1979 · two-phase · 35 fields
Output
Click Validate to encode the 35-field long-running request.
poll every 5 blk · max 10000
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {PrecompileConsumer} from "./utils/PrecompileConsumer.sol";

contract LongRunningJob is PrecompileConsumer {
    address constant LONG_HTTP = address(0x805);
    address constant ASYNC_DELIVERY = 0x5A16214fF555848411544b005f7Ac063742f39F6;

    event JobSubmitted(bytes32 indexed jobId, address indexed sender);
    event JobReady(bytes32 indexed jobId, uint16 status, bytes body);
    event JobFailed(bytes32 indexed jobId, string error);

    /// @notice Submit a long-running job. Three HTTP requests:
    ///   1. initial — kick off the task, returns task ID via JQ path
    ///   2. poll    — check status (executor repeats until JQ path matches)
    ///   3. result  — fetch final result (optional — empty url uses poll body)
    function submitJob(address executor) external {
        bytes memory encoded = abi.encode(
            executor,
            new bytes[](0), uint256(500), new bytes[](0), bytes(""),
            uint64(5),                       // pollIntervalBlocks
            uint64(block.number + 10000),   // maxPollBlock
            "{{TASK_ID}}",                  // taskIdMarker
            address(this), this.onLongRunningResult.selector,
            uint256(300000), uint256(1_000_000_000),
            uint256(100_000_000), uint256(0),
            // ... 18 more fields for the 3 HTTP sub-requests
            // see /playground/long-http for the full encoding
            uint256(0), uint8(0), false
        );
        (bool ok,) = LONG_HTTP.call(encoded);
        require(ok, "long-http submit failed");
    }

    /// @notice Phase 2 callback — only AsyncDelivery may call.
    function onLongRunningResult(bytes32 jobId, bytes calldata result) external {
        require(msg.sender == ASYNC_DELIVERY, "unauth");
        // Decode using HTTP response shape: (uint16 status, string[] keys, string[] vals, bytes body, string err)
        (uint16 status, , , bytes memory body, string memory err) =
            abi.decode(result, (uint16, string[], string[], bytes, string));
        if (bytes(err).length != 0) {
            emit JobFailed(jobId, err);
        } else {
            emit JobReady(jobId, status, body);
        }
    }
}