eth-portfolio-temp 0.0.20.dev0__tar.gz → 0.0.22.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of eth-portfolio-temp might be problematic. Click here for more details.

Files changed (112) hide show
  1. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/PKG-INFO +1 -1
  2. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/README.md +9 -5
  3. eth_portfolio_temp-0.0.22.dev0/docs/exporter.rst +131 -0
  4. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/index.rst +1 -0
  5. eth_portfolio_temp-0.0.22.dev0/docs/new-protocols.rst +132 -0
  6. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/__init__.py +9 -0
  7. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_loaders/token_transfer.py +1 -1
  8. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_shitcoins.py +1 -0
  9. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/docker/__init__.py +2 -1
  10. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/docker/docker_compose.py +15 -6
  11. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/main.py +9 -1
  12. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_temp.egg-info/PKG-INFO +1 -1
  13. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_temp.egg-info/SOURCES.txt +1 -0
  14. eth_portfolio_temp-0.0.20.dev0/docs/exporter.rst +0 -44
  15. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/.env.sample +0 -0
  16. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/.github/workflows/black.yaml +0 -0
  17. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/.github/workflows/compile.yaml +0 -0
  18. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/.github/workflows/deploy_docs.yaml +0 -0
  19. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/.github/workflows/mypy.yaml +0 -0
  20. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/.github/workflows/release.yaml +0 -0
  21. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/.gitignore +0 -0
  22. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/Makefile +0 -0
  23. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/brownie-config.yaml +0 -0
  24. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/Makefile +0 -0
  25. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/alabaster.css +0 -0
  26. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/basic.css +0 -0
  27. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/custom.css +0 -0
  28. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/doctools.js +0 -0
  29. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/documentation_options.js +0 -0
  30. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/file.png +0 -0
  31. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/language_data.js +0 -0
  32. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/minus.png +0 -0
  33. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/plus.png +0 -0
  34. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/pygments.css +0 -0
  35. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/searchtools.js +0 -0
  36. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/_build/html/_static/sphinx_highlight.js +0 -0
  37. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/conf.py +0 -0
  38. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/docs/make.bat +0 -0
  39. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_argspec.py +0 -0
  40. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_cache.py +0 -0
  41. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_config.py +0 -0
  42. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_db/__init__.py +0 -0
  43. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_db/decorators.py +0 -0
  44. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_db/entities.py +0 -0
  45. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_db/utils.py +0 -0
  46. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_decimal.py +0 -0
  47. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_decorators.py +0 -0
  48. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_exceptions.py +0 -0
  49. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_ledgers/__init__.py +0 -0
  50. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_ledgers/address.py +0 -0
  51. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_ledgers/portfolio.py +0 -0
  52. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_loaders/__init__.py +0 -0
  53. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_loaders/_nonce.py +0 -0
  54. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_loaders/balances.py +0 -0
  55. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_loaders/transaction.py +0 -0
  56. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_loaders/utils.py +0 -0
  57. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_submodules.py +0 -0
  58. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_utils.py +0 -0
  59. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_ydb/__init__.py +0 -0
  60. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/_ydb/token_transfers.py +0 -0
  61. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/address.py +0 -0
  62. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/buckets.py +0 -0
  63. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/constants.py +0 -0
  64. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/portfolio.py +0 -0
  65. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/__init__.py +0 -0
  66. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/_base.py +0 -0
  67. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/convex.py +0 -0
  68. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/dsr.py +0 -0
  69. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/lending/README.md +0 -0
  70. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/lending/__init__.py +0 -0
  71. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/lending/_base.py +0 -0
  72. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/lending/compound.py +0 -0
  73. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/lending/liquity.py +0 -0
  74. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/lending/maker.py +0 -0
  75. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/lending/unit.py +0 -0
  76. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/protocols/liquity.py +0 -0
  77. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/py.typed +0 -0
  78. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/structs/__init__.py +0 -0
  79. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/structs/modified.py +0 -0
  80. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/structs/structs.py +0 -0
  81. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/typing/__init__.py +0 -0
  82. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio/typing/balance/single.py +0 -0
  83. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/__init__.py +0 -0
  84. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/_args.py +0 -0
  85. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/_logging.py +0 -0
  86. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/_portfolio.py +0 -0
  87. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/_utils.py +0 -0
  88. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/balances.py +0 -0
  89. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/docker/.grafana/dashboards/dashboards.yaml +0 -0
  90. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/docker/.grafana/dashboards/portfolio/Balances.json +0 -0
  91. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/docker/.grafana/datasources/datasources.yml +0 -0
  92. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/docker/check.py +0 -0
  93. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/docker/docker-compose.yaml +0 -0
  94. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/py.typed +0 -0
  95. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/victoria/__init__.py +0 -0
  96. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_scripts/victoria/types.py +0 -0
  97. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_temp.egg-info/dependency_links.txt +0 -0
  98. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_temp.egg-info/entry_points.txt +0 -0
  99. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_temp.egg-info/not-zip-safe +0 -0
  100. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_temp.egg-info/requires.txt +0 -0
  101. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/eth_portfolio_temp.egg-info/top_level.txt +0 -0
  102. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/pyproject.toml +0 -0
  103. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/requirements.txt +0 -0
  104. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/setup.cfg +0 -0
  105. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/setup.py +0 -0
  106. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/tests/_test_completeness.py +0 -0
  107. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/tests/conftest.py +0 -0
  108. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/tests/fixtures.py +0 -0
  109. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/tests/protocols/test_external.py +0 -0
  110. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/tests/scripts/test_utils.py +0 -0
  111. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/tests/test_portfolio.py +0 -0
  112. {eth_portfolio_temp-0.0.20.dev0 → eth_portfolio_temp-0.0.22.dev0}/tests/test_typing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eth_portfolio_temp
3
- Version: 0.0.20.dev0
3
+ Version: 0.0.22.dev0
4
4
  Summary: eth-portfolio makes it easy to analyze your portfolio.
5
5
  Home-page: https://github.com/BobTheBuidler/eth-portfolio
6
6
  Author: BobTheBuidler
@@ -1,17 +1,21 @@
1
1
  # eth-portfolio
2
2
  Use `eth-portfolio` to output information about your portfolio in a streamlined, speed-optimized way.
3
3
 
4
+ ### Requirements
5
+ - Python 3.9 or higher.
6
+ - At least 16GB of RAM.
7
+
8
+ ### Prerequisites
9
+ - First, you will need to bring your own archive node. This can be one you run yourself, or one from one of the common providers (Tenderly, Alchemy, QuickNode, etc.)
10
+ - You must configure a [brownie network](https://eth-brownie.readthedocs.io/en/stable/network-management.html) to use your RPC.
11
+ - You will also need an auth token for [Etherscan](https://etherscan.io/)'s API. Follow their [guide](https://docs.etherscan.io/etherscan-v2/getting-an-api-key) to get your key, and set env var `ETHERSCAN_TOKEN` with its value.
12
+
4
13
  ### Installation:
5
14
  - Make sure you are using Python >= 3.9 and < 3.13. You should start with a fresh virtual environment, and then just...
6
15
  ```
7
16
  pip install git+https://github.com/BobTheBuidler/eth-portfolio
8
17
  ```
9
18
 
10
- ### Prerequisites
11
-
12
- - First, you will need to bring your own archive node. This can be one you run yourself, or one from one of the common providers (Tenderly, Alchemy, QuickNode, etc.)
13
- - You must configure a [brownie network](https://eth-brownie.readthedocs.io/en/stable/network-management.html) to use your RPC.
14
-
15
19
  ### Usage:
16
20
  For basic use, input each of your addresses as environment variables using the following pattern:
17
21
  ```
@@ -0,0 +1,131 @@
1
+ Portfolio Exporter
2
+ ==================
3
+
4
+ Overview
5
+ --------
6
+ The Portfolio Exporter is a command-line tool provided by eth-portfolio. It is designed to extract and compile portfolio data – such as token balances, transaction history, and other relevant financial information – into exportable formats that can be further analyzed or integrated with external services.
7
+
8
+ Requirements
9
+ ------------
10
+ - Python 3.10 or higher.
11
+ - At least 16GB of RAM.
12
+ - All dependencies installed as specified in the project’s ``requirements.txt`` file.
13
+ - Proper configuration settings (e.g., API keys, network endpoints) must be set up as required by the portfolio and balance loaders. More info below.
14
+
15
+ Usage
16
+ -----
17
+ The Portfolio Exporter should be used via the CLI. Include each of your wallets in the command like so:
18
+
19
+ .. code-block:: bash
20
+
21
+ eth-portfolio export --wallet 0x123 --wallet 0x234 --wallet 0x345
22
+
23
+ Command-Line Options
24
+ --------------------
25
+ The Portfolio Exporter supports several command-line options to customize its behavior:
26
+
27
+ - ``--wallet <address>``
28
+ Specify a wallet to be included in your portfolio. You can pass this flag multiple times for multiple wallets.
29
+
30
+ - ``--network <network-id>``
31
+ The brownie network identifier for the rpc you wish to use. default: mainnet
32
+
33
+ - ``--interval <interval>``
34
+ The time interval between datapoints. default: 6h
35
+
36
+ - ``--first-tx-block <block>``
37
+ The block of your portfolio's first transaction, if known. This value, if provided, allows us to speed up processing of your data by limiting the block range we need to query. If not provided, the whole blockchain will be scanned. default: 0
38
+
39
+ - ``--export-start-block <block>``
40
+ The first block in the range you wish to export. default: 0
41
+
42
+ Docker Containers
43
+ -----------------
44
+ When you run the Portfolio Exporter, ETH Portfolio will build and start 3 required Docker containers on your system, as well as up to 1 optional container depending on your configuration. These containers work together to collect, store, and visualize your portfolio data:
45
+
46
+ - ``grafana``
47
+ The Grafana container provides a web-based dashboard for visualizing your portfolio metrics and balances. It is pre-configured with a "Balances" dashboard and uses victoria-metrics as its Prometheus-compatible data source. Grafana is accessible locally (default port 3000) and supports dashboard image rendering via the renderer container. Anonymous access is enabled for convenience.
48
+
49
+ - ``renderer`` (optional)
50
+ The renderer container runs the official grafana-image-renderer service, enabling Grafana to export dashboards as images. This is useful for generating reports or sharing visualizations. It is tightly integrated with the Grafana container and operates on port 8091 by default. **This container is only started if you pass the ``--start-renderer`` flag to the infra command.**
51
+
52
+ - ``victoria-metrics``
53
+ victoria-metrics is a high-performance, long-retention time-series database that stores all portfolio and balance metrics. Data is persisted to a local volume for durability, with a default retention period of 10 years. It receives metrics from vmagent and serves as the main data source for Grafana (default port 8428).
54
+
55
+ - ``vmagent``
56
+ vmagent is responsible for collecting and forwarding metrics to victoria-metrics. It is configured to remote write all scraped metrics to the victoria-metrics container. vmagent ensures that all relevant portfolio data is reliably collected and stored for visualization and analysis.
57
+
58
+ Data Flow Summary
59
+ -----------------
60
+ The containers interact as follows:
61
+
62
+ 1. **eth-portfolio** and/or related exporters expose metrics endpoints.
63
+ 2. **vmagent** scrapes these endpoints and forwards the data to **victoria-metrics**.
64
+ 3. **victoria-metrics** stores the time-series data for long-term analysis.
65
+ 4. **Grafana** is pre-configured to use victoria-metrics as its data source and provides dashboards (such as "Balances") for visualization.
66
+ 5. The **renderer** container enables Grafana to export dashboards as images for reporting or sharing (if started with ``--start-renderer``).
67
+
68
+ .. mermaid::
69
+
70
+ graph TD
71
+ A[eth-portfolio metrics/exporters] --> B(vmagent)
72
+ B --> C(victoria-metrics)
73
+ C --> D[Grafana]
74
+ D --> E[renderer]
75
+ D --> F[User Dashboard]
76
+
77
+ Additional Information
78
+ ----------------------
79
+ - All containers are orchestrated via Docker Compose and are automatically started as needed.
80
+ - Grafana provisioning files ensure dashboards and data sources are set up out-of-the-box.
81
+ - Metrics are stored with a long retention period, enabling historical analysis.
82
+ - Dashboard images can be generated for reporting via the renderer (if started).
83
+
84
+ Data Extraction and Portfolio Calculations
85
+ ------------------------------------------
86
+
87
+ The Portfolio Exporter performs a comprehensive extraction and calculation process to ensure accurate and detailed portfolio data. The workflow is as follows:
88
+
89
+ **1. Data Extraction Process**
90
+
91
+ - **Per-Wallet, Per-Timestamp:**
92
+ For each wallet specified via the CLI, the exporter iterates over a series of timestamps (based on the `--interval` argument). At each timestamp, it determines the corresponding Ethereum block and extracts a snapshot of the portfolio at that point in time.
93
+
94
+ - **Asynchronous Data Loading:**
95
+ The exporter leverages highly concurrent, asynchronous routines to efficiently load data for all wallets and tokens. It uses specialized loader functions to fetch:
96
+ - Token balances (including ERC-20 and protocol-specific tokens)
97
+ - Transaction history
98
+ - Token transfers
99
+ - Protocol positions (e.g., lending, borrowing, staking)
100
+
101
+ - **Block and Transaction Resolution:**
102
+ For each timestamp, the exporter resolves the closest block and loads all relevant on-chain data for the specified wallets. This includes querying balances, fetching transaction receipts, and aggregating protocol positions.
103
+
104
+ **2. Portfolio Calculations**
105
+
106
+ - **Balance and Value Computation:**
107
+ For each token held by a wallet, the exporter calculates:
108
+ - The raw token balance
109
+ - The USD value of the balance (using price oracles or on-chain data)
110
+ - Protocol-specific metrics (e.g., supplied/borrowed amounts, rewards)
111
+
112
+ - **Aggregation and Structuring:**
113
+ The exporter organizes data into logical sections, such as "assets", "debts", and "external" protocol positions. It aggregates balances across all wallets and protocols, ensuring a unified view of the portfolio.
114
+
115
+ - **Metric Formatting:**
116
+ Each data point is formatted as a Prometheus metric, including metadata such as wallet address, token address, token symbol, protocol name, and a logical "bucket" for grouping. Both the raw balance and USD value are exported for each token.
117
+
118
+ **3. Export and Storage**
119
+
120
+ - **Deduplication:**
121
+ Before exporting, the system checks if data for a given timestamp already exists in the time-series database to avoid redundant processing.
122
+
123
+ - **Export to VictoriaMetrics:**
124
+ The processed metrics are sent to the VictoriaMetrics time-series database, where they are stored for long-term analysis and visualization in Grafana.
125
+
126
+ - **Error Handling and Robustness:**
127
+ The exporter is designed to handle network errors, missing data, and protocol-specific quirks gracefully, ensuring reliable and repeatable exports.
128
+
129
+ **Summary**
130
+
131
+ This architecture allows the Portfolio Exporter to provide a high-fidelity, time-resolved view of all wallet balances, protocol positions, and historical portfolio values. The modular, asynchronous design ensures scalability and performance, even for large portfolios or long time ranges.
@@ -12,6 +12,7 @@ Welcome to eth-portfolio's documentation!
12
12
 
13
13
  source/modules.rst
14
14
  exporter
15
+ new-protocols
15
16
 
16
17
  Indices and tables
17
18
  ==================
@@ -0,0 +1,132 @@
1
+ Contributing: Adding New Protocols
2
+ ==================================
3
+
4
+ This guide explains how to add support for new staking pools, lending/borrowing protocols, and other DeFi integrations to eth-portfolio. The system is designed for extensibility, using abstract base classes (ABCs) and a modular protocol architecture.
5
+
6
+ Choosing the Appropriate Base Class
7
+ -----------------------------------
8
+
9
+ eth-portfolio supports several types of protocols, each with a corresponding abstract base class. To add a new protocol, first determine which category your integration fits into:
10
+
11
+ - **Generic Protocol** (`ProtocolABC`):
12
+ Use this for most DeFi protocols that do not fit a more specific category. This is the most flexible base class and is suitable for lending, borrowing, or any protocol with custom logic.
13
+ See: `Adding a New Lending/Borrowing or Generic Protocol`_
14
+
15
+ - **Staking Pool** (`StakingPoolABC`):
16
+ Use this for protocols where users stake tokens to earn rewards, and the pool may have multiple tokens or custom reward logic.
17
+ See: `Adding a New Staking Pool`_
18
+
19
+ - **Single-Token Staking Pool** (`SingleTokenStakingPoolABC`):
20
+ Use this for staking pools that only accept a single token and have a straightforward staking/reward structure.
21
+ See: `Adding a New Single-Token Staking Pool`_
22
+
23
+ - **Protocol with Staking** (`ProtocolWithStakingABC`):
24
+ Use this if your protocol combines lending/borrowing or other DeFi features with an integrated staking component.
25
+ See: `Adding a Protocol with Staking`_
26
+
27
+ If you are unsure, start with `ProtocolABC` for lending/borrowing or custom protocols, and use the staking pool base classes for staking integrations. See the subsections below for details and examples.
28
+
29
+ Adding a New Staking Pool
30
+ -------------------------
31
+
32
+ Subclass `StakingPoolABC` from `eth_portfolio/protocols/_base.py` for pools with multiple tokens or custom logic.
33
+
34
+ **Steps:**
35
+ 1. Subclass `StakingPoolABC`.
36
+ 2. Implement the `_balances` method to return a `TokenBalances` mapping for a given address and block.
37
+ 3. Implement any required methods such as `contract`, `deploy_block`, etc.
38
+ 4. Register your pool in the appropriate protocol module.
39
+
40
+ **Example:**
41
+
42
+ .. code-block:: python
43
+
44
+ from eth_portfolio.protocols._base import StakingPoolABC
45
+
46
+ class MyStakingPool(StakingPoolABC):
47
+ def contract(self):
48
+ # Return a web3 contract instance for the staking pool
49
+ ...
50
+
51
+ async def _balances(self, address, block=None):
52
+ # Query the staked balance and rewards for the address
53
+ ...
54
+
55
+ See `eth_portfolio/protocols/liquity.py` for real-world examples.
56
+
57
+ Adding a New Single-Token Staking Pool
58
+ --------------------------------------
59
+
60
+ Subclass `SingleTokenStakingPoolABC` from `eth_portfolio/protocols/_base.py` for pools that only accept a single token.
61
+
62
+ **Example:**
63
+
64
+ .. code-block:: python
65
+
66
+ from eth_portfolio.protocols._base import SingleTokenStakingPoolABC
67
+
68
+ class MySingleTokenStakingPool(SingleTokenStakingPoolABC):
69
+ def contract(self):
70
+ ...
71
+
72
+ async def _balances(self, address, block=None):
73
+ ...
74
+
75
+ See `eth_portfolio/protocols/liquity.py` and `eth_portfolio/protocols/convex.py` for examples.
76
+
77
+ Adding a New Lending/Borrowing or Generic Protocol
78
+ --------------------------------------------------
79
+
80
+ Subclass `ProtocolABC` from `eth_portfolio/protocols/_base.py` for lending, borrowing, or other custom DeFi protocols.
81
+
82
+ **Steps:**
83
+ 1. Subclass `ProtocolABC`.
84
+ 2. Implement the `_balances` method to return a `TokenBalances` mapping, including supplied, borrowed, and reward tokens.
85
+ 3. Register your protocol in the appropriate module.
86
+
87
+ **Example:**
88
+
89
+ .. code-block:: python
90
+
91
+ from eth_portfolio.protocols._base import ProtocolABC
92
+
93
+ class MyLendingProtocol(ProtocolABC):
94
+ async def _balances(self, address, block=None):
95
+ # Query supplied and borrowed balances for the address
96
+ ...
97
+
98
+ See `eth_portfolio/protocols/dsr.py` and `eth_portfolio/protocols/lending/` for examples.
99
+
100
+ Adding a Protocol with Staking
101
+ ------------------------------
102
+
103
+ If your protocol combines lending/borrowing with staking, subclass `ProtocolWithStakingABC` from `eth_portfolio/protocols/_base.py`.
104
+
105
+ **Example:**
106
+
107
+ .. code-block:: python
108
+
109
+ from eth_portfolio.protocols._base import ProtocolWithStakingABC
110
+
111
+ class MyProtocolWithStaking(ProtocolWithStakingABC):
112
+ async def _balances(self, address, block=None):
113
+ # Query balances and staking positions
114
+ ...
115
+
116
+ See `eth_portfolio/protocols/convex.py` for an example.
117
+
118
+ Best Practices and Tips
119
+ -----------------------
120
+
121
+ - **Use Async Methods:** All balance queries should be asynchronous for performance.
122
+ - **Handle Edge Cases:** Account for protocol-specific quirks, such as non-standard tokens or special reward logic.
123
+ - **Testing:** Add tests for your protocol to ensure correctness and compatibility.
124
+ - **Documentation:** Document your protocol’s behavior and any configuration requirements.
125
+
126
+ References
127
+ ----------
128
+
129
+ - Abstract base classes: `eth_portfolio/protocols/_base.py`
130
+ - Example staking pools: `eth_portfolio/protocols/liquity.py`, `eth_portfolio/protocols/convex.py`
131
+ - Example lending protocols: `eth_portfolio/protocols/dsr.py`, `eth_portfolio/protocols/lending/`
132
+ - Protocol registration: `eth_portfolio/protocols/__init__.py`
@@ -1,3 +1,12 @@
1
+ import warnings
2
+
3
+ warnings.filterwarnings(
4
+ "ignore",
5
+ message="Changing decimals precision could have unintended side effects!",
6
+ category=UserWarning,
7
+ )
8
+
9
+
1
10
  import a_sync._smart
2
11
 
3
12
  a_sync._smart.set_smart_task_factory()
@@ -148,7 +148,7 @@ async def _insert_to_db(transfer: TokenTransfer, load_prices: bool) -> None:
148
148
  raise
149
149
  except decimal.InvalidOperation as e:
150
150
  # TODO: debug why this happens sometimes
151
- logger.exception(e, transfer)
151
+ logger.exception("%s %s", e, transfer)
152
152
  pass
153
153
 
154
154
 
@@ -89,6 +89,7 @@ shitcoins: Final = {
89
89
  "0xF01f7A348681776c1FC9A066c6973882B693cdC6",
90
90
  "0x0e1CD6d2715432e4DBedFE969b0Eb2867FF61d5b",
91
91
  # Generally looks like shit
92
+ "0x7CD6143B8781dC7e0667e50DB02Eb6539799722F",
92
93
  "0x174Cd3359C6a4E6B64D2995Da4E2E4631379526E",
93
94
  "0x85E199607eb8aEef775Ae6424b42d20616267852",
94
95
  "0x4D57c67C8Bab0Fb3A0a0A35B904FBff4E5450521",
@@ -1,11 +1,12 @@
1
1
  from eth_portfolio_scripts.docker.check import *
2
- from eth_portfolio_scripts.docker.docker_compose import build, down, ensure_containers, up
2
+ from eth_portfolio_scripts.docker.docker_compose import build, down, ensure_containers, up, stop
3
3
 
4
4
  __all__ = [
5
5
  # commands
6
6
  "build",
7
7
  "up",
8
8
  "down",
9
+ "stop",
9
10
  # decorators
10
11
  "ensure_containers",
11
12
  # checks
@@ -14,19 +14,28 @@ logger = logging.getLogger(__name__)
14
14
  compose_file = path.join(path.dirname(path.abspath(__file__)), "docker-compose.yaml")
15
15
 
16
16
 
17
- def up() -> None:
18
- build()
17
+ def up(*services: str) -> None:
18
+ build(*services)
19
19
  print("starting the infra containers...")
20
- _exec_command(["up", "-d"])
20
+ _exec_command(["up", "-d", *services])
21
21
 
22
22
 
23
- def down(*_) -> None:
23
+ def down() -> None:
24
24
  _exec_command(["down"])
25
25
 
26
26
 
27
- def build() -> None:
27
+ def build(*services: str) -> None:
28
28
  print("building the grafana containers")
29
- _exec_command(["build"])
29
+ _exec_command(["build", *services])
30
+
31
+
32
+ def stop(container_name: str) -> None:
33
+ """
34
+ Stop the specified container if it is running.
35
+ Defaults to stopping the 'renderer' container.
36
+ """
37
+ print(f"stopping the {container_name} container...")
38
+ _exec_command(["stop", container_name])
30
39
 
31
40
 
32
41
  _P = ParamSpec("_P")
@@ -23,6 +23,11 @@ infra_parser = subparsers.add_parser(
23
23
  )
24
24
  infra_parser.add_argument("cmd", help="What do you want to do?")
25
25
  add_infra_port_args(infra_parser)
26
+ infra_parser.add_argument(
27
+ "--start-renderer",
28
+ action="store_true",
29
+ help="If set, starts the renderer container in addition to the default containers. By default, only grafana, victoria-metrics, and vmagent are started.",
30
+ )
26
31
 
27
32
  export_parser.add_argument(
28
33
  "--wallet",
@@ -87,7 +92,10 @@ def main():
87
92
  if command == "infra":
88
93
  if args.cmd == "start":
89
94
  # Start the backend containers
90
- docker.up()
95
+ if getattr(args, "start_renderer", False):
96
+ docker.up()
97
+ else:
98
+ docker.up("grafana", "victoria-metrics", "vmagent")
91
99
  elif args.cmd == "stop":
92
100
  docker.down()
93
101
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eth-portfolio-temp
3
- Version: 0.0.20.dev0
3
+ Version: 0.0.22.dev0
4
4
  Summary: eth-portfolio makes it easy to analyze your portfolio.
5
5
  Home-page: https://github.com/BobTheBuidler/eth-portfolio
6
6
  Author: BobTheBuidler
@@ -16,6 +16,7 @@ docs/conf.py
16
16
  docs/exporter.rst
17
17
  docs/index.rst
18
18
  docs/make.bat
19
+ docs/new-protocols.rst
19
20
  docs/_build/html/_static/alabaster.css
20
21
  docs/_build/html/_static/basic.css
21
22
  docs/_build/html/_static/custom.css
@@ -1,44 +0,0 @@
1
- Portfolio Exporter
2
- ==================
3
-
4
- Overview
5
- --------
6
- The Portfolio Exporter is a command-line tool provided by eth-portfolio. It is designed to extract and compile portfolio data – such as token balances, transaction history, and other relevant financial information – into exportable formats that can be further analyzed or integrated with external services.
7
-
8
- Requirements
9
- ------------
10
- - Python 3.10 or higher.
11
- - At least 16GB of RAM.
12
- - All dependencies installed as specified in the project’s ``requirements.txt`` file.
13
- - Proper configuration settings (e.g., API keys, network endpoints) must be set up as required by the portfolio and balance loaders. More info below.
14
-
15
- Usage
16
- -----
17
- The Portfolio Exporter should be used via the CLI. Include each of your wallets in the command like so:
18
-
19
- .. code-block:: bash
20
-
21
- eth-portfolio export --wallet 0x123 --wallet 0x234 --wallet 0x345
22
-
23
- Command-Line Options
24
- --------------------
25
- The Portfolio Exporter supports several command-line options to customize its behavior:
26
-
27
- - ``--wallet <address>``
28
- Specify a wallet to be included in your portfolio. You can pass this flag multiple times for multiple wallets.
29
-
30
- - ``--network <network-id>``
31
- The brownie network identifier for the rpc you wish to use. default: mainnet
32
-
33
- - ``--interval <interval>``
34
- The time interval between datapoints. default: 6h
35
-
36
- - ``--first-tx-block <block>``
37
- The block of your portfolio's first transaction, if known. This value, if provided, allows us to speed up processing of your data by limiting the block range we need to query. If not provided, the whole blockchain will be scanned. default: 0
38
-
39
- - ``--export-start-block <block>``
40
- The first block in the range you wish to export. default: 0
41
-
42
- Additional Information
43
- ----------------------
44
- TODO: add more details on the underlying data extraction process and portfolio calculations