- Area: Move contracts, rooch_framework::payment_revenue, events/indexer
- Labels: enhancement, contracts, events, indexer
Summary
Revenue events (RevenueDepositedEvent, RevenueWithdrawnEvent, RevenueHubCreatedEvent) are currently emitted without a per-account handle, making it hard for clients to query history for a specific account (agent). We propose emitting events using moveos_std::event::emit_with_handle with a per-account handle ID derived from the account’s revenue hub_id, so indexers and clients can fetch account-scoped streams efficiently.
Problem
- All revenue events share global streams per event type; frontend needs to query by type and client-filter by owner, which is inefficient and mixes accounts.
- The UI currently shows all events because there’s no per-account event handle to filter on.
Proposal
Use moveos_std::event with custom per-account handle IDs:
- For each event type, compute a per-account handle ID using the hub_id:
- deposited: custom_event_handle_id<ObjectID, RevenueDepositedEvent>(hub_id)
- withdrawn: custom_event_handle_id<ObjectID, RevenueWithdrawnEvent>(hub_id)
- hub created: custom_event_handle_id<ObjectID, RevenueHubCreatedEvent>(hub_id)
- Emit via emit_with_handle(handle_id, event) instead of emit(event).
- No need to store EventHandle fields in state; handle IDs are computed from hub_id on the fly.
Design Details
use moveos_std::event;
let hub_obj = borrow_or_create_revenue_hub(account);
let hub_id = object::id(hub_obj);
/* ... state updates ... */
let handle_id = event::custom_event_handle_id<ObjectID, RevenueDepositedEvent>(hub_id);
event::emit_with_handle<RevenueDepositedEvent>(
handle_id,
RevenueDepositedEvent {
hub_id,
owner: account,
coin_type,
amount,
source_type: source.source_type,
source_id: source.source_id,
source_description: source.description,
},
);
let hub_obj = borrow_mut_revenue_hub(owner_addr);
let hub_id = object::id(hub_obj);
/* ... withdraw ... */
let handle_id = event::custom_event_handle_id<ObjectID, RevenueWithdrawnEvent>(hub_id);
event::emit_with_handle<RevenueWithdrawnEvent>(
handle_id,
RevenueWithdrawnEvent {
hub_id,
owner: owner_addr,
coin_type,
amount,
fee_amount: 0u256,
net_amount: amount,
fee_rate_bps: 0u16,
},
);
let hub_obj = borrow_or_create_revenue_hub(sender);
let hub_id = object::id(hub_obj);
let handle_id = event::custom_event_handle_id<ObjectID, RevenueHubCreatedEvent>(hub_id);
event::emit_with_handle<RevenueHubCreatedEvent>(
handle_id,
RevenueHubCreatedEvent { hub_id, owner: sender },
);
Client/Indexer Impact
- Indexer already exposes event_id.event_handle_id and event_seq.
- Frontends can filter by event_handle_id = custom_event_handle_id<ObjectID, T>(hub_id) to fetch only the target account’s events.
- Total count per account can be inferred from event_seq (0-based), or exposed via a view in the future if needed.
Backward Compatibility
- Option A: Temporarily double-emit (legacy emit + new emit_with_handle) for one release window to avoid breaking existing consumers.
- Option B: Hard switch to emit_with_handle with a minor version bump and release notes.
Acceptance Criteria
- Each account’s events have distinct event_handle_id based on hub_id.
- Frontend can reliably query only the current agent’s events.
- No regressions in deposit/withdraw functionality.
- Tests updated to validate handle-based emissions.
Risks/Notes
- This approach avoids storing EventHandle in state and does not require &signer for handle creation; handle IDs are derived deterministically from hub_id.
- If existing hubs need migration to “start” handle-based streams, no state change is required—just begin emitting with the computed handle IDs.
References
- Contract: frameworks/rooch-framework/sources/payment_revenue.move
- Event lib: frameworks/moveos-stdlib/sources/event.move (moveos_std::event)
Tasks
- Switch all revenue event emissions to moveos_std::event::emit_with_handle using custom_event_handle_id<ObjectID, T>(hub_id).
- Optional: double-emit during a deprecation window.
- Update tests and docs.
- Update frontend queries to filter by event_handle_id for account-scoped history.
Summary
Revenue events (RevenueDepositedEvent, RevenueWithdrawnEvent, RevenueHubCreatedEvent) are currently emitted without a per-account handle, making it hard for clients to query history for a specific account (agent). We propose emitting events using moveos_std::event::emit_with_handle with a per-account handle ID derived from the account’s revenue hub_id, so indexers and clients can fetch account-scoped streams efficiently.
Problem
Proposal
Use moveos_std::event with custom per-account handle IDs:
Design Details
let hub_obj = borrow_or_create_revenue_hub(sender); let hub_id = object::id(hub_obj); let handle_id = event::custom_event_handle_id<ObjectID, RevenueHubCreatedEvent>(hub_id); event::emit_with_handle<RevenueHubCreatedEvent>( handle_id, RevenueHubCreatedEvent { hub_id, owner: sender }, );Client/Indexer Impact
Backward Compatibility
Acceptance Criteria
Risks/Notes
References
Tasks