OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-wallet-desktop commits / 7e39ed6

Fix: disable native notifications (libnotify blocks) and store token transactions locally
Deployment: testing (hyper-wallet-desktop-test) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7e39ed68e7d5846943cab77271d118af112722d1
by plankatron <fleeky@gmail.com> · 2026-01-30T03:13:08.000Z

Changed files (3) +34 -42

.claude/deployment-history.json +2 -2
……@@ -4,7 +4,7 @@
44 "branch": "testing",
55 "version": "unknown",
66 "pear_key": "pear://unknown",
7 "deployed_at": "2026-01-29T22:03:04-05:00",
8 "commit_message": "Fix: use current account index for token transfers and add testnet contract fallbacks",
7 "deployed_at": "2026-01-29T22:09:37-05:00",
8 "commit_message": "Fix: make notifications non-blocking to prevent UI hang",
99 "tmux": "pear-seed:5"
1010}
desktop/wallet.js +10 -40
……@@ -3809,49 +3809,19 @@ function setupNativeFeatureListeners() {
38093809}
38103810
38113811// Native Notification Helper
3812// NOTE: Native notifications disabled in Pear runtime due to libnotify blocking issues
3813// Using in-app toasts only (showSuccess/showError)
38123814function showNotification(title, body, type = 'info') {
3813 // Always log to console (primary notification method)
3815 // Log to console only - native notifications cause UI freeze in Pear runtime
38143816 console.log(`📢 Notification: ${title} - ${body}`)
38153817
3816 // Run notification in a separate task to avoid blocking UI
3817 // Wrap everything in setTimeout(0) to make it non-blocking
3818 setTimeout(() => {
3819 try {
3820 // Check if Notification API is available
3821 if ('Notification' in window) {
3822 // Request permission if not already granted
3823 if (Notification.permission === 'granted') {
3824 new Notification(title, {
3825 body: body,
3826 icon: '/assets/icon.png', // Add app icon if available
3827 badge: '/assets/badge.png'
3828 })
3829 } else if (Notification.permission !== 'denied') {
3830 Notification.requestPermission().then(permission => {
3831 if (permission === 'granted') {
3832 try {
3833 new Notification(title, {
3834 body: body,
3835 icon: '/assets/icon.png',
3836 badge: '/assets/badge.png'
3837 })
3838 } catch (err) {
3839 // Silently fail - notification not critical
3840 console.log('📢 Native notification unavailable (not critical)')
3841 }
3842 }
3843 }).catch(err => {
3844 // Silently fail - notification not critical
3845 console.log('📢 Notification permission request failed (not critical)')
3846 })
3847 }
3848 }
3849 } catch (err) {
3850 // Silently fail if notification system not available
3851 // This is expected on systems without notification daemon
3852 console.log('📢 Native notifications unavailable (not critical):', err.message)
3853 }
3854 }, 0)
3818 // Show in-app notification via toast (non-blocking)
3819 if (type === 'success') {
3820 showSuccess(`${title}: ${body}`)
3821 } else if (type === 'error') {
3822 showError(`${title}: ${body}`)
3823 }
3824 // Native Notification API disabled - causes libnotify blocking in pear-runtime
38553825}
38563826
38573827// Expose functions to global window object for onclick/onchange handlers
wallet-server.cjs +22 -0
……@@ -1835,6 +1835,28 @@ const routes = {
18351835 console.log(` Fee: ${formatAmount(fee, baseChain)}`)
18361836 console.log(` To: ${to}`)
18371837
1838 // Store transaction locally so it appears immediately
1839 try {
1840 const fromAddress = await account.getAddress()
1841 await storeTransaction({
1842 hash: result.hash,
1843 chain: chain, // e.g., 'ethereum-usdc'
1844 network,
1845 direction: 'sent',
1846 from: fromAddress,
1847 to,
1848 amount: amountBigInt.toString(),
1849 fee: (result.fee || fee).toString(),
1850 timestamp: Date.now(),
1851 status: 'pending',
1852 token: tokenInfo.symbol
1853 })
1854 console.log(` 💾 Transaction stored locally`)
1855 } catch (storeErr) {
1856 console.warn(' ⚠️ Failed to store transaction locally:', storeErr.message)
1857 // Non-critical - transaction still succeeded on-chain
1858 }
1859
18381860 sendJSON(res, {
18391861 hash: result.hash,
18401862 fee: result.fee.toString(),