Currently, web monetization providers doesn't have a feature to show subscribers a breakdown of where their money went. This is due to the fact that providers don't track or know where their subscribers go, in the name of privacy. It's a tough balance between privacy and data.
What I built
I built a secure browser extension that lets you track and manage your micropayments to Web-Monetized websites, having a web monetization provider membership (i.e. Coil).
PayTrackr stores all of your micropayments locally on your device. Only you have access to your data. Not even the web monetization providers can read your data.
PayTrackr is 100% open source software. The source code for PayTrackr is hosted on GitHub and everyone is free to review, audit, and contribute to the PayTrackr codebase.
PayTrackr is currently in beta testing so there will be changes anytime soon.
Track and manage your micropayments into one place 🎉
PayTrackr
PayTrackr is the easiest and safest way to track and manage your micropayments to Web-Monetized websites, having a web monetization provider membership (i.e. Coil).
The first thing I did is to figure out how can I listen to monetization events in each page I visit. This is the most important part in building this extension because we can't really do much without having access to streamed payments.
Luckily, we can use a content script since it has access to all pages we visit in the browser.
But no. We can't use a content script.
document.monetization is an expando property on a standard DOM document interface, this property is not a part of DOM, it's essentially a JavaScript object so it's not accessible directly from a content script which runs in an isolated world - all JavaScript objects/variables/expandos are isolated so the page scripts can't see the JS objects of content scripts and vice versa.
In Chrome, to overcome this, we need to run a code in page context and then use standard DOM messaging via CustomEvent to coordinate the code in page context and the content script.
Basically we injected a code and it is now running in page context. Then to communicate between the injected page script and the content script, we can add this to our content.js file.
With that, we can now listen to monetization progress events for all Web-Monetized content we visit which holds mostly the data we need to build our extension.
{"name":"PayTrackr","description":"Track and manage your micropayments into one place 🎉","version":"0.0.1","manifest_version":2,"icons":{"48":"icons/icon_48.png","128":"icons/icon_128.png"},"browser_action":{"default_title":"paytrackr","default_popup":"popup/popup.html"},"background":{"scripts":["background.js"]},"content_scripts":[{"matches":["<all_urls>"],"js":["content.js"]}],"content_security_policy":"script-src 'self' 'unsafe-eval'; object-src 'self'","web_accessible_resources":["inject.js"],"permissions":["storage","unlimitedStorage","notifications"]}
To listen to events from iframes, we can set all_frames to true in our content script.
Note: We need to add inject.js in the web_accessible_resources for Chrome to not refuse to load our script and display the following error in the console:
Denying load of chrome-extension://[EXTENSIONID]/script.js. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.
Charity implementation
So you may be wondering how I did the split payments when the charity option is enabled.
I created a function that creates an iframe element and appends it to the body of the document.
The area of focus in the code above is the iframe.src and iframe.allow. The value of the iframe.src is basically an empty Web-Monetized page I deployed in vercel and to monetize the iframe, we add monetization to the iframe's allow attribute.
Walls I bumped into
Originally, I was going to use chrome.storage.sync instead of chrome.storage.local to store micropayments and have synchronization between devices but the sync property have limits.
Because of that, I refactored my code to use chrome.storage.local and good thing about this is that we can store unlimited amount of data ... but without sync.
Future plans
Sync data between devices
✅ Start/Stop/Pause payment streams?
Send history to email
Thank you Dev and Grant For The Web for conducting this awesome hackathon and giving all the participants an opportunity to contribute.