Skip to content

Typed subscription event parsing (nextBlock, nextLog) #43

@koko1123

Description

@koko1123

Problem

Subscription.next() returns raw JSON bytes. Callers must manually parse the notification envelope to extract typed data:

// Current: caller parses raw JSON
const raw = try sub.next();
defer allocator.free(raw);
// ...now manually extract block number from notification JSON 😬

This is the primary friction point for building bots with subscription.zig. Both the simple-arbitrage example (#37) and the liquidation keeper (#39) need typed data from subscriptions immediately.

Proposed API

Add typed helpers to Subscription:

pub const Subscription = struct {
    // existing...

    /// For new_heads subscriptions: parse and return the next block header.
    /// Frees the raw notification internally.
    pub fn nextBlock(self: *Subscription, allocator: std.mem.Allocator) !block_mod.BlockHeader

    /// For logs subscriptions: parse and return the next log.
    /// Frees the raw notification internally.
    pub fn nextLog(self: *Subscription, allocator: std.mem.Allocator) !receipt_mod.Log

    /// For new_pending_transactions: return the next tx hash.
    pub fn nextTxHash(self: *Subscription) ![32]u8
};

Usage in examples

simple-arbitrage (#37) — needs block_number to target block_number + 1 for bundle:

var sub = try Subscription.subscribe(allocator, &ws, .new_heads);
while (true) {
    const header = try sub.nextBlock(allocator);
    defer header.deinit(allocator);
    try processBlock(header.number, &pairs, &fb_client);
}

liquidation keeper (#39) — needs typed Log to update position state:

var sub = try Subscription.subscribe(allocator, &ws, .{ .logs = .{
    .address = PERP_MANAGER,
    .topics = &.{POSITION_OPENED_TOPIC},
}});
while (true) {
    const log = try sub.nextLog(allocator);
    defer log.deinit(allocator);
    try updatePositionState(&positions, log);
}

Implementation notes

  • nextBlock: call next(), then reuse provider.zig's existing block header JSON parser on params.result
  • nextLog: call next(), then reuse the log parsing already in provider.getLogs
  • nextTxHash: call next(), extract 32-byte hash from params.result string
  • The notification envelope format is: {"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x...","result":{...}}}

Priority

This is blocking both #37 and #39 examples. Should land before the next release.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions