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.
Submission Category:
Creative Catalyst / Exciting Experiments
Download links:
Demo
Dashboard - Aggregated breakdown on how much went to each site in total
Recent Payments - History of micropayments to websites with web monetization
Enable/Disable Monetization
Payment Counter - Floating counter of how much went to each active tab in total
Payment Alerts - Get notifications when a certain amount is reached
Export History - Export micropayments history to csv/xlsx
Charity - Turn on to split payments between the Web-Monetized website and the PayTrackr developer. (Switched off by default)
You can find updated demos in the comment section.
Benefits
Installing PayTrackr side by side with Coil or any other provider soon gives us benefits like:
- We become financially aware and improve money management
- We can allocate money to each site equally if we want to
- We can monitor payment streams in real-time
Link to Code
The code and installation instructions are hosted on GitHub.
wobsoriano / paytrackr
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).
Download links
Features
- Dashboard - Aggregated breakdown on how much went to each site in total
- Recent Payments - History of micropayments to websites with web monetization
- Enable/Disable Monetization
- Payment Counter - Floating counter of how much went to each active tab in total
- Payment Alerts - Get notifications when a certain amount is reached
- Export History - Export micropayments history to csv/xlsx
Usage
$ npm install
$ npm run build:dev
Running locally
Google Chrome
- Open Chrome and type
chrome://extensions
in the search bar. Turn the switchDeveloper mode
on. - Look for the button
Load unpacked
at the top-left and select thedist
folder found in the root's path of our extension when we runnpm run build:dev
. - β¦
How I built it
Tech Stack
- Vue - JavaScript Framework
- Vuetify - Material Design component framework for Vue
- Chart.js - Flexible JS Charts
- SheetJS - Used to export data to csv/xlsx
- CoinGecko API - XRP/USD conversion
Browser APIs used:
- Storage - used to store payment streams locally
-
Notifications - used to notify user when a certain amount declared in the
Alerts
tab is reached. - Tabs - used to send updates when toggling monetization status, etc.
My discovery along the way
If you're not familiar with browser extension development, I advise you to take a look at Chrome's Getting Started Tutorial or Mozilla's.
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.
First we create a file called inject.js
.
if (document.monetization) {
document.monetization.addEventListener("monetizationprogress", (e) => {
document.dispatchEvent(
new CustomEvent("paytrackr_monetizationprogress", {
detail: e.detail,
})
);
});
}
Then create our content script file called content.js
and add this code.
let s = document.createElement('script');
s.src = chrome.runtime.getURL('script.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
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.
document.addEventListener('paytrackr_monetizationprogress', (e) => {
console.log('received', e.detail);
});
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.
To do this in Firefox, we can use wrappedJSObject.
This is now what our manifest.json
looks like.
{
"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.
"content_scripts": [
{
"matches": ["<all_urls>"],
"all_frames": true,
"js": ["content.js"]
}
],
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.
const attachIframe = () => {
const iframe = document.createElement("iframe");
iframe.src = "https://paytrackr-developer.now.sh/";
iframe.style = "width:0;height:0;border:0;border:none;";
iframe.allow = "monetization";
document.body.appendChild(iframe);
};
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.
Please let me know if you have any questions.
Cover photo by Josh Appel on Unsplash
Top comments (13)
v0.2.0
Hello everyone!
Good news! v0.2.2 has tons of interesting updates:
PayTrackr is currently in beta so there will be changes anytime soon!
Added a new feature for v0.1.1
Probabilistic RevShare - Agreeing to support the developer gives him 5% chance of getting a payment every second a member is in a Web-Monetized content.
This looks super cool and useful!
Thanks a lot Emma!
Very cool! I have it installed and it looks great!
Awesome. Thanks Ben! β₯οΈ
This is super cool π
Thanks Thomas! π
Awesome. I have already started using this.
Thanks Dave!
How can I enable "charity option" ?
Available in Chrome now!