dao-treasury 0.0.60__cp312-cp312-win32.whl → 0.1.6__cp312-cp312-win32.whl
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 dao-treasury might be problematic. Click here for more details.
- dao_treasury/.grafana/provisioning/dashboards/breakdowns/Expenses.json +195 -154
- dao_treasury/.grafana/provisioning/dashboards/breakdowns/Revenue.json +192 -149
- dao_treasury/.grafana/provisioning/dashboards/dashboards.yaml +7 -81
- dao_treasury/.grafana/provisioning/dashboards/streams/LlamaPay.json +10 -22
- dao_treasury/.grafana/provisioning/dashboards/summary/Monthly.json +283 -23
- dao_treasury/.grafana/provisioning/dashboards/transactions/Treasury Transactions.json +49 -39
- dao_treasury/.grafana/provisioning/dashboards/transactions/Unsorted Transactions.json +367 -0
- dao_treasury/.grafana/provisioning/dashboards/treasury/Cashflow (Including Unsorted).json +109 -187
- dao_treasury/.grafana/provisioning/dashboards/treasury/Cashflow.json +77 -127
- dao_treasury/.grafana/provisioning/dashboards/treasury/Current Treasury Assets.json +509 -105
- dao_treasury/.grafana/provisioning/dashboards/treasury/Historical Treasury Balances.json +3856 -2924
- dao_treasury/.grafana/provisioning/dashboards/treasury/Operating Cashflow.json +57 -97
- dao_treasury/.grafana/provisioning/datasources/datasources.yaml +9 -4
- dao_treasury/__init__.py +0 -4
- dao_treasury/_docker.cp312-win32.pyd +0 -0
- dao_treasury/_docker.py +30 -22
- dao_treasury/_nicknames.cp312-win32.pyd +0 -0
- dao_treasury/_nicknames.py +3 -2
- dao_treasury/_wallet.cp312-win32.pyd +0 -0
- dao_treasury/constants.cp312-win32.pyd +0 -0
- dao_treasury/db.py +383 -131
- dao_treasury/docker-compose.yaml +19 -3
- dao_treasury/main.py +42 -4
- dao_treasury/sorting/__init__.cp312-win32.pyd +0 -0
- dao_treasury/sorting/__init__.py +38 -21
- dao_treasury/sorting/_matchers.cp312-win32.pyd +0 -0
- dao_treasury/sorting/_rules.cp312-win32.pyd +0 -0
- dao_treasury/sorting/factory.cp312-win32.pyd +0 -0
- dao_treasury/sorting/rule.cp312-win32.pyd +0 -0
- dao_treasury/sorting/rules/__init__.cp312-win32.pyd +0 -0
- dao_treasury/sorting/rules/ignore/__init__.cp312-win32.pyd +0 -0
- dao_treasury/sorting/rules/ignore/llamapay.cp312-win32.pyd +0 -0
- dao_treasury/treasury.py +4 -2
- dao_treasury/types.cp312-win32.pyd +0 -0
- {dao_treasury-0.0.60.dist-info → dao_treasury-0.1.6.dist-info}/METADATA +18 -4
- dao_treasury-0.1.6.dist-info/RECORD +53 -0
- dao_treasury__mypyc.cp312-win32.pyd +0 -0
- dao_treasury/streams/__init__.cp312-win32.pyd +0 -0
- dao_treasury/streams/llamapay.cp312-win32.pyd +0 -0
- dao_treasury-0.0.60.dist-info/RECORD +0 -54
- {dao_treasury-0.0.60.dist-info → dao_treasury-0.1.6.dist-info}/WHEEL +0 -0
- {dao_treasury-0.0.60.dist-info → dao_treasury-0.1.6.dist-info}/top_level.txt +0 -0
dao_treasury/docker-compose.yaml
CHANGED
|
@@ -3,9 +3,12 @@ networks:
|
|
|
3
3
|
docker_eth_portfolio:
|
|
4
4
|
external: true
|
|
5
5
|
|
|
6
|
+
volumes:
|
|
7
|
+
dao_treasury_pgdata:
|
|
8
|
+
|
|
6
9
|
services:
|
|
7
10
|
grafana:
|
|
8
|
-
image: grafana/grafana:12.
|
|
11
|
+
image: grafana/grafana:12.3.0
|
|
9
12
|
ports:
|
|
10
13
|
- 127.0.0.1:${DAO_TREASURY_GRAFANA_PORT:-3004}:3000
|
|
11
14
|
environment:
|
|
@@ -18,9 +21,8 @@ services:
|
|
|
18
21
|
- GF_RENDERING_SERVER_URL=http://renderer:8091/render
|
|
19
22
|
- GF_RENDERING_CALLBACK_URL=http://grafana:3000/
|
|
20
23
|
- GF_LOG_FILTERS=rendering:debug
|
|
21
|
-
- GF_INSTALL_PLUGINS=volkovlabs-variable-panel
|
|
24
|
+
- GF_INSTALL_PLUGINS=volkovlabs-variable-panel
|
|
22
25
|
volumes:
|
|
23
|
-
- ~/.dao-treasury/:/app/dao-treasury-data
|
|
24
26
|
- ./.grafana/provisioning/:/etc/grafana/provisioning/
|
|
25
27
|
networks:
|
|
26
28
|
- dao_treasury
|
|
@@ -39,3 +41,17 @@ services:
|
|
|
39
41
|
- dao_treasury
|
|
40
42
|
- docker_eth_portfolio
|
|
41
43
|
restart: always
|
|
44
|
+
|
|
45
|
+
postgres:
|
|
46
|
+
image: postgres:18
|
|
47
|
+
restart: always
|
|
48
|
+
environment:
|
|
49
|
+
POSTGRES_USER: dao_treasury
|
|
50
|
+
POSTGRES_PASSWORD: dao_treasury
|
|
51
|
+
POSTGRES_DB: dao_treasury
|
|
52
|
+
volumes:
|
|
53
|
+
- dao_treasury_pgdata:/var/lib/postgresql
|
|
54
|
+
ports:
|
|
55
|
+
- 127.0.0.1:${DAO_TREASURY_POSTGRES_PORT:-8675}:5432
|
|
56
|
+
networks:
|
|
57
|
+
- dao_treasury
|
dao_treasury/main.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This module parses command-line arguments, sets up environment variables for
|
|
4
4
|
Grafana and its renderer, and defines the entrypoint for a one-time export of
|
|
5
|
-
DAO treasury transactions. It populates the local
|
|
5
|
+
DAO treasury transactions. It populates the local PostgreSQL database and starts
|
|
6
6
|
the required Docker services for Grafana dashboards. Transactions are fetched
|
|
7
7
|
via :class:`dao_treasury.Treasury`, sorted according to optional rules, and
|
|
8
8
|
inserted using the database routines (:func:`dao_treasury.db.TreasuryTx.insert`).
|
|
@@ -29,6 +29,7 @@ from pathlib import Path
|
|
|
29
29
|
import brownie
|
|
30
30
|
import yaml
|
|
31
31
|
from a_sync import create_task
|
|
32
|
+
from dao_treasury._nicknames import setup_address_nicknames_in_db
|
|
32
33
|
from dao_treasury._wallet import load_wallets_from_yaml
|
|
33
34
|
from eth_portfolio_scripts.balances import export_balances
|
|
34
35
|
from eth_typing import BlockNumber
|
|
@@ -125,6 +126,18 @@ parser.add_argument(
|
|
|
125
126
|
help="Port for the Grafana rendering service. Default: 8091",
|
|
126
127
|
default=8091,
|
|
127
128
|
)
|
|
129
|
+
parser.add_argument(
|
|
130
|
+
"--custom-bucket",
|
|
131
|
+
type=str,
|
|
132
|
+
action="append",
|
|
133
|
+
help=(
|
|
134
|
+
"Custom bucket mapping for a wallet address. "
|
|
135
|
+
"Specify as 'address:bucket_name'. "
|
|
136
|
+
"Can be used multiple times. Example: "
|
|
137
|
+
"--custom-bucket '0x123:My Bucket' --custom-bucket '0x456:Other Bucket'"
|
|
138
|
+
),
|
|
139
|
+
default=None,
|
|
140
|
+
)
|
|
128
141
|
|
|
129
142
|
args = parser.parse_args()
|
|
130
143
|
|
|
@@ -209,13 +222,36 @@ async def export(args) -> None:
|
|
|
209
222
|
for address in addresses:
|
|
210
223
|
db.Address.set_nickname(address, nickname)
|
|
211
224
|
|
|
212
|
-
|
|
225
|
+
# Parse custom_buckets from --custom-bucket arguments
|
|
226
|
+
custom_buckets = None
|
|
227
|
+
if args.custom_bucket:
|
|
228
|
+
custom_buckets = {}
|
|
229
|
+
item: str
|
|
230
|
+
for item in args.custom_bucket:
|
|
231
|
+
if ":" not in item:
|
|
232
|
+
parser.error(
|
|
233
|
+
f"Invalid format for --custom-bucket: '{item}'. Must be 'address:bucket_name'."
|
|
234
|
+
)
|
|
235
|
+
address, bucket = item.split(":", 1)
|
|
236
|
+
address = address.strip()
|
|
237
|
+
bucket = bucket.strip()
|
|
238
|
+
if not address or not bucket:
|
|
239
|
+
parser.error(
|
|
240
|
+
f"Invalid format for --custom-bucket: '{item}'. Both address and bucket_name are required."
|
|
241
|
+
)
|
|
242
|
+
custom_buckets[address] = bucket
|
|
243
|
+
|
|
244
|
+
treasury = Treasury(
|
|
245
|
+
wallets, args.sort_rules, custom_buckets=custom_buckets, asynchronous=True
|
|
246
|
+
)
|
|
213
247
|
|
|
214
248
|
# Start only the requested containers
|
|
215
249
|
if args.start_renderer is True:
|
|
216
250
|
_docker.up()
|
|
217
251
|
else:
|
|
218
|
-
_docker.up("grafana")
|
|
252
|
+
_docker.up("grafana", "postgres")
|
|
253
|
+
|
|
254
|
+
setup_address_nicknames_in_db()
|
|
219
255
|
|
|
220
256
|
# eth-portfolio needs this present
|
|
221
257
|
# TODO: we need to update eth-portfolio to honor wallet join and exit times
|
|
@@ -231,7 +267,9 @@ async def export(args) -> None:
|
|
|
231
267
|
|
|
232
268
|
export_task = create_task(
|
|
233
269
|
asyncio.gather(
|
|
234
|
-
|
|
270
|
+
# TODO: combine these into Treasury class?
|
|
271
|
+
# would allow for only one set of logs in memory
|
|
272
|
+
export_balances(args, custom_buckets),
|
|
235
273
|
treasury.populate_db(BlockNumber(0), brownie.chain.height),
|
|
236
274
|
)
|
|
237
275
|
)
|
|
Binary file
|
dao_treasury/sorting/__init__.py
CHANGED
|
@@ -88,13 +88,8 @@ __all__ = [
|
|
|
88
88
|
|
|
89
89
|
# C constants
|
|
90
90
|
TxGroup: Final = db.TxGroup
|
|
91
|
-
MUST_SORT_INBOUND_TXGROUP_DBID: Final = db.must_sort_inbound_txgroup_dbid
|
|
92
|
-
MUST_SORT_OUTBOUND_TXGROUP_DBID: Final = db.must_sort_outbound_txgroup_dbid
|
|
93
91
|
|
|
94
|
-
INTERNAL_TRANSFER_TXGROUP_DBID:
|
|
95
|
-
name="Internal Transfer",
|
|
96
|
-
parent=TxGroup.get_dbid("Ignore"),
|
|
97
|
-
)
|
|
92
|
+
INTERNAL_TRANSFER_TXGROUP_DBID: int | None = None
|
|
98
93
|
"""Database ID for the 'Internal Transfer' transaction group.
|
|
99
94
|
|
|
100
95
|
This group represents transactions that occur internally between treasury-owned wallets.
|
|
@@ -104,9 +99,7 @@ See Also:
|
|
|
104
99
|
:class:`dao_treasury.db.TxGroup`
|
|
105
100
|
"""
|
|
106
101
|
|
|
107
|
-
OUT_OF_RANGE_TXGROUP_DBID =
|
|
108
|
-
name="Out of Range", parent=TxGroup.get_dbid("Ignore")
|
|
109
|
-
)
|
|
102
|
+
OUT_OF_RANGE_TXGROUP_DBID: int | None = None
|
|
110
103
|
"""Database ID for the 'Out of Range' transaction group.
|
|
111
104
|
|
|
112
105
|
This category is assigned to transactions where neither the sender nor the recipient
|
|
@@ -143,6 +136,9 @@ def sort_basic(entry: LedgerEntry) -> TxGroupDbid:
|
|
|
143
136
|
:func:`sort_advanced`
|
|
144
137
|
:class:`dao_treasury.sorting.HashMatcher`
|
|
145
138
|
"""
|
|
139
|
+
global INTERNAL_TRANSFER_TXGROUP_DBID
|
|
140
|
+
global OUT_OF_RANGE_TXGROUP_DBID
|
|
141
|
+
|
|
146
142
|
from_address = entry.from_address
|
|
147
143
|
to_address = entry.to_address
|
|
148
144
|
block = entry.block_number
|
|
@@ -150,8 +146,17 @@ def sort_basic(entry: LedgerEntry) -> TxGroupDbid:
|
|
|
150
146
|
txgroup_dbid: Optional[TxGroupDbid] = None
|
|
151
147
|
if TreasuryWallet.check_membership(from_address, block):
|
|
152
148
|
if TreasuryWallet.check_membership(to_address, block):
|
|
149
|
+
if INTERNAL_TRANSFER_TXGROUP_DBID is None:
|
|
150
|
+
INTERNAL_TRANSFER_TXGROUP_DBID = TxGroup.get_dbid(
|
|
151
|
+
name="Internal Transfer",
|
|
152
|
+
parent=TxGroup.get_dbid("Ignore"),
|
|
153
|
+
)
|
|
153
154
|
txgroup_dbid = INTERNAL_TRANSFER_TXGROUP_DBID
|
|
154
155
|
elif not TreasuryWallet.check_membership(to_address, block):
|
|
156
|
+
if OUT_OF_RANGE_TXGROUP_DBID is None:
|
|
157
|
+
OUT_OF_RANGE_TXGROUP_DBID = TxGroup.get_dbid(
|
|
158
|
+
name="Out of Range", parent=TxGroup.get_dbid("Ignore")
|
|
159
|
+
)
|
|
155
160
|
txgroup_dbid = OUT_OF_RANGE_TXGROUP_DBID
|
|
156
161
|
|
|
157
162
|
if txgroup_dbid is None:
|
|
@@ -167,10 +172,10 @@ def sort_basic(entry: LedgerEntry) -> TxGroupDbid:
|
|
|
167
172
|
|
|
168
173
|
if txgroup_dbid is None:
|
|
169
174
|
if TreasuryWallet.check_membership(from_address, block):
|
|
170
|
-
txgroup_dbid =
|
|
175
|
+
txgroup_dbid = db.must_sort_outbound_txgroup_dbid
|
|
171
176
|
|
|
172
177
|
elif TreasuryWallet.check_membership(to_address, block):
|
|
173
|
-
txgroup_dbid =
|
|
178
|
+
txgroup_dbid = db.must_sort_inbound_txgroup_dbid
|
|
174
179
|
|
|
175
180
|
else:
|
|
176
181
|
raise NotImplementedError("this isnt supposed to happen")
|
|
@@ -197,6 +202,9 @@ def sort_basic_entity(tx: db.TreasuryTx) -> TxGroupDbid:
|
|
|
197
202
|
:func:`sort_basic`
|
|
198
203
|
:func:`sort_advanced`
|
|
199
204
|
"""
|
|
205
|
+
global INTERNAL_TRANSFER_TXGROUP_DBID
|
|
206
|
+
global OUT_OF_RANGE_TXGROUP_DBID
|
|
207
|
+
|
|
200
208
|
from_address = tx.from_address.address
|
|
201
209
|
to_address = tx.to_address
|
|
202
210
|
block = tx.block
|
|
@@ -204,11 +212,20 @@ def sort_basic_entity(tx: db.TreasuryTx) -> TxGroupDbid:
|
|
|
204
212
|
txgroup_dbid: Optional[TxGroupDbid] = None
|
|
205
213
|
if TreasuryWallet.check_membership(from_address, block):
|
|
206
214
|
if TreasuryWallet.check_membership(tx.to_address.address, block):
|
|
215
|
+
if INTERNAL_TRANSFER_TXGROUP_DBID is None:
|
|
216
|
+
INTERNAL_TRANSFER_TXGROUP_DBID = TxGroup.get_dbid(
|
|
217
|
+
name="Internal Transfer",
|
|
218
|
+
parent=TxGroup.get_dbid("Ignore"),
|
|
219
|
+
)
|
|
207
220
|
txgroup_dbid = INTERNAL_TRANSFER_TXGROUP_DBID
|
|
208
221
|
elif not (
|
|
209
222
|
TreasuryWallet.check_membership(tx.to_address.address, tx.block)
|
|
210
223
|
or from_address in constants.DISPERSE_APP
|
|
211
224
|
):
|
|
225
|
+
if OUT_OF_RANGE_TXGROUP_DBID is None:
|
|
226
|
+
OUT_OF_RANGE_TXGROUP_DBID = TxGroup.get_dbid(
|
|
227
|
+
name="Out of Range", parent=TxGroup.get_dbid("Ignore")
|
|
228
|
+
)
|
|
212
229
|
txgroup_dbid = OUT_OF_RANGE_TXGROUP_DBID
|
|
213
230
|
|
|
214
231
|
if txgroup_dbid is None:
|
|
@@ -222,23 +239,23 @@ def sort_basic_entity(tx: db.TreasuryTx) -> TxGroupDbid:
|
|
|
222
239
|
|
|
223
240
|
if txgroup_dbid is None:
|
|
224
241
|
if TreasuryWallet.check_membership(from_address, block):
|
|
225
|
-
txgroup_dbid =
|
|
242
|
+
txgroup_dbid = db.must_sort_outbound_txgroup_dbid
|
|
226
243
|
|
|
227
244
|
elif TreasuryWallet.check_membership(to_address.address, block):
|
|
228
|
-
txgroup_dbid =
|
|
245
|
+
txgroup_dbid = db.must_sort_inbound_txgroup_dbid
|
|
229
246
|
|
|
230
247
|
elif from_address in constants.DISPERSE_APP:
|
|
231
|
-
txgroup_dbid =
|
|
248
|
+
txgroup_dbid = db.must_sort_outbound_txgroup_dbid
|
|
232
249
|
|
|
233
250
|
elif from_address in constants.DISPERSE_APP:
|
|
234
|
-
txgroup_dbid =
|
|
251
|
+
txgroup_dbid = db.must_sort_outbound_txgroup_dbid
|
|
235
252
|
|
|
236
253
|
else:
|
|
237
254
|
raise NotImplementedError("this isnt supposed to happen")
|
|
238
255
|
|
|
239
256
|
if txgroup_dbid not in (
|
|
240
|
-
|
|
241
|
-
|
|
257
|
+
db.must_sort_inbound_txgroup_dbid,
|
|
258
|
+
db.must_sort_outbound_txgroup_dbid,
|
|
242
259
|
):
|
|
243
260
|
logger.info("Sorted %s to %s", tx, TxGroup.get_fullname(txgroup_dbid))
|
|
244
261
|
|
|
@@ -274,8 +291,8 @@ async def sort_advanced(entry: db.TreasuryTx) -> TxGroupDbid:
|
|
|
274
291
|
txgroup_dbid = sort_basic_entity(entry)
|
|
275
292
|
|
|
276
293
|
if txgroup_dbid in (
|
|
277
|
-
|
|
278
|
-
|
|
294
|
+
db.must_sort_inbound_txgroup_dbid,
|
|
295
|
+
db.must_sort_outbound_txgroup_dbid,
|
|
279
296
|
):
|
|
280
297
|
for rules in SORT_RULES.values():
|
|
281
298
|
for rule in rules:
|
|
@@ -286,8 +303,8 @@ async def sort_advanced(entry: db.TreasuryTx) -> TxGroupDbid:
|
|
|
286
303
|
except ContractNotVerified:
|
|
287
304
|
continue
|
|
288
305
|
if txgroup_dbid not in (
|
|
289
|
-
|
|
290
|
-
|
|
306
|
+
db.must_sort_inbound_txgroup_dbid,
|
|
307
|
+
db.must_sort_outbound_txgroup_dbid,
|
|
291
308
|
):
|
|
292
309
|
logger.info("Sorted %s to %s", entry, TxGroup.get_fullname(txgroup_dbid))
|
|
293
310
|
await entry._set_txgroup(txgroup_dbid)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
dao_treasury/treasury.py
CHANGED
|
@@ -18,11 +18,11 @@ This is the main entry point for orchestrating DAO treasury analytics.
|
|
|
18
18
|
from asyncio import create_task, gather
|
|
19
19
|
from logging import getLogger
|
|
20
20
|
from pathlib import Path
|
|
21
|
-
from typing import Final, Iterable, List, Optional, Union
|
|
21
|
+
from typing import Dict, Final, Iterable, List, Optional, Union
|
|
22
22
|
|
|
23
23
|
import a_sync
|
|
24
24
|
from a_sync.a_sync.abstract import ASyncABC
|
|
25
|
-
from eth_typing import BlockNumber
|
|
25
|
+
from eth_typing import BlockNumber, HexAddress
|
|
26
26
|
from eth_portfolio.structs import LedgerEntry
|
|
27
27
|
from eth_portfolio.typing import PortfolioBalances
|
|
28
28
|
from eth_portfolio_scripts._portfolio import ExportablePortfolio
|
|
@@ -52,6 +52,7 @@ class Treasury(a_sync.ASyncGenericBase): # type: ignore [misc]
|
|
|
52
52
|
sort_rules: Optional[Path] = None,
|
|
53
53
|
start_block: int = 0,
|
|
54
54
|
label: str = "your org's treasury",
|
|
55
|
+
custom_buckets: Optional[Dict[HexAddress, str]] = None,
|
|
55
56
|
asynchronous: bool = False,
|
|
56
57
|
) -> None:
|
|
57
58
|
"""Initialize the Treasury singleton for managing DAO funds.
|
|
@@ -124,6 +125,7 @@ class Treasury(a_sync.ASyncGenericBase): # type: ignore [misc]
|
|
|
124
125
|
start_block=start_block,
|
|
125
126
|
label=label,
|
|
126
127
|
load_prices=True,
|
|
128
|
+
custom_buckets=custom_buckets,
|
|
127
129
|
asynchronous=asynchronous,
|
|
128
130
|
)
|
|
129
131
|
"""An eth_portfolio.Portfolio object used for exporting tx and balance history"""
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dao_treasury
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: Produce comprehensive financial reports for your on-chain org
|
|
5
5
|
Classifier: Development Status :: 3 - Alpha
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -14,8 +14,8 @@ Classifier: Operating System :: OS Independent
|
|
|
14
14
|
Classifier: Topic :: Software Development :: Libraries
|
|
15
15
|
Requires-Python: >=3.10,<3.13
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
|
-
Requires-Dist: eth-portfolio-temp
|
|
18
|
-
Requires-Dist:
|
|
17
|
+
Requires-Dist: eth-portfolio-temp==0.3.2
|
|
18
|
+
Requires-Dist: psycopg2-binary==2.9.11
|
|
19
19
|
Dynamic: classifier
|
|
20
20
|
Dynamic: description
|
|
21
21
|
Dynamic: description-content-type
|
|
@@ -30,6 +30,7 @@ DAO Treasury is a comprehensive financial reporting and treasury management solu
|
|
|
30
30
|
- **Financial Reporting for DAOs:** Extends core portfolio functionalities to generate detailed reports tailored for on-chain organizations.
|
|
31
31
|
- **Dashboard Provisioning:** Utilizes [Grafana](https://grafana.com/) dashboards—defined in JSON files within the .grafana/provisioning directories—to offer real-time, dynamic visualizations of treasury data.
|
|
32
32
|
- **Automated Data Export:** Features a treasury export tool that, once configured (with a supported [brownie network](https://eth-brownie.readthedocs.io/en/stable/network-management.html) and [Docker](https://www.docker.com/get-started/)), continuously captures financial snapshots at set intervals.
|
|
33
|
+
- **Custom Buckets for Wallets:** Assign custom categories ("buckets") to specific wallet addresses for more granular reporting using the `--custom-bucket` CLI option.
|
|
33
34
|
- **Ease of Contribution:** Non-technical users can easily update or create dashboard visuals using Grafana’s intuitive UI. The [Contributing Guidelines](https://github.com/BobTheBuidler/dao-treasury/blob/master/CONTRIBUTING.md) document provides a step-by-step guide to defining new visuals and dashboards and integrating those changes into the repository, ensuring that anyone can contribute to the visual reporting aspect of the project.
|
|
34
35
|
|
|
35
36
|
## Requirements
|
|
@@ -42,7 +43,7 @@ DAO Treasury is a comprehensive financial reporting and treasury management solu
|
|
|
42
43
|
- 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.). Your archive node must have tracing enabled (free-tier Alchemy nodes do not support this option).
|
|
43
44
|
- You must configure a [brownie network](https://eth-brownie.readthedocs.io/en/stable/network-management.html) to use your RPC.
|
|
44
45
|
- You will 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.
|
|
45
|
-
- You'll also need [Docker](https://www.docker.com/get-started/) installed on your system. If on MacOS, you will need to leave Docker Desktop open while
|
|
46
|
+
- You'll also need [Docker](https://www.docker.com/get-started/) installed on your system. If on MacOS, you will need to leave Docker Desktop open while DAO Treasury is running.
|
|
46
47
|
|
|
47
48
|
## Installation
|
|
48
49
|
|
|
@@ -64,15 +65,28 @@ For local development (from source installation), use:
|
|
|
64
65
|
poetry run dao-treasury run --wallet 0x123 --network mainnet --interval 12h
|
|
65
66
|
```
|
|
66
67
|
|
|
68
|
+
**Assigning Custom Buckets to Wallets:**
|
|
69
|
+
|
|
70
|
+
You can assign custom categories ("buckets") to specific wallet addresses for more granular reporting. Use the `--custom-bucket` option one or more times, each with the format `address:bucket_name`:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
dao-treasury run --wallet 0x123 --network mainnet --custom-bucket "0x123:Operations" --custom-bucket "0x456:Grants" --custom-bucket "0x789:Investments"
|
|
74
|
+
```
|
|
75
|
+
|
|
67
76
|
**CLI Options:**
|
|
77
|
+
> Only optional arguments are listed here. Required arguments (such as `--wallet` or `--wallets`) are shown in the usage examples above.
|
|
78
|
+
|
|
68
79
|
- `--network`: The id of the brownie network the exporter will connect to (default: mainnet)
|
|
69
80
|
- `--interval`: The time interval between each data snapshot (default: 12h)
|
|
70
81
|
- `--concurrency`: The max number of historical blocks to export concurrently. (default: 30)
|
|
71
82
|
- `--daemon`: Run the export process in the background (default: False) (NOTE: currently unsupported)
|
|
83
|
+
- `--sort-rules`: Directory containing sort rules definitions for transaction categorization.
|
|
84
|
+
- `--nicknames`: File containing address nicknames for reporting.
|
|
72
85
|
- `--grafana-port`: Set the port for the Grafana dashboard where you can view data (default: 3004)
|
|
73
86
|
- `--renderer-port`: Set the port for the report rendering service (default: 8091)
|
|
74
87
|
- `--victoria-port`: Set the port for the Victoria metrics reporting endpoint (default: 8430)
|
|
75
88
|
- `--start-renderer`: If set, both the Grafana and renderer containers will be started for dashboard image export. By default, only the grafana container is started.
|
|
89
|
+
- `--custom-bucket`: Assign a custom bucket/category to a wallet address for reporting. Specify as `address:bucket_name`. Can be used multiple times.
|
|
76
90
|
|
|
77
91
|
After running the command, the export script will run continuously until you close your terminal.
|
|
78
92
|
To view the dashboards, just open your browser and navigate to [http://localhost:3004](http://localhost:3004)!
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
dao_treasury__mypyc.cp312-win32.pyd,sha256=1dXNAAs0AMxvDIrQZE4JU444RE3ScJFlgNmRziBCDaA,265728
|
|
2
|
+
dao_treasury/ENVIRONMENT_VARIABLES.py,sha256=LS_D4ALB3BO-vYKyh1tzRHi10QBE6f654Zy8pmJ_xPY,656
|
|
3
|
+
dao_treasury/__init__.py,sha256=fEHZYMeNqVUI9YAVXCHozxDB7cvJJnaF4HBRyeAlOiw,1435
|
|
4
|
+
dao_treasury/_docker.cp312-win32.pyd,sha256=ofk30OF9wg2z6qdmekB8t7IfdfyqYj5Z_Ksu6lQOGHc,9216
|
|
5
|
+
dao_treasury/_docker.py,sha256=yAMcwXl48hGPN2sH5b56O_XP3wrd1gap959Xrk8KpKM,6337
|
|
6
|
+
dao_treasury/_nicknames.cp312-win32.pyd,sha256=xSvvgC34hDijMrXFELOa7JaWTSznt0lg15LvrawjNss,9216
|
|
7
|
+
dao_treasury/_nicknames.py,sha256=4Smlv4y5248PM-yDEyybbR1Of1-tIHgf0PCBAXTE3Aw,1071
|
|
8
|
+
dao_treasury/_wallet.cp312-win32.pyd,sha256=PNRYC5_gpu6dnIQmJfi5w6ExN24yCniGoPi0Qf_X_-k,9216
|
|
9
|
+
dao_treasury/_wallet.py,sha256=nHBAKFJstdKuYbvpskGVx2KU80YrZHGHsEh5V3TwIHs,10712
|
|
10
|
+
dao_treasury/constants.cp312-win32.pyd,sha256=M_yWtqRKml0tN2nqVksxleNmItyouf93kVZFz-PXXZk,9216
|
|
11
|
+
dao_treasury/constants.py,sha256=-T0oPw7lC5YeaiplHAtYL-2ss7knvKrJKQ1LCc8kX8g,1483
|
|
12
|
+
dao_treasury/db.py,sha256=RtKgCBNh8VxzDhx0FrFn5d9BxxAxbp9aAvl4XtqbztY,61710
|
|
13
|
+
dao_treasury/docker-compose.yaml,sha256=QDObz1wC7RhEgKqkCATvYWI0iIQGNA26ZwxBuv-f-lI,1670
|
|
14
|
+
dao_treasury/main.py,sha256=G7ufSB4h6hojvDzU2Zj-5yMSp39bgnPguHbVAw9JvBY,9886
|
|
15
|
+
dao_treasury/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
dao_treasury/treasury.py,sha256=K4XOg-5BHoP5HoRlHNu4afNpYs2-8sjCOOGwdt3M21w,7541
|
|
17
|
+
dao_treasury/types.cp312-win32.pyd,sha256=g7kFmksfAYd_YAYiH1lpi9JyS1v005N3HT-ItjQdv8k,9216
|
|
18
|
+
dao_treasury/types.py,sha256=KFz4WKPp4t_RBwIT6YGwOcgbzw8tdHIOcXTFsUA0pJA,3818
|
|
19
|
+
dao_treasury/.grafana/provisioning/dashboards/dashboards.yaml,sha256=to_cVfl8X6-5zVskkDxNtTE191TH52XO2peGfHPI5F0,201
|
|
20
|
+
dao_treasury/.grafana/provisioning/dashboards/breakdowns/Expenses.json,sha256=aBwKDj5HBkSXlSt5L7Cg_Ce5yK0VaRKAWVe19j-HCgQ,17809
|
|
21
|
+
dao_treasury/.grafana/provisioning/dashboards/breakdowns/Revenue.json,sha256=xzvFemq3hYoXdoOafspsuCU8jHCbC2JOtgOq_a_aFPU,17517
|
|
22
|
+
dao_treasury/.grafana/provisioning/dashboards/streams/LlamaPay.json,sha256=ukfBKgqIF7I43Lv8SfEnLrrYqCmRQbmSiumwd2h1a8A,6657
|
|
23
|
+
dao_treasury/.grafana/provisioning/dashboards/summary/Monthly.json,sha256=Qq7nT43rbaFEdmW188ptAWSZ8swBT39jF5lSEzjULb8,9896
|
|
24
|
+
dao_treasury/.grafana/provisioning/dashboards/transactions/Treasury Transactions.json,sha256=oUQSEaoT3rjOYYkRDnzA5R7UEFo4h0IJVTmNSraBLo4,13806
|
|
25
|
+
dao_treasury/.grafana/provisioning/dashboards/transactions/Unsorted Transactions.json,sha256=G7qS6IDh4PcEMAwEcvS1U98FuVHlV7YoTaGw_r8ENN4,19098
|
|
26
|
+
dao_treasury/.grafana/provisioning/dashboards/treasury/Cashflow (Including Unsorted).json,sha256=mfKHcSzP2p1_34wOa5LNyv_j2M2hqOlYB4u5mlIpYfc,23886
|
|
27
|
+
dao_treasury/.grafana/provisioning/dashboards/treasury/Cashflow.json,sha256=4DowQdq-4w8VZrdVXzyl56Ngd-EbvSxsRkXstIa0SAg,17383
|
|
28
|
+
dao_treasury/.grafana/provisioning/dashboards/treasury/Current Treasury Assets.json,sha256=VNqRUx9-Jgg4GhyHXRY8nZp67P12ehmWyludW77gP98,26508
|
|
29
|
+
dao_treasury/.grafana/provisioning/dashboards/treasury/Historical Treasury Balances.json,sha256=53fCotzJSElELRS1ABNkXX0_CG1_gBLHpjOthhYTDnw,136157
|
|
30
|
+
dao_treasury/.grafana/provisioning/dashboards/treasury/Operating Cashflow.json,sha256=16Ue5dPjrDWP--YWnPZlBUqeXoys510gqxM3ALE_R8k,13831
|
|
31
|
+
dao_treasury/.grafana/provisioning/datasources/datasources.yaml,sha256=TGuZ9h4aHsDkDW39aSjoy9HZYwvht7zX_0oosAGdE98,427
|
|
32
|
+
dao_treasury/sorting/__init__.cp312-win32.pyd,sha256=zYZi2Vxe9gKAzs5sBMb471rs8xjk9VNo9G_r6HXFRPA,9216
|
|
33
|
+
dao_treasury/sorting/__init__.py,sha256=z3Bd2HUZjilZfV1cWSHUHagAPEPGyI0S8h6DtBf6w78,11448
|
|
34
|
+
dao_treasury/sorting/_matchers.cp312-win32.pyd,sha256=-8tfs7GNb_JsbLj_1rYaGIu0hj3xEnadrWh5CJx_Q3Y,9216
|
|
35
|
+
dao_treasury/sorting/_matchers.py,sha256=ACi6aXZCKW5OTiztsID7CXCGJounj5c6ivhOCg2436M,14392
|
|
36
|
+
dao_treasury/sorting/_rules.cp312-win32.pyd,sha256=r1Zpt-bgv8SQm1UwxQ2AkXFPj9gp7Gpd6Hf0BJtWHcY,9216
|
|
37
|
+
dao_treasury/sorting/_rules.py,sha256=DxhdUgpS0q0LWeLl9W1Bjn5LZz9z4OLA03vQllPMH9k,9229
|
|
38
|
+
dao_treasury/sorting/factory.cp312-win32.pyd,sha256=QlwEI8UC-FyxCLN3tWSoAGakcNaFa9QIEz4Zut_0CS0,9216
|
|
39
|
+
dao_treasury/sorting/factory.py,sha256=zlJ18xlMTxv8ACV6_MimCVIDsw3K5AZcyvKaNYY7R14,10484
|
|
40
|
+
dao_treasury/sorting/rule.cp312-win32.pyd,sha256=Zy_Cxc2AtxGYjrNAfCf7A6Lib_U9FiwQU0LC-WZ5zfw,9216
|
|
41
|
+
dao_treasury/sorting/rule.py,sha256=wbL8s0-6dxcCKghUtEDSkLDBnyvggsJ3gt_RawQ6kB4,11972
|
|
42
|
+
dao_treasury/sorting/rules/__init__.cp312-win32.pyd,sha256=SWN5-xIjsKhEQcT3NKXCvya2A2lvL9kU7b2kqLiulKM,9216
|
|
43
|
+
dao_treasury/sorting/rules/__init__.py,sha256=hcLfejOEwD8RaM2RE-38Ej6_WkvL9BVGvIIGY848E6E,49
|
|
44
|
+
dao_treasury/sorting/rules/ignore/__init__.cp312-win32.pyd,sha256=YggqtNascpppNbKUZMwU8SMle2fMeS6ug6kAAsxdjIE,9216
|
|
45
|
+
dao_treasury/sorting/rules/ignore/__init__.py,sha256=16THKoGdj6qfkkytuCFVG_R1M6KSErMI4AVE1p0ukS4,58
|
|
46
|
+
dao_treasury/sorting/rules/ignore/llamapay.cp312-win32.pyd,sha256=axEQe9FzT7xhvgiA61WwmdDsmCcIl0ItHL4-LarRF5Y,9216
|
|
47
|
+
dao_treasury/sorting/rules/ignore/llamapay.py,sha256=aYyAJRlmv419IeaqkcV5o3ffx0UVfteU0lTl80j0BGo,783
|
|
48
|
+
dao_treasury/streams/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
|
+
dao_treasury/streams/llamapay.py,sha256=rO1Mh2ndTziR6pnRkKHnQ22a_Yx9PM_-BG7I4dspEZ8,13535
|
|
50
|
+
dao_treasury-0.1.6.dist-info/METADATA,sha256=V8cnOfc9hp25K3UTakSn0un9qqZ4fJXQXNP_leeUow4,8306
|
|
51
|
+
dao_treasury-0.1.6.dist-info/WHEEL,sha256=LwxTQZ0gyDP_uaeNCLm-ZIktY9hv6x0e22Q-hgFd-po,97
|
|
52
|
+
dao_treasury-0.1.6.dist-info/top_level.txt,sha256=CV8aYytuSYplDhLVY4n0GphckdysXCd1lHmbqfsPxNk,33
|
|
53
|
+
dao_treasury-0.1.6.dist-info/RECORD,,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
dao_treasury__mypyc.cp312-win32.pyd,sha256=9C1HlnsqSbzfSpSm-NGBlNC82zsa_o4MT-U5fo1ZTRY,445440
|
|
2
|
-
dao_treasury/ENVIRONMENT_VARIABLES.py,sha256=LS_D4ALB3BO-vYKyh1tzRHi10QBE6f654Zy8pmJ_xPY,656
|
|
3
|
-
dao_treasury/__init__.py,sha256=ai8iALE_Zv43O9cH1jkNJ39bzhr60kBDX6L7C4Nj9FA,1539
|
|
4
|
-
dao_treasury/_docker.cp312-win32.pyd,sha256=sS8pLlDft5E8b2vrDZySAvvcgjFSyVpbrzC_Snepy74,9216
|
|
5
|
-
dao_treasury/_docker.py,sha256=UFMN-TIBUQBheMIhIhSMhaq7UFgt6ubUcfzwPNap_6o,6098
|
|
6
|
-
dao_treasury/_nicknames.cp312-win32.pyd,sha256=NeCUYzzOdELEhl-mXDdomjfBR4srr70FYpJiK5HP4gI,9216
|
|
7
|
-
dao_treasury/_nicknames.py,sha256=n8c-JZhORYymCMv6jsC96IthAzAhpslyEn-KCk_YiSM,1049
|
|
8
|
-
dao_treasury/_wallet.cp312-win32.pyd,sha256=wvoXkZYVnz_jqE8IQCNM4RZX9yQCP0LfNNExzNdOvmw,9216
|
|
9
|
-
dao_treasury/_wallet.py,sha256=nHBAKFJstdKuYbvpskGVx2KU80YrZHGHsEh5V3TwIHs,10712
|
|
10
|
-
dao_treasury/constants.cp312-win32.pyd,sha256=0vBsc4XafcRGKxe4rVgpO43GMQYLIjK0kd2zyCeTn4E,9216
|
|
11
|
-
dao_treasury/constants.py,sha256=-T0oPw7lC5YeaiplHAtYL-2ss7knvKrJKQ1LCc8kX8g,1483
|
|
12
|
-
dao_treasury/db.py,sha256=3_-nm8vD92ECaHxjMYf0eaXfsBRC2ojGcm-AFz2ZLAQ,50625
|
|
13
|
-
dao_treasury/docker-compose.yaml,sha256=wNNE9xmkchcV-nJxzrmUkbUA0CW1qgdGQKJ7uw2P8nU,1350
|
|
14
|
-
dao_treasury/main.py,sha256=w7VBmBwNBYjOkz2LpT4_9FZ1CI8AVcr4vyfr1wZVk5Q,8458
|
|
15
|
-
dao_treasury/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
-
dao_treasury/treasury.py,sha256=wh4wESLbYSHjcfpa-sW5TIqa5pSC9Y_7Id8tzLzJLaw,7414
|
|
17
|
-
dao_treasury/types.cp312-win32.pyd,sha256=X1WImhXY-YGPZvIQTXerwNjojQ7TE3fLMtzb0JxhYVY,9216
|
|
18
|
-
dao_treasury/types.py,sha256=KFz4WKPp4t_RBwIT6YGwOcgbzw8tdHIOcXTFsUA0pJA,3818
|
|
19
|
-
dao_treasury/.grafana/provisioning/dashboards/dashboards.yaml,sha256=NfmmICGLVfIrI8ulzUTUYc7wFetk2v-x6eaoYHnCvQc,1914
|
|
20
|
-
dao_treasury/.grafana/provisioning/dashboards/breakdowns/Expenses.json,sha256=gxfPI4eO3PDPe70Yx7_dN0Yx5isvgy-MKe-fizBClMw,16879
|
|
21
|
-
dao_treasury/.grafana/provisioning/dashboards/breakdowns/Revenue.json,sha256=eowBLlWgL3bsE1B17oYZKA-N9woBT4lHlRrhdqSY5KA,16483
|
|
22
|
-
dao_treasury/.grafana/provisioning/dashboards/streams/LlamaPay.json,sha256=zRSpnlDD3_fsynCDxfdV3HRjqWbeAqhad-YBe1rMQGo,7419
|
|
23
|
-
dao_treasury/.grafana/provisioning/dashboards/summary/Monthly.json,sha256=eqOVxhBV3YYsGhEs2xvnuDU1VX_DdxDFn-XuXKJ3Tpc,6860
|
|
24
|
-
dao_treasury/.grafana/provisioning/dashboards/transactions/Treasury Transactions.json,sha256=Ig_Z9gdAUnPb3OKZzkokoM9OmFsUiJRIcCTOMImJk-k,13133
|
|
25
|
-
dao_treasury/.grafana/provisioning/dashboards/treasury/Cashflow (Including Unsorted).json,sha256=s0SYuemqh9RgYm2H_gApmUJ73w-7P5czviUFmE0qOzE,28145
|
|
26
|
-
dao_treasury/.grafana/provisioning/dashboards/treasury/Cashflow.json,sha256=MzmeP5fdATIUCzeXV0ZBfzuwef2TRm050Sa6FAjUCpc,20009
|
|
27
|
-
dao_treasury/.grafana/provisioning/dashboards/treasury/Current Treasury Assets.json,sha256=TeVujxB5ibsPdbfwmbpW1ApjcdfKoSGkv_mS4wBDtZQ,14681
|
|
28
|
-
dao_treasury/.grafana/provisioning/dashboards/treasury/Historical Treasury Balances.json,sha256=7qVXn2PjeBIp2pFRbVfxA4PeWxhhVKQCr4qIPZoIj90,133963
|
|
29
|
-
dao_treasury/.grafana/provisioning/dashboards/treasury/Operating Cashflow.json,sha256=fYkiZ37Eg2vu9dPJavCZXPPtX6-rTDbJwE_Ougpo2Mk,15828
|
|
30
|
-
dao_treasury/.grafana/provisioning/datasources/datasources.yaml,sha256=gLmJsOkEXNzWRDibShfHFySWeuExW-dSB_U0OSfH868,344
|
|
31
|
-
dao_treasury/sorting/__init__.cp312-win32.pyd,sha256=NKFEimpOwrlBSmqTr9ChNM5uGkeRwp0ao5_J6bE2HSc,9216
|
|
32
|
-
dao_treasury/sorting/__init__.py,sha256=_uxM_FE1paM8oDAhDdHSyhDwnrlxCYX_lGn2DOqCaHU,10666
|
|
33
|
-
dao_treasury/sorting/_matchers.cp312-win32.pyd,sha256=G0v2xROhErK1I-DpduZRCiSJp13y64wlnoVXHmjGdX8,9216
|
|
34
|
-
dao_treasury/sorting/_matchers.py,sha256=ACi6aXZCKW5OTiztsID7CXCGJounj5c6ivhOCg2436M,14392
|
|
35
|
-
dao_treasury/sorting/_rules.cp312-win32.pyd,sha256=cRTpBunUb6uodFOaFYpZsA1kLFRJdhb32Z1lOcLixiE,9216
|
|
36
|
-
dao_treasury/sorting/_rules.py,sha256=DxhdUgpS0q0LWeLl9W1Bjn5LZz9z4OLA03vQllPMH9k,9229
|
|
37
|
-
dao_treasury/sorting/factory.cp312-win32.pyd,sha256=t4A_98mjbAW1xe0NbISwPgziPb_Qh6AGYRLCq2v7Bso,9216
|
|
38
|
-
dao_treasury/sorting/factory.py,sha256=zlJ18xlMTxv8ACV6_MimCVIDsw3K5AZcyvKaNYY7R14,10484
|
|
39
|
-
dao_treasury/sorting/rule.cp312-win32.pyd,sha256=XT3mWpFUd6x4R8zt5E1A_ETgAjz2pD_RSTAgZo1jIww,9216
|
|
40
|
-
dao_treasury/sorting/rule.py,sha256=wbL8s0-6dxcCKghUtEDSkLDBnyvggsJ3gt_RawQ6kB4,11972
|
|
41
|
-
dao_treasury/sorting/rules/__init__.cp312-win32.pyd,sha256=yo5UFwiR8QpUjU0pbqmnuVw1cmbgY8vigUQnMxabR0U,9216
|
|
42
|
-
dao_treasury/sorting/rules/__init__.py,sha256=hcLfejOEwD8RaM2RE-38Ej6_WkvL9BVGvIIGY848E6E,49
|
|
43
|
-
dao_treasury/sorting/rules/ignore/__init__.cp312-win32.pyd,sha256=m_zHc62_OKuujmAZvHQQAOyVtwNJsHJ8dhjqZMbs1dg,9216
|
|
44
|
-
dao_treasury/sorting/rules/ignore/__init__.py,sha256=16THKoGdj6qfkkytuCFVG_R1M6KSErMI4AVE1p0ukS4,58
|
|
45
|
-
dao_treasury/sorting/rules/ignore/llamapay.cp312-win32.pyd,sha256=Xj-Nsdezk9DTM8inY3qSJgaAXi_a-8_UNAB74WPFY5s,9216
|
|
46
|
-
dao_treasury/sorting/rules/ignore/llamapay.py,sha256=aYyAJRlmv419IeaqkcV5o3ffx0UVfteU0lTl80j0BGo,783
|
|
47
|
-
dao_treasury/streams/__init__.cp312-win32.pyd,sha256=bFul_pUtkIv-N2VQMEZgLcxjY_bndZYd9hydX9yLltk,9216
|
|
48
|
-
dao_treasury/streams/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
|
-
dao_treasury/streams/llamapay.cp312-win32.pyd,sha256=7erKuzOJ_xJkOlTI1TaAK1NBkkEAz5m3mLqtrvvKKr8,9216
|
|
50
|
-
dao_treasury/streams/llamapay.py,sha256=rO1Mh2ndTziR6pnRkKHnQ22a_Yx9PM_-BG7I4dspEZ8,13535
|
|
51
|
-
dao_treasury-0.0.60.dist-info/METADATA,sha256=Ufkev7h0V31lvudy9p5vpX_EtSeVE51ehJwbH2CX-Uw,7274
|
|
52
|
-
dao_treasury-0.0.60.dist-info/WHEEL,sha256=LwxTQZ0gyDP_uaeNCLm-ZIktY9hv6x0e22Q-hgFd-po,97
|
|
53
|
-
dao_treasury-0.0.60.dist-info/top_level.txt,sha256=CV8aYytuSYplDhLVY4n0GphckdysXCd1lHmbqfsPxNk,33
|
|
54
|
-
dao_treasury-0.0.60.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|