/ README.md
README.md
1 Account Monitor 2 =============== 3 4 > Locally monitor accounts on EVM chains, without leaking information to RPC providers. 5 6 # Why? 7 The goal of this project is to notify users if something unexpected happened (account was compromised), in a way that preserves privacy from 3rd party services. 8 9 # Limitations 10 * For native token transfers, only outgoing transactions are detected (wen [EIP-7708](https://eip.tools/eip/7708)?) and those, only when using `Blocks` mode. 11 * Smart contract wallets will not trigger any notifications when sending native tokens, even in `Blocks` mode. 12 * While some types of transactions are properly identified, "complex" transactions (swaps/buy) will not be correctly categorized, but a notification will be sent (depending on spam filter options). 13 * The token symbols come from [rotki assets](https://github.com/rotki/assets) which means that not all tokens are included and the list is only updated when Account Monitor is updated. 14 * No notifications for previous transactions. 15 16 # Features 17 * Support any EVM chain (at least in `Events` mode). 18 * Use [ntfy](https://ntfy.sh/) to allow self-hosted notifications. 19 * Load accounts via a yaml on start and/or via an API call. 20 * Script to load accounts from [rotki](https://rotki.com/). 21 * Prometheus monitoring endpoint. 22 23 # Quickstart 24 25 Requirements: docker 26 27 1. Clone this repository 28 2. Copy `.env.example` to `.env` 29 3. Configure variables in `.env` (requires an Alchemy API key and ntfy token) 30 4. Copy `accounts.example.yaml` to `accounts.yaml` 31 5. Modify `accounts.yaml` to remove the examples and add the accounts to monitor 32 6. Run `docker-compose up` 33 34 The instructions above use Alchemy to make them easy to follow, if you want to use another RPC provider (or even better, your own node), set the appropriate endpoint for `CHAIN_RPC_ETHEREUM` in `docker-compose.yaml` 35 36 # Configuration 37 Configuration is done via environment variables 38 39 ## Global 40 41 | Variable | Type | Required | Description | 42 | --- | --- | --- | --- | 43 |`NTFY_TOKEN` | `string` | `true` | Ntfy's Auth token | 44 |`NTFY_URL` | `string` | `true` | Ntfy's server URL | 45 |`NTFY_TOPIC` | `string` | `true` | Topic to send notifications to | 46 |`CHAINS` | `string` | `true` | Uppercase comma separated list of chains to monitor (any EVM chain is supported) | 47 |`STATIC_ACCOUNTS_PATH`| `string` | `false` | Location from which to read the accounts to add during launch. This should be a yaml file with the same format as `accounts.example.yaml`. If not set, all accounts must be added via REST | 48 49 ## Per Chain 50 For each chain defined in `CHAINS` there should be a block with the following variables, with the defined suffix (`ETHEREUM` in this example) 51 52 | Variable | Type | Required | Default | Description | 53 | --- | --- | --- | --- | --- | 54 |`CHAIN_RPC_ETHEREUM` | `string` | `true` | | HTTPS RPC of a chain | 55 | `CHAIN_NAME_ETHEREUM` | `string` | `true` | | Used in the notifications' message | 56 | `CHAIN_BLOCKTME_ETHEREUM` | `int` | `true` | | Milliseconds in between blocks. When using `Event` mode, increasing this value will make fewer requests to the RPC, batching all blocks in an interval | 57 | `CHAIN_MODE_ETHEREUM` | `Blocks | Events` | `false` | `Blocks` | Method to use when queering RPCs for new transactions. See [Mode](#mode) | 58 | `CHAIN_SPAM_FILTER_LEVEL_ETHEREUM` | `None | KnownAssets | SelfSubmittedTxs` | `false` | `KnownAssets` | Spam filter configuration for the chain, see [Spam Filter](#spam-filter) | 59 | `CHAIN_EXPLORER_ETHEREUM` | `string` | `false` | `None` | Domain of the chain's explorer, to include a link in the notification | 60 | `CHAIN_ID_ETHEREUM` | `int` | `false` | | Chain ID. Only used for verification, will be ignored if not configured | 61 62 ### Mode 63 One of the goals of this project is to be able to monitor accounts across all the EVM chains a user wants for free using an RPC provider. The two modes have important trade-offs, choose carefully. Neither method leaks any of the monitored accounts to the RPC providers. 64 * **Events**: The events mode will **not** include outgoing transfers of native tokens nor transactions which do not emit any onchain Events/Logs, but setting a `CHAIN_BLOCKTME_chain` higher than the actual chain blocktime (5000 for 5s) allows users to scrape 6~7 chains using a free Alchemy account. 65 * **Blocks**: Blocks mode uses a more expensive method to query RPCs but does include all outgoing transactions even if they only send native tokens or don't have any Events/Logs. Not all RPC Provider/Chains support this mode as it uses the newish method `eth_getBlockReceipts` (or Alchemy's version `alchemy_getTransactionReceipts`) 66 67 ### Spam Filter 68 Chains with cheap gas cause a lot of incoming spam/scam transactions. `CHAIN_SPAM_FILTER_LEVEL_chain` can be used to filter out unwanted notifications. The available options are: (from strict to noisy) 69 * **SelfSubmittedTxs**: Only transactions sent by monitored accounts will trigger notifications. Will not notify of any incoming transactions. Not useful for use with Smart Contract Wallets. 70 * **KnownAssets**: Transactions that pass SelfSubmittedTxs + Transactions where a known token (from [rotki assets](https://github.com/rotki/assets)) is transferred to or from a monitored account. 71 * **None**: All transactions will trigger notifications. 72 73 ## Debugging configuration 74 The following environment variables can be used to debug Account Monitor 75 76 77 | Variable | Type | Required | Default | Description | 78 | --- | --- | --- | --- | --- | 79 | `RUST_LOG` | `string` | `false` | | Use `account_monitor=debug` to enable debugging | 80 | `NTFY_DISABLE` | `boolean` | `false` | `false` | Log notification message instead of sending it through ntfy. Makes ntfy env variables optional. RUST_LOG should be at least set to `info`. | 81 | `DEBUG_BLOCK` | `int` | `false` | | Look for transactions in a single block. The program will exit when a transaction of a monitored account is found. | 82 83 # API 84 The API exposes a single endpoint to add a monitored account. There is no way to list the currently monitored accounts. Attempts to add an already monitored account, will be ignored. 85 86 A reverse proxy can be used to manage access to the API endpoint. 87 88 The following command can be used to add a new account: 89 ```sh 90 curl --json '{"address":"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "label":"Vitalik"}' http://localhost:3030 91 ``` 92 93 # Scripts 94 A couple of helper scripts are available to facilitate adding accounts via the API. 95 Both scripts need `LOADING_SCRIPTS_HOST` to be set (or included in `.env`) this should point to where Account Monitor is running. 96 97 * `scripts/load_accounts_from_rotki.sh`: Requires rotki to be open and logged in. Will monitor all the user's Ethereum addresses setup in rotki. 98 * `scripts/load_accounts_from_yaml.sh`: Receives the location of a yaml file with accounts as a parameter. The file should have the same format as [accounts.example.yaml](./accounts.example.yaml). 99 100 # Acknowledgments 101 Thanks to [rotki](https://rotki.com) for curating tokens and known addresses. And an awesome portfolio tracker. 102 103 Thanks to [ntfy](https://ntfy.sh) for a building a simple to use notification server, compatible with computers, and phones with most OSs. 104 105 # Contributing 106 Issues and PRs for this repository are welcome and managed in [Radicle](https://radicle.xyz/guides/user). 107 108 Repository ID: [rad:z3SRsZ8YdvUg4UEkqffuHrFdFEcML](https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z3SRsZ8YdvUg4UEkqffuHrFdFEcML)