Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/montoya/insights-counter
A MetaMask snap that displays how many times you have interacted with an address.
https://github.com/montoya/insights-counter
metamask snaps
Last synced: about 1 month ago
JSON representation
A MetaMask snap that displays how many times you have interacted with an address.
- Host: GitHub
- URL: https://github.com/montoya/insights-counter
- Owner: Montoya
- License: apache-2.0
- Created: 2023-03-31T15:18:12.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-04-19T03:38:54.000Z (over 1 year ago)
- Last Synced: 2024-11-09T15:04:03.422Z (about 1 month ago)
- Topics: metamask, snaps
- Language: TypeScript
- Homepage: https://montoya.github.io/insights-counter/
- Size: 1.26 MB
- Stars: 3
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.APACHE2
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# Insights Snap
## Tutorial
Steps to code this yourself:
### 1. Go to the snap manifest `packages/snap/snap.manifest.json` and change the permissions to the following:
```JSON
"initialPermissions": {
"snap_manageState": {},
"endowment:transaction-insight": {}
},
```### 2. Go to the snap source code `packages/snap/src/index.ts` and replace it with this:
```TypeScript
import { OnTransactionHandler } from '@metamask/snaps-types';
import { text } from '@metamask/snaps-ui';
import { hasProperty, isObject } from '@metamask/utils';/**
* Handle an incoming transaction, and return any insights.
*
* @param args - The request handler args as object.
* @param args.transaction - The transaction object.
* @returns The transaction insights.
*/
export const onTransaction: OnTransactionHandler = async ({ transaction }) => {
if (
!isObject(transaction) ||
!hasProperty(transaction, 'to') ||
typeof transaction.to !== 'string'
) {
console.warn('Unknown transaction type.');
return { content: text('Unknown transaction') };
}return { content: text('**Test:** Successful') };
};
```This will handle a typical transaction and show a generic message in the transaction insights interface.
Run `yarn && yarn start` to build the snap, launch the local server, and install it.
You can then try going to a generic contract on mainnet and interact with it to see the transaction insights displayed: [Simple Storage](https://etherscan.io/address/0x48b4cb193b587c6f2dab1a9123a7bd5e7d490ced#writeContract).
### 3. Modify the snap source code return to get and display the address you are interacting with:
```Typescript
return { content: text('**You are interacting with:** ' + transaction.to) };
```Go back to the dapp, reconnect the snap to install the latest version, and go back to the contract to interact with it. This time you will see the address of the contract.
### 4. Use manageState to store a counter for each address you interact with:
```TypeScript
let state = (await snap.request({
method: 'snap_manageState',
params: { operation: 'get' },
})) as { addresses: {} } || null;if (!state) { // if no data this is likely null
state = { addresses: {} };
// initialize state if empty and set default data
await snap.request({
method: 'snap_manageState',
params: { operation: 'update', newState: state },
});
}let interactions = state.addresses['address:'+transaction.to] || 0;
interactions++;
let returnText = 'You have interacted with this address '+interactions+' times.';
if(interactions < 2) {
returnText = 'This is the **first time** you are interacting with this address.';
}state.addresses['address:'+transaction.to] = interactions;
snap.request({
method: 'snap_manageState',
params: { operation: 'update', newState: state },
});
```Add the panel type to the types you request from `snaps-ui`:
```TypeScript
import { panel, text } from '@metamask/snaps-ui';
```And modify the return value to display the number of times the user has interacted with this address:
```TypeScript
return { content: panel([
text('**You are interacting with:** ' + transaction.to),
text(returnText)
]) };
```The final source code of the snap is:
```TypeScript
import { OnTransactionHandler } from '@metamask/snaps-types';
import { panel, text } from '@metamask/snaps-ui';
import { hasProperty, isObject } from '@metamask/utils';/**
* Handle an incoming transaction, and return any insights.
*
* @param args - The request handler args as object.
* @param args.transaction - The transaction object.
* @returns The transaction insights.
*/
export const onTransaction: OnTransactionHandler = async ({ transaction }) => {
if (
!isObject(transaction) ||
!hasProperty(transaction, 'to') ||
typeof transaction.to !== 'string'
) {
console.warn('Unknown transaction type.');
return { content: text('Unknown transaction') };
}let state = (await snap.request({
method: 'snap_manageState',
params: { operation: 'get' },
})) as { addresses: {} } || null;if (!state) { // if no data this is likely null
state = { addresses: {} };
// initialize state if empty and set default data
await snap.request({
method: 'snap_manageState',
params: { operation: 'update', newState: state },
});
}let interactions = state.addresses['address:'+transaction.to] || 0;
interactions++;
let returnText = 'You have interacted with this address '+interactions+' times.';
if(interactions < 2) {
returnText = 'This is the **first time** you are interacting with this address.';
}state.addresses['address:'+transaction.to] = interactions;
await snap.request({
method: 'snap_manageState',
params: { operation: 'update', newState: state },
});return { content: panel([
text('**You are interacting with:** ' + transaction.to),
text(returnText)
]) };
};
```_Only ~50 lines of code!_
Reconnect the snap to install the latest version, then try interacting with a contract multiple times to see the count go up. You can try interacting with different addresses and you will that the result matches how many times you interact with each one!
## Caveats
1. This snap only runs when the user views the transaction insights tab for this snap. So it is really a count of that. If the user interacts with an address without viewing the tab, then that is never counted.
2. The transaction insights tab is loaded more than once when viewed, so the counter will fire multiple times, giving innacurate counts. To mitigate this, I have added a timestamp checker to only update the count if at least 4 seconds have passed since the last update. The source code in this repository has this feature.