- Payment monitor: enter private view key to track incoming payments - Scans mempool + last 100 blocks via PHP proxy with 4-node failover - Lightweight crypto: 30KB noble-curves bundle (Ed25519 + Keccak-256) - Subaddress support (network byte 42 detection, a*D validation) - Confirmation progress bar (0-10 confirmations) - Underpayment detection - Deadline badges (7/14/30 days) replacing minutes input - QR code: standard colors (black on white) for wallet scanner compatibility - QR hint positioned below QR code - View key masked input, never stored or transmitted
61 lines
1.5 KiB
JavaScript
61 lines
1.5 KiB
JavaScript
var CACHE_NAME = 'xmrpay-v2';
|
|
var ASSETS = [
|
|
'/',
|
|
'/index.html',
|
|
'/app.js',
|
|
'/i18n.js',
|
|
'/monitor.js',
|
|
'/style.css',
|
|
'/lib/qrcode.min.js'
|
|
// xmr-crypto.bundle.js is lazy-loaded and runtime-cached
|
|
];
|
|
|
|
self.addEventListener('install', function (e) {
|
|
e.waitUntil(
|
|
caches.open(CACHE_NAME).then(function (cache) {
|
|
return cache.addAll(ASSETS);
|
|
})
|
|
);
|
|
self.skipWaiting();
|
|
});
|
|
|
|
self.addEventListener('activate', function (e) {
|
|
e.waitUntil(
|
|
caches.keys().then(function (names) {
|
|
return Promise.all(
|
|
names.filter(function (n) { return n !== CACHE_NAME; })
|
|
.map(function (n) { return caches.delete(n); })
|
|
);
|
|
})
|
|
);
|
|
self.clients.claim();
|
|
});
|
|
|
|
self.addEventListener('fetch', function (e) {
|
|
var url = new URL(e.request.url);
|
|
|
|
// External APIs and RPC proxy — network only, don't cache
|
|
if (url.hostname !== location.hostname || url.pathname.startsWith('/api/')) {
|
|
e.respondWith(fetch(e.request));
|
|
return;
|
|
}
|
|
|
|
// App assets — cache first, fallback to network
|
|
e.respondWith(
|
|
caches.match(e.request).then(function (cached) {
|
|
var networkFetch = fetch(e.request).then(function (response) {
|
|
if (response.ok) {
|
|
var clone = response.clone();
|
|
caches.open(CACHE_NAME).then(function (cache) {
|
|
cache.put(e.request, clone);
|
|
});
|
|
}
|
|
return response;
|
|
}).catch(function () {
|
|
return cached;
|
|
});
|
|
return cached || networkFetch;
|
|
})
|
|
);
|
|
});
|