You can query Flow for a list of events in a specific range by creating following helper method:
const getEvents = async (params) => {
// Define event type from params
const { contractAddress, contractName, eventName } = params;
const eventType = `A.${contractAddress}.${contractName}.${eventName}`;
const { from = 0, to } = params;
let toBlock;
if (to === undefined) {
// Get latest block
const blockResponse = await fcl.send(
await sdk.build([sdk.getLatestBlock()])
);
toBlock = blockResponse.latestBlock.height;
} else {
toBlock = to;
}
const response = await fcl.send(
await sdk.build([sdk.getEvents(eventType, from, toBlock)])
);
// Return a list of events
return response.events;
};
And then use it, for example, like this:
const getHelloEvents = async () => {
const events = await getEvents({
contractName: "HelloWorld",
contractAddress: "01cf0e2f2f715450", // note the address is without "0x" prefix
eventName: "CustomEvent",
});
console.log({ events });
};
I’ve also updated the repository, which this method and others to help you deploy contract, send transactions and execute scripts on Flow. You can reference it here:
2 Likes
Hey @MaxStarka !
I tried creating a custom event on my own.
However, I’m facing this problem as can be seen below -
value[0].name should be “id” not “ethid”
value[1].name should be “ethid” not “id”
Any guesses what’s wrong with my code?
All cool with your code, @jayesh_wayesh. It’s a known error that arguments are alphabetically sorted. The team is working on it
As a temporary solution, in your Cadence code for event declaration, add prefixes a_
, b_
, etc. like this (don’t forget to update the signature, when you emit them )
pub event Converted(a_id: UInt64, b_ethid: String)
Create a helper method:
export const fixNames = (item) => {
var result = {}
for (let name of Object.keys(item)) {
const value = item[name]
const fixedName = name.replace(/\w+_/,'')
result[fixedName] = value
}
return result
}
And your method for requesting events :
const getEvents = async (params) => {
// Define event type from params
const { contractAddress, contractName, eventName } = params;
const eventType = `A.${contractAddress}.${contractName}.${eventName}`;
const { from = 0, to } = params;
let toBlock;
if (to === undefined) {
// Get latest block
const blockResponse = await fcl.send(
await sdk.build([sdk.getLatestBlock()])
);
toBlock = blockResponse.latestBlock.height;
} else {
toBlock = to;
}
const response = await fcl.send(
await sdk.build([sdk.getEvents(eventType, from, toBlock)])
);
// Decode server response, so we could get properly formatted values
const events = await fcl.decode(response);
// Now let's purge prefixes from names
const fixedEvents = events.map((item) => {
const { data } = item;
item.data = fixNames(data);
return item;
});
// Return a list of events
return fixedEvents;
};
This way you will be able to utilize fcl.decode
method and later you can redeploy the code without prefixes and it should (theoretically) still work without updating your Javascript code
2 Likes
Hello @MaxStarka,
I have just started using flow blockchain and trying to listen to event.
I have tried the code that you have mentioned and it gives me error “err Error: failed to get events: could not look up block: key not found”
can you please point what am i doing wrong? i tried with “0x” prefix and also without that
const events = await getEvents({
contractName: "TopShot",
contractAddress: "0b2a3299cc857e29", // note the address is without "0x" prefix
eventName: "PlayAddedToSet",
});