How to track transactions/events on a specific wallet using ethers.js? - javascript

I want to track all "mint" transactions happening on a specific wallet using ethers.js. I know that you can create a filter, where you track a specific event signature, but I want to track all "mint" events, which can differ in the indivdual signatures.
Currently I have this, but it only tracks a specific event signature:
const filter = [
ethers.utils.id("Mint(address,uint256)"),
null,
[ethers.utils.hexZeroPad(address, 32)],
]
provider.on(filter, (log, event) => {
// process event
})
Mint Events can have different amounts and types of arguments. I want to track all events with the same name ("Mint"), but with different arguments? Any of you know a solution to that?
Is there a way to track all transactions happening on a specific wallet and look up the events emitted from each transaction?

The event name is not stored in the transaction receipt - so there's no way to filter all events that contain "XYZ" in its name.
The transaction receipt (specifically topics[0] of each event log within the receipt) stores the event selector. Which is a keccak-256 hash of the event name and argument types.
For example:
Mint(address,uint256) => 0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885
Mint(address) => 0x3c3284d117c92d0b1699230960384e794dcba184cc48ff114fe4fed20c9b0565
MintToken(address,uint256) => 0xdcdea898caf5576419f89caf69301592a4758349a0bd62300b58849213420a72
So you'll need to create a list of event signatures (value of topics[0]) that you're interested in, and filter against them.
Note: There's also anonymous events that don't store its selector at all, but this doesn't seem to apply to your case.
Is there a way to track all transactions happening on a specific wallet and look up the events emitted from each transaction?
Not available with the standardized JSON RPC API. So you'll need to build a collector service of all blocks and all transactions within them, retrieve their receipts, and then pass those that you're interested in to other service.
Or you can use some 3rd party service that does it in the background and simply sends you a webhook or other type of notification when there's a transaction from/to any of the addresses that you're watching.

Related

How can I access the child of a unique key in Firebase?

I am trying to access the child value of a unique key value (that had been "pushed") within Firebase. Currently, my database looks like this: I want to access the value of "emailOfUser"
I am very new to Firebase so I am not familiar with the functions. Currently, this is my method of obtaining other values for a different section of the database:
Thank you so much for any feedback!
I've tried different methods to accessing this data within the Firebase, but I cannot get it to work/the methods I were using were outdated. I also tried to "update" the Firebase instead of "pushing" the values to prevent a unique key from generating, but it simply overwrote my current data rather than appending something new.
If you want to load all the users who voted and print their emails, you can do that with:
get(child(dbref, 'usersWhoVoted')).then((snapshot) => {
snapshot.forEach((childSnapshot) => {
console.log(childSnapshot.key, childSnapshot.val().emailOfUser);
});
})
Note that your current structure allows a user to vote multiple times. If you want to only allow them to vote once, use some identifier of the user as the key in your database structure:
userVotes: {
"uniqueIdOfUser1": "valueTheyVotedOn",
"uniqueIdOfUser1": "valueTheyVotedOn",
...
}
Now each user can by definition only vote once, If they vote again (assuming your security rules allow that), their new vote will simply replace the existing vote.

How to only read changes in firebase realtime database

I have a database collection with readings, each new reading needs to be checked if it's out of the ordinary, if it is, there needs to be an alert sent.
So i'm using db.ref('collection').on('child_added', (child => { check(child); });
The problem with the .on function is that when the listener is added, all previous data is also read.
So how do i read a collection that only reads the changes in the database, also when the listener is first added? Or if that doesn't work, how do I differentiate the already added data with the new data?
The Firebase database synchronizes the state of whatever query or reference you attach your listener to. There is no option to only get new nodes built into the API.
If you want only new nodes, you will have to:
Ensure each node has an associated timestamp or order. If you're using Firebase's built-in push() keys, those might already serve that function.
Know what "new" means to the client, for example by either keeping the last timestamp or push key that it saw.
And then use a query to only request nodes after the stores timestamp/key.
So for example, if you only want to read nodes that are created after the moment you attach the listener, you could do something like this:
let now = db.ref('collection').push().key; // determine current key
db.ref('collection').orderByKey().startAt(now).on('child_added', ...)

Nestjs event emitter alternative with callback

I am experimenting and learning about nestjs but I am not able to find a proper solution to the following scenario:
Module Users
Module Books
Module Dashboard
The dashboard is a graphql that resolves his needs to calling the service of the books and the service of the users of those books.
I only know two ways of solving the order of a book and at the same time update the user information.
1- Using a mutation on the graphql dashboard that also calls an event that will be listen by the corresponding service that will update this new order, here is the example of this use case: https://github.com/nestjs/nest/tree/master/sample/30-event-emitter
2- Using Dependency Injection considering the dashboard to have a dependency of the corresponding services of users and books and simply update everything that is needed.
The problem:
Solution 1 the event does not provide a callback or response, it acts as the emition of an event that I cannot get feedback afterwards, more like an action or command than a function.
Solution 2 the dashboard knows too much, I don't need to provide the whole module as DI, to later call just one method to update the user information after an order had happen.
What I need, and I don't find anyware. An Event that I can listen after it gets executed... in other words similar to the following:
export interface OrderResults {
user: UserCustomer;
order: OrderCreated;
}
#Injectable()
export class Dashboard {
constructor(private reaonly eventEmitter: EventEmitter2): Promise<OrderResults> {}
async createOrder(order) {
const orderEventResults = await this.eventEmitter.emit('create.order', order)
return orderEventResults
}
}
The order event results, is that the users and the orders got properly notified and updated, resolving with the results of the listener of the user / orders.
My dashboard is completely agnostic of how or who will take care of this, but will serve to the client the results that corresponds from this events getting resolved by those services who take care of this event.
Any help or guidance in regards to this will be welcomed.
I'm not familiar with Nest, but EventEmitter2 which uses Nest has emitAsync method, so it should work:
const orderEventResults = await this.eventEmitter.emitAsync('create.order', order)
return orderEventResults

how to log all events (use actions) an DOM elements that have event listeners?

I would like to record all events that are fired through user action on DOM elements. A feature like recording user actions (macro) on my website so the app can later re-generate the current state by executing use actions sequentially. How to do it?
Is there any API or solution to find all events that are processed by event listeners?
Or should I gather events by myself? If so, what would be your approach/solution/design?
this OP says no: https://stackoverflow.com/a/63346192/5078847
It would be technically possible to record such a thing by
(1) using addEventListener exclusively in your site's code (if you don't, you'll have to also iterate through all on- properties and scan for inline handlers too, which is quite a pain)
(2) Overwrite the addEventListener prototype with a custom hander that, when fired, stores information uniquely identifying the click in an array (for example, save the name of the event fired, and a full selector string to the element the event is dispatched to, and if you need it, also the amount of time since the page was loaded)
(3) When needed, save the array somewhere
(4) To emulate the user's prior actions, retrieve the array, then iterate through it. For each action, create and dispatch an event to the unique selector at the time required.
But this is really, really convoluted. It would make a lot more sense for there to be a single source of truth for what's being displayed on your page. To save a state, just serialize the object that holds the data. To resume a state, retrieve the object and render according to its contents.
There isn't anything built in, like the other post said. Chrome devtools has a function getEventListeners that gets all the handlers for a given element (singular). You also can't use this outside of Chrome's devtools.
You could (but shouldn't) hijack addEventListener from the prototype chain.
Based off of this old forum here
/** !! Foot-Gun !! **/
/** Proof of Concept/Probably Doesn't Work **/
HTMLElement.prototype._addEventListener = HTMLElement.prototype.addEventListener;
HTMLElement.prototype.addEventListener = function(eventName, handlerFunction, eventOptions) {
// reportFunction you would have to write yourself
this._addEventListener(eventName, reportFunction, eventOptions);
this._addEventListener(eventName, handlerFunction, eventOptions);
// Store an array of them on the element
if ('currentListeners' in this === false) {
this.currentListeners = [
{ eventName, handlerFunction, eventOptions }
];
} else {
this.currentListeners.push({ eventName, handlerFunction, eventOptions });
}
}
Granted, I just handed out a loaded foot-gun for anyone who wants one. It's an anti-pattern at best, it doesn't control/track state, emulate user interactions, etc. etc.
I wouldn't recommend this for "regenerating" or rerendering UI as it's gonna be more trouble than it's worth.
If you're trying to use this for debugging, there are a couple of SAAS whose whole business models are based off of this, like HotJar and Sentry.io. I'd recommend checking them out first if you're looking for a solution.

Cloud Functions - Preventing triggers on certain fields

I have an app that people can request food , then I have orders, each order have an status for that order so I made a function that will send a user notification each time the status of this order changes, the status can be changed by the store which take the order and by the user when the order is done.
But I want to limit the execution of this function to just 2 fields, the userId and the status fields, because now I have onUpdated, this trigger will always launch whenever an update is made to this document.
I'm planning to update other fields than uid and status for this document and I dont want the trigger to relaunch again and send a notification to the user if not needed.
Is there anyway to limit the trigger by just certain fields in the document?
exports.onOrderUpdated = functions.firestore
.document('orders/{orderId}').onUpdate((change, context) => {
var db = admin.firestore();
try{
const orderDataSnap = change.after.data();
var userId = orderDataSnap.uid;
var orderStatus = orderDataSnap.status;
}catch(error){
return handleErrorToUser(error);
}
Here I only want to execute this function only when userId and status changes in that document
Is there anyway to do this ?
Thanks
According to the documentation of Change, there are before and after snapshots.
You can call the data() method on each of these these and check if the userId and status are both equal in the before and after copies. If they are, just return out of the function early.
No there isn't any possibility to trigger a Cloud Function only if some specific fields of a document are changed. As explained by samdy1 in his answer you can detect, within the Cloud Function, which field(s) has(ve) changed but for that the Cloud Function needs to be triggered.
One solution would be to write a document to another dedicated collection, in parallel to the change.
For example, if you are updating the document with a new status, you write a doc to a collection statusUpdates with the ID of the parent order document and the status value, and you trigger a Cloud Function based on this document creation.
Of course, it implies a document creation and it has a cost (In addition to the CF triggering). It's up to you to do the math, depending on the frequency of the updates, to calculate if this approach will be cheaper than the approach consisting in triggering the Cloud Function for the order document for nothing.

Categories