Commit 17f26d23 authored by Stefy Spora's avatar Stefy Spora

Fix Web3 donation independence and improve documentation

- Fixed Web3 donation to work on any website, not just FetLife pages
- Improved MetaMask detection in popup context
- Enhanced error handling for Web3 transactions
- Updated README with Web3 donation independence details
- Updated CHANGELOG with version 1.0.1 changes
- Moved Web3 donation logic to popup context for better reliability
parent 5e3cb489
...@@ -5,6 +5,18 @@ All notable changes to the FetLife Privacy Helper extension will be documented i ...@@ -5,6 +5,18 @@ All notable changes to the FetLife Privacy Helper extension will be documented i
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.0.1] - 2025-08-30
### Fixed
- **Web3 Donation Independence**: Fixed Web3 donation functionality to work on any website, not just FetLife pages
- **MetaMask Detection**: Improved MetaMask detection in popup context for better reliability
- **Error Handling**: Enhanced error handling for Web3 transactions and user rejections
- **Popup Context**: Moved Web3 donation logic to popup context for extension-wide availability
### Changed
- **Web3 Integration**: Web3 donations now work independently of current page context
- **MetaMask Support**: Better support for both modern `window.ethereum` and legacy `window.web3` providers
## [1.0.0] - 2025-08-30 ## [1.0.0] - 2025-08-30
### Added ### Added
......
...@@ -55,6 +55,21 @@ A Chrome browser extension that automates privacy settings on FetLife.com. When ...@@ -55,6 +55,21 @@ A Chrome browser extension that automates privacy settings on FetLife.com. When
3. Select "Run on All Media" from the context menu 3. Select "Run on All Media" from the context menu
4. Notifications will show progress and completion status 4. Notifications will show progress and completion status
## Donations
The extension includes multiple donation options to support its development:
### Web3/MetaMask Donation
- **Works on any website** - The Web3 donation is completely independent of the current page
- Click the "🦊 Donate with MetaMask" button in the extension popup
- Supports both modern `window.ethereum` and legacy `window.web3` providers
- Default donation: 0.1 ETH to `0xdA6dAb526515b5cb556d20269207D43fcc760E51`
- Users can modify the amount in MetaMask before confirming
### Bitcoin Donation
- Address: `bc1qcpt2uutqkz4456j5r78rjm3gwq03h5fpwmcc5u`
- Traditional BTC donation method
## How It Works ## How It Works
The extension uses a modern XHR-based approach for reliable privacy updates: The extension uses a modern XHR-based approach for reliable privacy updates:
......
...@@ -233,22 +233,79 @@ document.addEventListener('DOMContentLoaded', function() { ...@@ -233,22 +233,79 @@ document.addEventListener('DOMContentLoaded', function() {
}, 5000); }, 5000);
} }
// Function to check if MetaMask is available via direct injection // Function to check if MetaMask is available in popup context
async function checkMetaMaskDirect(tabId) { function checkMetaMaskAvailable() {
return typeof window.ethereum !== 'undefined' ||
(typeof window.web3 !== 'undefined' && typeof window.web3.currentProvider !== 'undefined');
}
// Function to handle Web3 donation directly in popup context
async function executeWeb3Donation() {
try { try {
const results = await chrome.scripting.executeScript({ // Check if MetaMask is installed
target: { tabId: tabId }, if (!checkMetaMaskAvailable()) {
func: () => { return { success: false, message: 'MetaMask not detected. Please install MetaMask extension.' };
// This function runs in the context of the web page }
return typeof window.ethereum !== 'undefined' ||
(typeof window.web3 !== 'undefined' && typeof window.web3.currentProvider !== 'undefined'); const ethereumProvider = window.ethereum || window.web3.currentProvider;
// Request account access
let accounts;
try {
accounts = await ethereumProvider.request({
method: 'eth_requestAccounts'
});
} catch (requestError) {
// Fallback for legacy providers
if (ethereumProvider.enable) {
accounts = await ethereumProvider.enable();
} else {
throw requestError; // Re-throw if no fallback available
} }
}); }
if (!accounts || accounts.length === 0) {
return { success: false, message: 'No accounts found. Please unlock your Web3 wallet.' };
}
const donationAddress = '0xdA6dAb526515b5cb556d20269207D43fcc760E51';
// Prepare transaction parameters (user can modify amount in wallet)
const transactionParameters = {
to: donationAddress,
from: accounts[0],
value: '0x16345785D8A0000', // 0.1 ETH in wei (default amount, user can change)
gas: '0x5208', // 21000 gas limit for simple transfer
};
// Send transaction
let txHash;
try {
txHash = await ethereumProvider.request({
method: 'eth_sendTransaction',
params: [transactionParameters],
});
} catch (transactionError) {
// Handle user rejection specifically
if (transactionError.code === 4001 ||
(transactionError.message && transactionError.message.includes('User denied transaction signature'))) {
return { success: false, message: 'Transaction cancelled by user.' };
}
throw transactionError; // Re-throw other errors
}
return { success: true, message: `Transaction sent! Hash: ${txHash.substring(0, 10)}...` };
return results[0].result === true;
} catch (error) { } catch (error) {
console.error('Direct MetaMask check failed:', error); console.error('Web3 donation error:', error);
return false;
if (error.code === 4001 || (error.message && error.message.includes('User denied'))) {
return { success: false, message: 'Transaction cancelled by user.' };
} else if (error.code === -32602) {
return { success: false, message: 'Invalid transaction parameters.' };
} else {
return { success: false, message: `Transaction failed: ${error.message || error.toString()}` };
}
} }
} }
...@@ -316,6 +373,29 @@ document.addEventListener('DOMContentLoaded', function() { ...@@ -316,6 +373,29 @@ document.addEventListener('DOMContentLoaded', function() {
web3DonateBtn.textContent = '🦊 Donate with MetaMask'; web3DonateBtn.textContent = '🦊 Donate with MetaMask';
} }
}); });
// Remove the old web3 event listener and add the new one
const oldBtn = document.getElementById('web3-donate-btn');
if (oldBtn) {
oldBtn.replaceWith(oldBtn.cloneNode(true));
const newBtn = document.getElementById('web3-donate-btn');
newBtn.addEventListener('click', async function() {
try {
newBtn.disabled = true;
newBtn.textContent = '🔄 Connecting...';
// Execute Web3 donation directly in popup context
const result = await executeWeb3Donation();
showWeb3Status(result.message, !result.success);
} catch (error) {
console.error('Web3 donation error:', error);
showWeb3Status('Failed to initiate donation: ' + (error.message || 'Unknown error'), true);
} finally {
newBtn.disabled = false;
newBtn.textContent = '🦊 Donate with MetaMask';
}
});
}
}); });
// Function to find and click the next link // Function to find and click the next link
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment