Last active
May 8, 2024 09:25
-
-
Save 0xtrou/3b994c1b1c8b7baac499a53c57c0bfb8 to your computer and use it in GitHub Desktop.
Handle Events in Cosmos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const EVENT_LEVEL = { | |
TX_LEVEL: 'tx_level', | |
MSG_LEVEL: 'msg_level', | |
} | |
export class TxEventParserProvider { | |
constructor( | |
private _registry: any, | |
private tx: any | |
) {} | |
public aggregateEvents(): any[] { | |
const tx = this.tx; | |
if (!!tx.tx_response.code) { // this means tx has failed | |
return []; | |
} | |
const txEvents: any[] = []; | |
const messageActionEventIndexes: number[] = []; | |
const messageEvents = {} | |
const decodedEvents = tx.tx_response.events.map((event: any) => ({ | |
type: event.type, | |
attributes: event.attributes.map((attribute: any, index: number) => ({ | |
block_height: parseInt(tx.tx_response.height, 10), | |
index, | |
key: attribute?.key | |
? this._registry.decodeAttribute(attribute?.key) | |
: null, | |
value: attribute?.value | |
? this._registry.decodeAttribute(attribute?.value) | |
: null, | |
})), | |
// msg_index: event.msg_index || undefined, // map later | |
// level: EVENT_LEVEL.TX_LEVEL, | |
})); | |
// Now we aggregate | |
// If your goal is to just separate out tx-level events and events for individual msgs, I think you only need to look at the events field (and ignore log altogether): | |
// - events under events are sorted by order of occurrence | |
// - "type":"message" event is the leading indicator of the start of a msg | |
// so basically any event that comes before the first "type":"message" is a tx-level event | |
// then between the second "type":"message" and the third "type":"message" is event for the second msg, and so on | |
// just use type: message with "key": "action" in its attributes | |
// so tx-level events will appear before every message events | |
// given the events were sorted by order of occurrence, you can just iterate through the events array and separate them out | |
decodedEvents.forEach((event: any, index: number) => { | |
// mark the index of message events | |
if (event.type === 'message' && event.attributes.length === 1 && event.attributes[0].key === 'action') { | |
messageActionEventIndexes.push(index); | |
messageEvents[index] = { | |
...event, | |
msg_index: messageActionEventIndexes.length - 1, // get current index | |
level: EVENT_LEVEL.MSG_LEVEL, | |
}; | |
txEvents.push(messageEvents[index]); | |
return; | |
} | |
// expect we already had message events | |
if (messageActionEventIndexes.length > 0) { | |
// if the event "message" without "action" attribute, then it is a message event, then we merge it with the previous message event | |
if (event.type === 'message' && event.attributes.find((attr: any) => attr.key === 'action') === undefined){ | |
const messageIndex = messageActionEventIndexes.length - 1; | |
messageEvents[messageActionEventIndexes[messageIndex]].attributes.push(...event.attributes.map((attr: any, index: number) => { | |
return { | |
...attr, | |
// modify index of the attributes | |
index: messageEvents[messageActionEventIndexes[messageIndex]].attributes.length + index, | |
} | |
})); | |
return; | |
} | |
// if the event is not a message event, and its index between message events, | |
// then we set tx_msg_index to the previous message event index | |
// also set the source to MSG_EVENT | |
const messageIndex = messageActionEventIndexes.length - 1; | |
txEvents.push({ | |
...event, | |
msg_index: messageIndex, | |
level: EVENT_LEVEL.MSG_LEVEL, | |
}); | |
return; | |
} | |
// detect tx-level events, so tx-level events will appear before every message events | |
if (messageActionEventIndexes.length === 0 || index < messageActionEventIndexes[0]) { | |
txEvents.push({ | |
...event, | |
msg_index: null, | |
level: EVENT_LEVEL.TX_LEVEL, | |
}); | |
return; | |
} | |
}); | |
return txEvents; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment