Repository navigation
Expand file tree
/
Copy pathfilters.js
More file actions
57 lines (46 loc) · 2.18 KB
/
Copy pathfilters.js
File metadata and controls
57 lines (46 loc) · 2.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
* Pluggable filter system. A filter is a function that takes a transaction
* object and returns true to keep it, false to drop it.
*
* Compose filters with `allOf` / `anyOf`. Add your own filters here.
*/
import { getAddress } from "viem";
const KNOWN_METHODS = {
"0xa9059cbb": "transfer(address,uint256)",
"0x23b872dd": "transferFrom(address,address,uint256)",
"0x095ea7b3": "approve(address,uint256)",
"0x38ed1739": "swapExactTokensForTokens(uint256,uint256,address[],address,uint256)",
"0x7ff36ab5": "swapExactETHForTokens(uint256,address[],address,uint256)",
"0x18cbafe5": "swapExactTokensForETH(uint256,uint256,address[],address,uint256)",
"0x791ac947": "swapExactTokensForETHSupportingFeeOnTransferTokens(...)",
"0xb6f9de95": "swapExactETHForTokensSupportingFeeOnTransferTokens(...)",
"0xfb3bdb41": "swapETHForExactTokens(uint256,address[],address,uint256)",
"0x5ae401dc": "multicall(uint256,bytes[])",
"0x3593564c": "execute(bytes,bytes[],uint256)",
"0xc04b8d59": "exactInput((bytes,address,uint256,uint256,uint256))",
};
export function methodSignature(tx) {
if (!tx.input || tx.input === "0x" || tx.input.length < 10) return null;
const sig = tx.input.slice(0, 10).toLowerCase();
return { selector: sig, name: KNOWN_METHODS[sig] ?? null };
}
// --- Composable filters ---
export const allOf = (...filters) => (tx) => filters.every((f) => f(tx));
export const anyOf = (...filters) => (tx) => filters.some((f) => f(tx));
export const not = (filter) => (tx) => !filter(tx);
// --- Common filter primitives ---
export const minValueWei = (min) => (tx) => BigInt(tx.value ?? "0x0") >= BigInt(min);
export const toAddress = (addr) => {
const target = getAddress(addr);
return (tx) => tx.to && getAddress(tx.to) === target;
};
export const fromAddress = (addr) => {
const target = getAddress(addr);
return (tx) => tx.from && getAddress(tx.from) === target;
};
export const methodSelector = (selector) => {
const target = selector.toLowerCase();
return (tx) => methodSignature(tx)?.selector === target;
};
export const isContractCall = () => (tx) => tx.input && tx.input.length >= 10;
export const isEthTransfer = () => (tx) => !tx.input || tx.input === "0x";