fuels-rs
fuels-rs copied to clipboard
Interface to query and filter user owned events
Once https://github.com/FuelLabs/fuels-rs/pull/582 is merged, it will enable us to offer some nice querying/filtering functionalities around logging and events.
One of these functionalities that requires no change to the client would be: given an owner (a public Bech32Address
), return all (or a paginated amount) events (logs) triggered by this owner.
We have to expose client.receipts(txId)
through the Provider
. Then, the design space is fairly large. But the SDK has to filter Log
s out of the Receipt
s.
The underlying implementation would encapsulate something like this:
let response = contract_instance.log_my_event(event).call().await?;
let w = contract_instance._get_wallet();
let request = PaginationRequest::<String> {
cursor: None,
results: 9999,
direction: PageDirection::Forward,
};
let txs = w
.get_provider()
.unwrap()
.get_transactions_by_owner(w.address(), request)
.await
.unwrap();
for tx in txs.results {
let receipt = w
.get_provider()
.unwrap()
.client
.receipts(&tx.transaction.id().to_string())
.await
.unwrap();
dbg!(&receipt); // Filter out only the logs, parse them, etc., and at the end, return a nice `Vec<T>` with all events.
}
We could, later on, add a whole simple querying language on top of this to enable better filtering. But that would be outside of this initial scope. For now, just being able to query all events from a user should be good starting point.
In order to know the original type of some logged data, we need the log->type mapping from the JSON ABI of the contract which logged it.
So if you call get_transactions_by_owner
and then call receipts
with those transaction ids, you can theoretically get logs from contracts for which you might not have the appropriate JSON ABIs (in #582 that data is stored inside the contract_instance
, so you would need those).
This means that:
- The API for getting decoded logs would need to be given one or more contract instances so that it may use them to decode logs.
- We would need to decide if it is an error to be given a log whose original type we cannot deduce from the contract instances given to us. We could skip that log for example, but it might be surprising to the user.
I'll go ahead and implement a draft of something along these lines and we can wiggle toward what is best from there.
FYI @digorithm
This might need a separate issue, but would we be able to handle failing require statements in a more user-friendly way?
Currently, a require
in sway logs a custom error type (often an enum variant, but not always), and then reverts with the value 42
.
The idea was always that the SDK would see the Revert(42)
and then know to look at the preceding log/logd receipt as the reason for the failure. This log/logd would need to be decoded to be human-readable.
I'm guessing that this is probably? doable now with the current state of things?
cc @digorithm