Karma Wallet
Karma Wallet turns leftover gas fee “dust” into au
Created on 30th June 2025
•
Karma Wallet
Karma Wallet turns leftover gas fee “dust” into au
The problem Karma Wallet solves
Gas fees are a necessary part of using the blockchain, but they’re often odd amounts that leave “dust” in the wallet. Karma Wallet turns these small amounts into meaningful contributions:
Support open-source projects without actively thinking about it.
Fund community initiatives in a passive, automated way.
Gamify generosity by making every transaction part of a bigger giving story.
Instead of letting your micro-ETH fragments sit idle, they get converted into micro-donations.
Challenges I ran into
⚙️ How It Works — Detailed UserOperation Flow
Karma Wallet is built on ERC-4337 and works within the UserOperation lifecycle. Here’s the exact flow:
1️⃣ Transaction Initiation
- User interacts with a dApp via Karma Wallet.
- The wallet constructs a UserOperation with:
- sender = Karma Wallet smart account address.
- callData = Encoded function call to the target dApp contract.
- value = Transaction value.
- maxFeePerGas = Current gas settings.
- maxPriorityFeePerGas = Current gas settings.
- paymasterAndData = Empty bytes.
- signature = Empty bytes.
2️⃣ UserOperation is signed and sent to Bundler
- The wallet sends the UserOperation to the Bundler.
- The Bundler processes the UserOperation and sends it to the EntryPoint.
- The EntryPoint processes the UserOperation and sends it to the Account Abstraction smart contract.
3️⃣ Account Abstraction Smart Contract
function execute(address dest, uint256 value, bytes calldata func) external {
_requireFromEntryPointOrOwner();
uint256 gasPre = gasleft();
_call(dest, value, func);
uint256 gasPost = gasleft();
uint256 gasUsed = gasPre - gasPost;
uint256 balance = address(this).balance;
uint256 tip = _calculateTip(gasUsed);
if (tip < balance) {
_jar.deposit{value: tip}(gasUsed, tip);
}
}
function _calculateTip(uint256 gasUsed) internal view returns (uint256) {
uint256 ethPriceUSD = _oracleAdaptor.getLatestEthPriceInUsd();
uint256 gasCostInWei = gasUsed * tx.gasprice;
uint256 gasCostInUSD = (gasCostInWei * ethPriceUSD) / 1e18;
uint256 tipInUSD = 0;
uint256 roundingMultipleUSD = 1e16; // $0.01 in 18-decimal USD
if (gasCostInUSD > 0) {
uint256 remainder = gasCostInUSD % roundingMultipleUSD;
if (remainder > 0) {
tipInUSD = roundingMultipleUSD - remainder;
}
}
uint256 tipInWei = (tipInUSD * 1e18) / ethPriceUSD;
return tipInWei;
}
- The Account Abstraction smart contract processes the UserOperation and sends it to the EntryPoint.
gasPreandgasPostmeasure the gas consumed during the call._calculateTip(gasUsed)converts gas used into USD value and determines the rounded-up tip.- If the wallet has enough ETH to cover the tip, it’s sent to the _jar contract.
Technologies used
Cheer Project
Cheering for a project means supporting a project you like with as little as 0.0025 ETH. Right now, you can Cheer using ETH on Arbitrum, Optimism and Base.