eth-portfolio 0.5.6__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 might be problematic. Click here for more details.
- eth_portfolio-0.5.6/.env.sample +3 -0
- eth_portfolio-0.5.6/.github/workflows/compile.yaml +52 -0
- eth_portfolio-0.5.6/.github/workflows/deploy_docs.yaml +102 -0
- eth_portfolio-0.5.6/.github/workflows/lint.yaml +27 -0
- eth_portfolio-0.5.6/.github/workflows/mypy.yaml +37 -0
- eth_portfolio-0.5.6/.github/workflows/release.yaml +221 -0
- eth_portfolio-0.5.6/.gitignore +19 -0
- eth_portfolio-0.5.6/Makefile +11 -0
- eth_portfolio-0.5.6/PKG-INFO +26 -0
- eth_portfolio-0.5.6/README.md +138 -0
- eth_portfolio-0.5.6/brownie-config.yaml +1 -0
- eth_portfolio-0.5.6/docs/Makefile +20 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/alabaster.css +703 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/basic.css +921 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/custom.css +1 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/doctools.js +156 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/documentation_options.js +14 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/file.png +0 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/language_data.js +199 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/minus.png +0 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/plus.png +0 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/pygments.css +83 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/searchtools.js +566 -0
- eth_portfolio-0.5.6/docs/_build/html/_static/sphinx_highlight.js +144 -0
- eth_portfolio-0.5.6/docs/caching.rst +93 -0
- eth_portfolio-0.5.6/docs/conf.py +98 -0
- eth_portfolio-0.5.6/docs/exporter.rst +170 -0
- eth_portfolio-0.5.6/docs/index.rst +23 -0
- eth_portfolio-0.5.6/docs/make.bat +35 -0
- eth_portfolio-0.5.6/docs/new-protocols.rst +132 -0
- eth_portfolio-0.5.6/eth_portfolio/__init__.py +25 -0
- eth_portfolio-0.5.6/eth_portfolio/_argspec.py +43 -0
- eth_portfolio-0.5.6/eth_portfolio/_cache.py +120 -0
- eth_portfolio-0.5.6/eth_portfolio/_config.py +4 -0
- eth_portfolio-0.5.6/eth_portfolio/_db/__init__.py +0 -0
- eth_portfolio-0.5.6/eth_portfolio/_db/decorators.py +148 -0
- eth_portfolio-0.5.6/eth_portfolio/_db/entities.py +311 -0
- eth_portfolio-0.5.6/eth_portfolio/_db/utils.py +620 -0
- eth_portfolio-0.5.6/eth_portfolio/_decimal.py +155 -0
- eth_portfolio-0.5.6/eth_portfolio/_decorators.py +85 -0
- eth_portfolio-0.5.6/eth_portfolio/_exceptions.py +65 -0
- eth_portfolio-0.5.6/eth_portfolio/_ledgers/__init__.py +0 -0
- eth_portfolio-0.5.6/eth_portfolio/_ledgers/address.py +924 -0
- eth_portfolio-0.5.6/eth_portfolio/_ledgers/portfolio.py +328 -0
- eth_portfolio-0.5.6/eth_portfolio/_loaders/__init__.py +33 -0
- eth_portfolio-0.5.6/eth_portfolio/_loaders/_nonce.py +194 -0
- eth_portfolio-0.5.6/eth_portfolio/_loaders/balances.py +96 -0
- eth_portfolio-0.5.6/eth_portfolio/_loaders/token_transfer.py +216 -0
- eth_portfolio-0.5.6/eth_portfolio/_loaders/transaction.py +241 -0
- eth_portfolio-0.5.6/eth_portfolio/_loaders/utils.py +68 -0
- eth_portfolio-0.5.6/eth_portfolio/_shitcoins.py +342 -0
- eth_portfolio-0.5.6/eth_portfolio/_stableish.py +42 -0
- eth_portfolio-0.5.6/eth_portfolio/_submodules.py +73 -0
- eth_portfolio-0.5.6/eth_portfolio/_utils.py +220 -0
- eth_portfolio-0.5.6/eth_portfolio/_ydb/__init__.py +0 -0
- eth_portfolio-0.5.6/eth_portfolio/_ydb/token_transfers.py +146 -0
- eth_portfolio-0.5.6/eth_portfolio/address.py +397 -0
- eth_portfolio-0.5.6/eth_portfolio/buckets.py +212 -0
- eth_portfolio-0.5.6/eth_portfolio/constants.py +87 -0
- eth_portfolio-0.5.6/eth_portfolio/portfolio.py +662 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/__init__.py +65 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/_base.py +107 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/convex.py +17 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/dsr.py +51 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/lending/README.md +6 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/lending/__init__.py +50 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/lending/_base.py +56 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/lending/compound.py +186 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/lending/liquity.py +108 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/lending/maker.py +111 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/lending/unit.py +44 -0
- eth_portfolio-0.5.6/eth_portfolio/protocols/liquity.py +16 -0
- eth_portfolio-0.5.6/eth_portfolio/py.typed +0 -0
- eth_portfolio-0.5.6/eth_portfolio/structs/__init__.py +43 -0
- eth_portfolio-0.5.6/eth_portfolio/structs/modified.py +69 -0
- eth_portfolio-0.5.6/eth_portfolio/structs/structs.py +626 -0
- eth_portfolio-0.5.6/eth_portfolio/typing/__init__.py +1419 -0
- eth_portfolio-0.5.6/eth_portfolio/typing/balance/single.py +176 -0
- eth_portfolio-0.5.6/eth_portfolio.egg-info/PKG-INFO +26 -0
- eth_portfolio-0.5.6/eth_portfolio.egg-info/SOURCES.txt +112 -0
- eth_portfolio-0.5.6/eth_portfolio.egg-info/dependency_links.txt +1 -0
- eth_portfolio-0.5.6/eth_portfolio.egg-info/entry_points.txt +2 -0
- eth_portfolio-0.5.6/eth_portfolio.egg-info/not-zip-safe +1 -0
- eth_portfolio-0.5.6/eth_portfolio.egg-info/requires.txt +12 -0
- eth_portfolio-0.5.6/eth_portfolio.egg-info/top_level.txt +3 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/__init__.py +20 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/_args.py +26 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/_logging.py +15 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/_portfolio.py +210 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/_utils.py +107 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/balances.py +57 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/docker/.grafana/dashboards/Portfolio/Balances.json +1962 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/docker/.grafana/dashboards/dashboards.yaml +10 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/docker/.grafana/datasources/datasources.yml +11 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/docker/__init__.py +16 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/docker/check.py +66 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/docker/docker-compose.yaml +61 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/docker/docker_compose.py +98 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/main.py +119 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/py.typed +1 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/victoria/__init__.py +73 -0
- eth_portfolio-0.5.6/eth_portfolio_scripts/victoria/types.py +38 -0
- eth_portfolio-0.5.6/pyproject.toml +37 -0
- eth_portfolio-0.5.6/renovate.json +6 -0
- eth_portfolio-0.5.6/requirements.txt +12 -0
- eth_portfolio-0.5.6/setup.cfg +4 -0
- eth_portfolio-0.5.6/setup.py +134 -0
- eth_portfolio-0.5.6/tests/_test_completeness.py +45 -0
- eth_portfolio-0.5.6/tests/conftest.py +45 -0
- eth_portfolio-0.5.6/tests/fixtures.py +0 -0
- eth_portfolio-0.5.6/tests/protocols/test_external.py +120 -0
- eth_portfolio-0.5.6/tests/scripts/test_utils.py +163 -0
- eth_portfolio-0.5.6/tests/test_portfolio.py +0 -0
- eth_portfolio-0.5.6/tests/test_typing.py +635 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: Compile
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
paths-ignore:
|
|
8
|
+
- '.github/workflows/**'
|
|
9
|
+
- '!.github/workflows/compile.yaml'
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
13
|
+
cancel-in-progress: true
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
build-ubuntu:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout code
|
|
20
|
+
uses: actions/checkout@v6
|
|
21
|
+
with:
|
|
22
|
+
# Check out the PR branch
|
|
23
|
+
ref: ${{ github.head_ref }}
|
|
24
|
+
continue-on-error: true
|
|
25
|
+
|
|
26
|
+
- name: Branch no longer exists on GitHub
|
|
27
|
+
if: failure()
|
|
28
|
+
run: |
|
|
29
|
+
echo "The branch ${{ github.head_ref }} no longer exists on GitHub"
|
|
30
|
+
exit 0
|
|
31
|
+
|
|
32
|
+
- name: Set up Python 3.13
|
|
33
|
+
uses: actions/setup-python@v6
|
|
34
|
+
with:
|
|
35
|
+
python-version: "3.13"
|
|
36
|
+
|
|
37
|
+
- name: Mypycify
|
|
38
|
+
uses: BobTheBuidler/mypycify@v0.2.6
|
|
39
|
+
with:
|
|
40
|
+
python-version: "3.13"
|
|
41
|
+
hash-key: |
|
|
42
|
+
pyproject.toml
|
|
43
|
+
setup.py
|
|
44
|
+
eth_portfolio/**/*.py
|
|
45
|
+
pip-cache-dependency-path: |
|
|
46
|
+
pyproject.toml
|
|
47
|
+
requirements.txt
|
|
48
|
+
normalize-source: true
|
|
49
|
+
push-source: true
|
|
50
|
+
commit-message: "chore: compile C files for source control"
|
|
51
|
+
trigger-pr-number: ${{ github.event.pull_request.number }}
|
|
52
|
+
trigger-branch-name: ${{ github.head_ref || github.ref_name }}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
name: Deploy Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
|
|
8
|
+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
id-token: write
|
|
12
|
+
pages: write
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build-wheel:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout code
|
|
23
|
+
uses: actions/checkout@v6
|
|
24
|
+
with:
|
|
25
|
+
ref: ${{ github.head_ref }}
|
|
26
|
+
continue-on-error: true
|
|
27
|
+
|
|
28
|
+
- name: Branch no longer exists on GitHub
|
|
29
|
+
if: failure()
|
|
30
|
+
run: |
|
|
31
|
+
echo "The branch ${{ github.head_ref }} no longer exists on GitHub"
|
|
32
|
+
exit 0
|
|
33
|
+
|
|
34
|
+
- name: Set up Python
|
|
35
|
+
uses: actions/setup-python@v6
|
|
36
|
+
with:
|
|
37
|
+
python-version: '3.12'
|
|
38
|
+
|
|
39
|
+
- name: Mypycify
|
|
40
|
+
uses: BobTheBuidler/mypycify@v0.2.6
|
|
41
|
+
with:
|
|
42
|
+
python-version: "3.12"
|
|
43
|
+
hash-key: |
|
|
44
|
+
pyproject.toml
|
|
45
|
+
setup.py
|
|
46
|
+
eth_portfolio/**/*.py
|
|
47
|
+
pip-cache-dependency-path: |
|
|
48
|
+
pyproject.toml
|
|
49
|
+
requirements.txt
|
|
50
|
+
|
|
51
|
+
build-and-deploy:
|
|
52
|
+
needs: build-wheel
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
steps:
|
|
55
|
+
- name: Check out code
|
|
56
|
+
uses: actions/checkout@v6
|
|
57
|
+
|
|
58
|
+
- name: Set up Python
|
|
59
|
+
uses: actions/setup-python@v6
|
|
60
|
+
with:
|
|
61
|
+
python-version: '3.12'
|
|
62
|
+
|
|
63
|
+
- name: Download wheel artifact
|
|
64
|
+
uses: actions/download-artifact@v7
|
|
65
|
+
with:
|
|
66
|
+
name: BobTheBuidler_mypycified_wheel-${{ runner.os }}-py3.12-source-${{ hashFiles('pyproject.toml', 'setup.py', 'eth_portfolio/**/*.py') }}-source
|
|
67
|
+
|
|
68
|
+
- name: Install dependencies
|
|
69
|
+
run: pip install $(find . -name '*.whl') sphinx sphinx-rtd-theme
|
|
70
|
+
|
|
71
|
+
- name: Build documentation config
|
|
72
|
+
run: make docs
|
|
73
|
+
|
|
74
|
+
- name: Build documentation
|
|
75
|
+
run: |
|
|
76
|
+
cd docs
|
|
77
|
+
BROWNIE_NETWORK_ID=mainnet ETHERSCAN_TOKEN=${{ secrets.ETHERSCAN_TOKEN }} make html
|
|
78
|
+
continue-on-error: true
|
|
79
|
+
|
|
80
|
+
- name: Deploy to GitHub Pages
|
|
81
|
+
uses: peaceiris/actions-gh-pages@v4
|
|
82
|
+
with:
|
|
83
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
84
|
+
publish_dir: ./docs/_build/html
|
|
85
|
+
|
|
86
|
+
- name: Checkout
|
|
87
|
+
uses: actions/checkout@v6
|
|
88
|
+
with:
|
|
89
|
+
ref: gh-pages
|
|
90
|
+
|
|
91
|
+
- name: Setup Pages
|
|
92
|
+
uses: actions/configure-pages@v5
|
|
93
|
+
|
|
94
|
+
- name: Upload artifact
|
|
95
|
+
uses: actions/upload-pages-artifact@v4
|
|
96
|
+
with:
|
|
97
|
+
# Upload entire repository
|
|
98
|
+
path: '.'
|
|
99
|
+
|
|
100
|
+
- name: Deploy to GitHub Pages
|
|
101
|
+
id: deployment
|
|
102
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Lint All The Things
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
paths-ignore:
|
|
8
|
+
- '.github/workflows/**'
|
|
9
|
+
- '!.github/workflows/lint.yaml'
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
13
|
+
cancel-in-progress: true
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
lint-all-the-things:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout code
|
|
20
|
+
uses: actions/checkout@v6
|
|
21
|
+
with:
|
|
22
|
+
ref: ${{ github.head_ref }}
|
|
23
|
+
- name: Lint All The Things
|
|
24
|
+
uses: BobTheBuidler/lint-all-the-things@v0.0.3
|
|
25
|
+
with:
|
|
26
|
+
python-version: 3.14
|
|
27
|
+
pyupgrade-target-version: py310
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: MyPy
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
paths:
|
|
6
|
+
- '**.py'
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
mypy:
|
|
14
|
+
runs-on: ${{ matrix.os }}
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
os: [ ubuntu-latest, macos-latest, windows-latest ]
|
|
19
|
+
pyversion: [ "3.10", "3.11", "3.12" ]
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout
|
|
23
|
+
uses: actions/checkout@v6
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
persist-credentials: false
|
|
27
|
+
|
|
28
|
+
- name: Setup Python (faster than using Python container)
|
|
29
|
+
uses: actions/setup-python@v6
|
|
30
|
+
with:
|
|
31
|
+
python-version: ${{ matrix.pyversion }}
|
|
32
|
+
|
|
33
|
+
- name: Install Dependencies
|
|
34
|
+
run: pip install -r requirements.txt
|
|
35
|
+
|
|
36
|
+
- name: Run MyPy
|
|
37
|
+
run: make mypy
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
name: Build and Publish Wheels
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
types: [published]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
inputs:
|
|
10
|
+
fake_tag:
|
|
11
|
+
description: 'Fake tag name to use for dry run (e.g. v2.3.4)'
|
|
12
|
+
required: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build_wheels:
|
|
16
|
+
name: Build wheels using cibuildwheel
|
|
17
|
+
runs-on: ${{ matrix.os }}
|
|
18
|
+
strategy:
|
|
19
|
+
fail-fast: false
|
|
20
|
+
matrix:
|
|
21
|
+
include:
|
|
22
|
+
# ----------------------------------------------------
|
|
23
|
+
# manylinux 64-bit
|
|
24
|
+
# ----------------------------------------------------
|
|
25
|
+
- os: ubuntu-latest
|
|
26
|
+
build_type: manylinux-x64
|
|
27
|
+
cibw_build: "*manylinux*"
|
|
28
|
+
cibw_archs_linux: x86_64
|
|
29
|
+
artifact_name: "wheels-ubuntu-latest-manylinux-x64"
|
|
30
|
+
|
|
31
|
+
# ----------------------------------------------------
|
|
32
|
+
# manylinux 32-bit
|
|
33
|
+
# ----------------------------------------------------
|
|
34
|
+
- os: ubuntu-latest
|
|
35
|
+
build_type: manylinux-x86
|
|
36
|
+
cibw_build: "*manylinux*"
|
|
37
|
+
cibw_archs_linux: i686
|
|
38
|
+
artifact_name: "wheels-ubuntu-latest-manylinux-x86"
|
|
39
|
+
|
|
40
|
+
# ----------------------------------------------------
|
|
41
|
+
# musllinux 64-bit
|
|
42
|
+
# ----------------------------------------------------
|
|
43
|
+
- os: ubuntu-latest
|
|
44
|
+
build_type: musllinux-x64
|
|
45
|
+
cibw_build: "*musllinux*"
|
|
46
|
+
cibw_archs_linux: x86_64
|
|
47
|
+
artifact_name: "wheels-ubuntu-latest-musllinux-x64"
|
|
48
|
+
|
|
49
|
+
# ----------------------------------------------------
|
|
50
|
+
# macOS (64-bit only)
|
|
51
|
+
# ----------------------------------------------------
|
|
52
|
+
- os: macos-latest
|
|
53
|
+
build_type: macos
|
|
54
|
+
cibw_build: ""
|
|
55
|
+
cibw_archs_linux: ""
|
|
56
|
+
artifact_name: "wheels-macos-latest"
|
|
57
|
+
|
|
58
|
+
# ----------------------------------------------------
|
|
59
|
+
# Windows 64-bit
|
|
60
|
+
# ----------------------------------------------------
|
|
61
|
+
- os: windows-latest
|
|
62
|
+
build_type: winx64
|
|
63
|
+
cibw_build: ""
|
|
64
|
+
cibw_archs_windows: AMD64
|
|
65
|
+
artifact_name: "wheels-windows-latest-x64"
|
|
66
|
+
|
|
67
|
+
# ----------------------------------------------------
|
|
68
|
+
# Windows 32-bit
|
|
69
|
+
# ----------------------------------------------------
|
|
70
|
+
- os: windows-latest
|
|
71
|
+
build_type: winx86
|
|
72
|
+
cibw_build: ""
|
|
73
|
+
cibw_archs_windows: x86
|
|
74
|
+
artifact_name: "wheels-windows-latest-x86"
|
|
75
|
+
|
|
76
|
+
steps:
|
|
77
|
+
- name: Check out code
|
|
78
|
+
uses: actions/checkout@v6
|
|
79
|
+
with:
|
|
80
|
+
fetch-depth: 0
|
|
81
|
+
|
|
82
|
+
# ----------------------------------------------------
|
|
83
|
+
# Extract version from git tag or use fake tag for dry run (strip leading 'v')
|
|
84
|
+
# ----------------------------------------------------
|
|
85
|
+
- name: Extract version from tag
|
|
86
|
+
id: get_version
|
|
87
|
+
shell: bash
|
|
88
|
+
run: |
|
|
89
|
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
90
|
+
echo "version=$(echo '${{ github.event.inputs.fake_tag }}' | sed 's/^v//')" >> $GITHUB_OUTPUT
|
|
91
|
+
else
|
|
92
|
+
echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
- name: Set up Python
|
|
96
|
+
uses: actions/setup-python@v6
|
|
97
|
+
with:
|
|
98
|
+
python-version: "3.13"
|
|
99
|
+
|
|
100
|
+
- name: Install cibuildwheel
|
|
101
|
+
run: |
|
|
102
|
+
python -m pip install --upgrade pip setuptools wheel cibuildwheel mypy[mypyc]
|
|
103
|
+
|
|
104
|
+
- name: Build wheels
|
|
105
|
+
env:
|
|
106
|
+
# Skip PyPy
|
|
107
|
+
CIBW_SKIP: pp*
|
|
108
|
+
# On Linux: manylinux / musllinux arches
|
|
109
|
+
CIBW_ARCHS_LINUX: ${{ matrix.cibw_archs_linux || '' }}
|
|
110
|
+
# On Windows: AMD64 / x86
|
|
111
|
+
CIBW_ARCHS_WINDOWS: ${{ matrix.cibw_archs_windows || '' }}
|
|
112
|
+
# Which wheels to build for Linux (manylinux vs. musllinux)
|
|
113
|
+
CIBW_BUILD: ${{ matrix.cibw_build || '' }}
|
|
114
|
+
# Use version from git tag (stripped 'v')
|
|
115
|
+
SETUPTOOLS_SCM_PRETEND_VERSION: ${{ steps.get_version.outputs.version }}
|
|
116
|
+
# Pass version into Docker for Linux builds
|
|
117
|
+
CIBW_ENVIRONMENT: "SETUPTOOLS_SCM_PRETEND_VERSION=${{ steps.get_version.outputs.version }}"
|
|
118
|
+
run: |
|
|
119
|
+
python -m cibuildwheel --output-dir wheelhouse
|
|
120
|
+
|
|
121
|
+
- name: Upload wheels
|
|
122
|
+
uses: actions/upload-artifact@v6
|
|
123
|
+
with:
|
|
124
|
+
name: ${{ matrix.artifact_name }}
|
|
125
|
+
path: wheelhouse/*.whl
|
|
126
|
+
|
|
127
|
+
publish_sdist_and_wheels:
|
|
128
|
+
name: Publish wheels to PyPI
|
|
129
|
+
needs: build_wheels
|
|
130
|
+
runs-on: ubuntu-latest
|
|
131
|
+
steps:
|
|
132
|
+
- name: Check out code
|
|
133
|
+
uses: actions/checkout@v6
|
|
134
|
+
with:
|
|
135
|
+
fetch-depth: 0
|
|
136
|
+
|
|
137
|
+
# ----------------------------------------------------
|
|
138
|
+
# Extract version from git tag or use fake tag for dry run (strip leading 'v')
|
|
139
|
+
# ----------------------------------------------------
|
|
140
|
+
- name: Extract version from tag
|
|
141
|
+
id: get_version
|
|
142
|
+
shell: bash
|
|
143
|
+
run: |
|
|
144
|
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
145
|
+
echo "version=$(echo '${{ github.event.inputs.fake_tag }}' | sed 's/^v//')" >> $GITHUB_OUTPUT
|
|
146
|
+
else
|
|
147
|
+
echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
- name: Set up Python
|
|
151
|
+
uses: actions/setup-python@v6
|
|
152
|
+
with:
|
|
153
|
+
python-version: "3.13"
|
|
154
|
+
|
|
155
|
+
- name: Install dependencies
|
|
156
|
+
run: |
|
|
157
|
+
python -m pip install --upgrade pip
|
|
158
|
+
pip install setuptools wheel twine mypy[mypyc] types-aiofiles
|
|
159
|
+
|
|
160
|
+
- name: Build sdist
|
|
161
|
+
env:
|
|
162
|
+
# Use version from git tag (stripped 'v')
|
|
163
|
+
SETUPTOOLS_SCM_PRETEND_VERSION: ${{ steps.get_version.outputs.version }}
|
|
164
|
+
run: python setup.py sdist
|
|
165
|
+
|
|
166
|
+
# ----------------------------------------------------
|
|
167
|
+
# Download wheels built on each runner
|
|
168
|
+
# ----------------------------------------------------
|
|
169
|
+
- name: Download manylinux 64-bit wheels
|
|
170
|
+
uses: actions/download-artifact@v7
|
|
171
|
+
with:
|
|
172
|
+
name: "wheels-ubuntu-latest-manylinux-x64"
|
|
173
|
+
path: wheelhouse/linux-many-x64
|
|
174
|
+
|
|
175
|
+
- name: Download manylinux 32-bit wheels
|
|
176
|
+
uses: actions/download-artifact@v7
|
|
177
|
+
with:
|
|
178
|
+
name: "wheels-ubuntu-latest-manylinux-x86"
|
|
179
|
+
path: wheelhouse/linux-many-x86
|
|
180
|
+
|
|
181
|
+
- name: Download musllinux 64-bit wheels
|
|
182
|
+
uses: actions/download-artifact@v7
|
|
183
|
+
with:
|
|
184
|
+
name: "wheels-ubuntu-latest-musllinux-x64"
|
|
185
|
+
path: wheelhouse/linux-musl-x64
|
|
186
|
+
|
|
187
|
+
- name: Download macOS wheels
|
|
188
|
+
uses: actions/download-artifact@v7
|
|
189
|
+
with:
|
|
190
|
+
name: "wheels-macos-latest"
|
|
191
|
+
path: wheelhouse/macos
|
|
192
|
+
|
|
193
|
+
- name: Download Windows 64-bit wheels
|
|
194
|
+
uses: actions/download-artifact@v7
|
|
195
|
+
with:
|
|
196
|
+
name: "wheels-windows-latest-x64"
|
|
197
|
+
path: wheelhouse/windows-x64
|
|
198
|
+
|
|
199
|
+
- name: Download Windows 32-bit wheels
|
|
200
|
+
uses: actions/download-artifact@v7
|
|
201
|
+
with:
|
|
202
|
+
name: "wheels-windows-latest-x86"
|
|
203
|
+
path: wheelhouse/windows-x86
|
|
204
|
+
|
|
205
|
+
# ----------------------------------------------------
|
|
206
|
+
# Publish sdist and wheels to PyPI
|
|
207
|
+
# ----------------------------------------------------
|
|
208
|
+
- name: Publish sdist and wheels to PyPI
|
|
209
|
+
if: ${{ github.event_name != 'workflow_dispatch' }}
|
|
210
|
+
env:
|
|
211
|
+
TWINE_USERNAME: __token__
|
|
212
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
|
213
|
+
run: |
|
|
214
|
+
twine upload \
|
|
215
|
+
dist/* \
|
|
216
|
+
wheelhouse/linux-many-x64/*.whl \
|
|
217
|
+
wheelhouse/linux-many-x86/*.whl \
|
|
218
|
+
wheelhouse/linux-musl-x64/*.whl \
|
|
219
|
+
wheelhouse/macos/*.whl \
|
|
220
|
+
wheelhouse/windows-x64/*.whl \
|
|
221
|
+
wheelhouse/windows-x86/*.whl
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
cache/
|
|
2
|
+
env/
|
|
3
|
+
.env
|
|
4
|
+
.mypy_cache/
|
|
5
|
+
.hypothesis
|
|
6
|
+
.pytest_cache
|
|
7
|
+
__pycache__/
|
|
8
|
+
eth_portfolio.egg-info/
|
|
9
|
+
build/**/*.py
|
|
10
|
+
build/**/*.json
|
|
11
|
+
build/**/*.md
|
|
12
|
+
build/**/*.typed
|
|
13
|
+
build/**/*.yaml
|
|
14
|
+
build/**/*.yml
|
|
15
|
+
build/ops.txt
|
|
16
|
+
**.o
|
|
17
|
+
**.so
|
|
18
|
+
**.whl
|
|
19
|
+
eth_portfolio_temp.egg-info/
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
.PHONY: docs
|
|
3
|
+
|
|
4
|
+
docs:
|
|
5
|
+
rm -r ./docs/source -f
|
|
6
|
+
rm -r ./docs/_templates -f
|
|
7
|
+
rm -r ./docs/_build -f
|
|
8
|
+
sphinx-apidoc -o ./docs/source ./eth_portfolio
|
|
9
|
+
|
|
10
|
+
test-exporter:
|
|
11
|
+
eth-portfolio export balances --wallet 0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52 --network tenderly
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eth_portfolio
|
|
3
|
+
Version: 0.5.6
|
|
4
|
+
Summary: eth-portfolio makes it easy to analyze your portfolio.
|
|
5
|
+
Home-page: https://github.com/BobTheBuidler/eth-portfolio
|
|
6
|
+
Author: BobTheBuidler
|
|
7
|
+
Author-email: bobthebuidlerdefi@gmail.com
|
|
8
|
+
Requires-Python: >=3.10,<3.14
|
|
9
|
+
Requires-Dist: checksum_dict>=2.1.7
|
|
10
|
+
Requires-Dist: dank_mids>=4.20.192
|
|
11
|
+
Requires-Dist: eth-brownie<1.23,>=1.22.0.dev0
|
|
12
|
+
Requires-Dist: eth_retry<1,>=0.3.4
|
|
13
|
+
Requires-Dist: evmspec>=0.4.1
|
|
14
|
+
Requires-Dist: ez-a-sync>=0.33.10
|
|
15
|
+
Requires-Dist: faster-async-lru==2.0.5.2
|
|
16
|
+
Requires-Dist: faster-eth-utils
|
|
17
|
+
Requires-Dist: numpy<3
|
|
18
|
+
Requires-Dist: pandas<3,>=1.4.3
|
|
19
|
+
Requires-Dist: typed-envs>=0.2.3
|
|
20
|
+
Requires-Dist: ypricemagic<5.2,>=5.1.3
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: author-email
|
|
23
|
+
Dynamic: home-page
|
|
24
|
+
Dynamic: requires-dist
|
|
25
|
+
Dynamic: requires-python
|
|
26
|
+
Dynamic: summary
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# eth-portfolio
|
|
2
|
+
Use `eth-portfolio` to output information about your portfolio in a streamlined, speed-optimized way.
|
|
3
|
+
|
|
4
|
+
### Requirements
|
|
5
|
+
- Python 3.10 or higher.
|
|
6
|
+
- At least 16GB of RAM, 32GB for Base chain.
|
|
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
|
+
|
|
13
|
+
### Installation:
|
|
14
|
+
- Make sure you are using Python >= 3.9 and < 3.13. You should start with a fresh virtual environment, and then just...
|
|
15
|
+
```
|
|
16
|
+
pip install git+https://github.com/BobTheBuidler/eth-portfolio
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Usage:
|
|
20
|
+
For basic use, input each of your addresses as environment variables using the following pattern:
|
|
21
|
+
```
|
|
22
|
+
PORTFOLIO_ADDRESS_0=0x123...
|
|
23
|
+
PORTFOLIO_ADDRESS_1=0x234...
|
|
24
|
+
PORTFOLIO_ADDRESS_2=0x345...
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Then do...
|
|
28
|
+
```
|
|
29
|
+
from eth_portfolio import portfolio
|
|
30
|
+
portfolio.eth_balance(block)
|
|
31
|
+
|
|
32
|
+
>>> {
|
|
33
|
+
0xaddress0: _BalanceItem(balance=1234, usd_value=5678)
|
|
34
|
+
0xaddress1: _BalanceItem(balance=1234, usd_value=5678)
|
|
35
|
+
0xaddress2: _BalanceItem(balance=1234, usd_value=5678)
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Getting token transfers:
|
|
40
|
+
```
|
|
41
|
+
from eth_portfolio import portfolio
|
|
42
|
+
token_transfers = portfolio.token_transfers.get(start_block, end_block)
|
|
43
|
+
token_transfers.df()
|
|
44
|
+
|
|
45
|
+
>>> {
|
|
46
|
+
0xaddress0: AddressTokenTransfersLedger(...) # Each of these contains the token transfers for the specified address
|
|
47
|
+
0xaddress1: AddressTokenTransfersLedger(...)
|
|
48
|
+
0xaddress2: AddressTokenTransfersLedger(...)
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Getting transactions as a DataFrame:
|
|
53
|
+
```
|
|
54
|
+
from eth_portfolio import portfolio
|
|
55
|
+
txs = portfolio.transactions.get(start_block, end_block)
|
|
56
|
+
txs.df()
|
|
57
|
+
|
|
58
|
+
>>> [I am a pretend DataFrame]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Getting assets:
|
|
62
|
+
```
|
|
63
|
+
from eth_portfolio import portfolio
|
|
64
|
+
portfolio.describe(start_block, end_block)
|
|
65
|
+
|
|
66
|
+
>>> {
|
|
67
|
+
'assets': {
|
|
68
|
+
'wallet0_address': {
|
|
69
|
+
'token0': {
|
|
70
|
+
'amount': 123,
|
|
71
|
+
'value usd: 456,
|
|
72
|
+
},
|
|
73
|
+
'token1': {
|
|
74
|
+
'amount': 123,
|
|
75
|
+
'value usd: 456,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
'wallet0_address': {
|
|
79
|
+
'token0': {
|
|
80
|
+
'amount': 123,
|
|
81
|
+
'value usd: 456,
|
|
82
|
+
},
|
|
83
|
+
'token1': {
|
|
84
|
+
'amount': 123,
|
|
85
|
+
'value usd: 456,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
'debt': {
|
|
90
|
+
'wallet0_address': {
|
|
91
|
+
'token0': {
|
|
92
|
+
'amount': 123,
|
|
93
|
+
'value usd: 456,
|
|
94
|
+
},
|
|
95
|
+
'token1': {
|
|
96
|
+
'amount': 123,
|
|
97
|
+
'value usd: 456,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
'wallet1_address': {
|
|
101
|
+
'token0': {
|
|
102
|
+
'amount': 123,
|
|
103
|
+
'value usd: 456,
|
|
104
|
+
},
|
|
105
|
+
'token1': {
|
|
106
|
+
'amount': 123,
|
|
107
|
+
'value usd: 456,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Getting net worth:
|
|
115
|
+
```
|
|
116
|
+
from eth_portfolio import portfolio
|
|
117
|
+
desc = portfolio.describe(block)
|
|
118
|
+
assets = desc['assets'] # OR you can do `assets = portfolio.assets(block)`
|
|
119
|
+
debt = desc['debt'] # OR you can do `debt = portfolio.debt(block)`
|
|
120
|
+
assets = sum(assets.values())
|
|
121
|
+
debt = sum(debt.values())
|
|
122
|
+
net = assets - debt
|
|
123
|
+
net.sum_usd()
|
|
124
|
+
|
|
125
|
+
>>> Decimal("123456.78900")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Advanced:
|
|
129
|
+
You also have more granular control available using the Portfolio object:
|
|
130
|
+
```
|
|
131
|
+
from eth_portfolio import Portfolio
|
|
132
|
+
port = Portfolio([0xaddress0, 0xaddress1, 0xaddress2])
|
|
133
|
+
port.describe(chain.height)
|
|
134
|
+
|
|
135
|
+
# Or for async code
|
|
136
|
+
async_port = Portfolio([0xaddress0, 0xaddress1, 0xaddress2], asynchronous=True)
|
|
137
|
+
await port.describe(chain.height)
|
|
138
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
autofetch_sources: true
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Minimal makefile for Sphinx documentation
|
|
2
|
+
#
|
|
3
|
+
|
|
4
|
+
# You can set these variables from the command line, and also
|
|
5
|
+
# from the environment for the first two.
|
|
6
|
+
SPHINXOPTS ?=
|
|
7
|
+
SPHINXBUILD ?= sphinx-build
|
|
8
|
+
SOURCEDIR = .
|
|
9
|
+
BUILDDIR = _build
|
|
10
|
+
|
|
11
|
+
# Put it first so that "make" without argument is like "make help".
|
|
12
|
+
help:
|
|
13
|
+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
14
|
+
|
|
15
|
+
.PHONY: help Makefile
|
|
16
|
+
|
|
17
|
+
# Catch-all target: route all unknown targets to Sphinx using the new
|
|
18
|
+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
|
19
|
+
%: Makefile
|
|
20
|
+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|