…configure-ipfs, add read-din-per-eth
PR A of the `develop` backport plan agreed on InfiniteZeroFoundation#79. Four independent fixes, no
behavioural change beyond removing a wallet requirement one command never
needed.
**1. `requires-python` >= 3.12.** `dincli/cli/dintoken.py:76` uses PEP 701
nested same-type quotes inside an f-string expression, which is a SyntaxError
before 3.12. Measured, not inferred, under a `uv`-installed CPython 3.11.15:
SyntaxError: f-string: unmatched '('
Clean under 3.12.3. Sweeping every file under `dincli/`, that is the only one
affected. Note this is a different site from the one that justified the same
bump on `main` (`aggregator.py:76-77`), which does not exist here.
**2. Four imported-but-undeclared dependencies.** `rich`, `requests`,
`eth-account` and `py-multibase` were all arriving transitively via
typer/web3/py-cid rather than being declared. `rich` is the load-bearing one:
at this package's own declared floor of `typer>=0.9.0`, typer 0.9.0 lists rich
only under `extra == "all"`, so a resolver may legitimately install without it.
Reproduced in a clean venv, then confirmed fixed:
before (develop's dep list) : ModuleNotFoundError: No module named 'rich'
after (this branch's list) : import dincli.main OK
`rich` is imported in 10 files, so that is a hard startup failure, not a
degraded path. This is the same class of bug as `main`'s explicit `click`
declaration, but note `click` itself is NOT applicable here: nothing on
`develop` imports it (`main` needs it because `cli/core.py:7` does). It becomes
necessary here only when the chain-id work lands, so it belongs with PR B.
**3. `configure-ipfs` added to the system callback skip-list.** It was falling
through to `get_en_w3_account_console()` and demanding a connected wallet it
never uses: the function body references only `ctx.obj.console`, `load_config`
and `resolve_ipfs_config`. Only this one entry was missing here - `develop`
already spells `"read-wallet"` and `"show-index"` correctly, so the other
two-thirds of `main`'s `c5ed47c` is a no-op on this branch.
**4. `read-din-per-eth`.** `dinPerEth()` is owner-mutable and `buy` spends
against whatever rate is live, with no way to read it first. `dinPerEth`
previously appeared only in `abis/DinCoordinator.json`.
Deviation from `main` worth flagging: `main` duplicates this command in both
`aggregator.py` and `auditor.py`. Here it is one shared helper in
`dintoken.py`, with the three `dintoken` sub-apps delegating to it exactly as
they already do for buy/stake/read-stake. A test pins that there is only one
implementation site.
16 tests added, including two guards proven able to fail by mutation: the
skip-list check catches the underscore-vs-dash dead-entry class, and the
dependency check catches any future import that is not declared. Suite:
114 -> 130 passing.
Refs InfiniteZeroFoundation#79
PR A of the split agreed on #79. Four independent fixes, no behavioural change beyond removing a wallet requirement one command never needed.
Two of the four turned out differently on
developthan themaincommits they came from, so those are called out below rather than buried.1.
requires-python→>=3.12Measured, not inferred.
develop:dincli/cli/dintoken.py:76uses PEP 701 nested same-type quotes inside an f-string expression. Under auv-installed CPython 3.11.15:Clean under 3.12.3, and sweeping every file under
dincli/that is the only one affected.Worth noting this is a different site from the one that justified the same bump on
main(aggregator.py:76-77, which doesn't exist here) — sodevelopneeded the floor on its own evidence, not by inheritance.2. Four imported-but-undeclared dependencies
rich,requests,eth-accountandpy-multibasewere all arriving transitively via typer/web3/py-cid instead of being declared.richis the load-bearing one, and it's an install-breaking bug today. At this package's own declared floor oftyper>=0.9.0, typer 0.9.0 lists rich only underextra == "all":So a resolver may legitimately install without rich. Reproduced in a clean venv, then confirmed fixed:
richis imported in 10 files, so it's a hard startup failure rather than a degraded path.Correction to the plan:
clickis not applicable here. I listed42f19caunder PR A on #79, but nothing ondevelopimports click —mainneeds it becausecli/core.py:7does, and that file arrives with the chain-id work. So it belongs with PR B, where it will actually be justified, and I've left it out of this one.3.
configure-ipfsadded to the skip-listIt was falling through to
get_en_w3_account_console()and demanding a connected wallet it never uses — the body references onlyctx.obj.console,load_configandresolve_ipfs_config.Only this one entry was missing.
developalready spells"read-wallet"and"show-index"correctly, so the other two-thirds ofc5ed47cis a no-op here.4.
read-din-per-ethdinPerEth()is owner-mutable andbuyspends against whatever rate is live, with no way to read it beforehand. Before this,dinPerEthappeared only inabis/DinCoordinator.json.Deviation from
main:mainduplicates this command in bothaggregator.pyandauditor.py. Here it's one shared helper indintoken.pywith the threedintokensub-apps delegating to it, exactly as they already do for buy/stake/read-stake. Available at all three call sites:A test pins that there is only one implementation site, so it can't quietly get duplicated later.
Tests
114 → 130 passing. 16 added, and two of them are guards I checked can actually fail rather than passing vacuously:
"read-wallet"back to"read_wallet"fails itdincli/and fails on any that isn't declared, so this class of bug can't come back silentlydintoken.py:76, with no false positives — if that syntax ever disappears the test says so, rather than leaving the floor unexplained