ID: task_300626_3
Assigned to: Santiago Rodriguez Cetran
Created: 2026-06-30
Status: Open
Repo: https://github.com/InfiniteZeroFoundation/DevNet (base branch: develop)
Roadmap ref: P3-T0.2b (Keystore Security & Resource Documentation) · Filecoin Provider Adapter (Developer/discussion/add-filecoin-support.md)
Dates: Jul 1–3, 2026 (3 days)
Clone the repository, create a branch, and switch to it:
# 1. Clone the repository
git clone https://github.com/InfiniteZeroFoundation/DevNet
# 2. Navigate to the project directory
cd DevNet
# 1. Switch to your develop branch
git checkout develop
# 2. Pull the latest changes from the remote repository
git pull origin develop
# 3. Create and switch to your new branch
git checkout -b feat/validator-readinessThis task continues the validator operational readiness track you started with PR #12. A prospective external validator has committed to joining the devnet once these items are in place — they are blocking requirements, not nice-to-haves.
One scoping note before you start: SIGTERM handling (T0.2a) has been deliberately deferred to P4. dincli is a one-shot CLI, not a daemon. Process-level SIGTERM handling adds complexity without meaningful benefit at this stage — it becomes relevant when dind (the din daemon) is built as a long-running daemon.
Umer will review all keystore-related changes given the security sensitivity before they merge. Flag the PR with needs-security-review when it's ready.
dincli/cli/system.py::connect_wallet already has multiple key-loading paths. The .env-based multi-account pattern (ETH_PRIVATE_KEY_<n>) is genuinely useful for local testing and multi-account workflows and should be kept. The goal is not to remove these paths but to clearly classify them by security tier and ensure production validators are steered toward the more secure options added in 1c.
Current paths and their appropriate tier:
| Path | Current behaviour | Tier |
|---|---|---|
privatekey positional argument |
Raw 0x... key accepted; warning printed but key enters shell history |
Dev only — strengthen the warning |
--key-file / -f |
Reads plaintext key from a file on disk | Dev/testing — document as not suitable for production |
--account <n> (non-demo) |
Reads ETH_PRIVATE_KEY_<n> from .env; supports multiple accounts |
Dev/testing — convenient and useful; not suitable for production validators |
_get_password from .env |
Encryption password pre-loaded from env var | Dev/testing — acceptable for automation; document the tradeoff |
Demo mode WALLET_FILE |
Saves "private_key" as plaintext JSON |
Dev/Hardhat only — already marked ⚠️ ONLY FOR MOCK!; no change needed |
Interactive getpass prompt |
Prompts for raw key, then encrypts at rest | Acceptable for production key import (key never touches disk) |
The docs and config templates should reflect this classification:
- In
.env.examplefiles (repo root andhardhat/), labelETH_PRIVATE_KEY_<n>entries explicitly as development/testing variables — do not remove them, but add a comment directing production validators to the keystore path instead - In
Documentation/public/guides/andDeveloper/DEVELOPMENT_SETUP.md, wherever a guide instructs setting a raw key in.env, add a callout: "This pattern is for local development. If you are running a production validator node, use the encrypted keystore — seeDocumentation/public/guides/wallet-setup.md." - In
dincli/docker/node/README.md, add a note in the environment variables section distinguishing dev and production key management
This is a gap that currently nowhere in the documentation addresses: the existing guides assume the operator already has a wallet and knows why to keep it separate. They do not.
Write Documentation/public/guides/wallet-setup.md with the following sections:
-
Why a dedicated burner wallet, not your main address. The private key will be loaded into
dinclito sign transactions on every command. Any compromise of the machine or the keystore file exposes every asset at that address. Use an address you are comfortable treating as disposable. -
Recommended tool — OWS (Open Wallet Standard). openwallet.sh is the simplest CLI-based option: chain-agnostic, agent-friendly, generates keystores that follow open standards, and pairs naturally with
dincli's workflow. Show the minimal steps to generate a fresh wallet and export its keystore file. -
Fund the burner wallet. Direct the operator to the Optimism Sepolia faucet with the new address. Note the minimum ETH needed to stake and submit a few transactions.
-
What happens next. Cross-reference the keystore migration guide (1d) so the operator understands how the key file gets loaded by
dincliafter setup.
This guide should be linked from Documentation/public/guides/ipfs.md and Developer/DEVELOPMENT_SETUP.md as a prerequisite step.
Do not remove any existing input paths. All of them — positional key argument, --key-file, --account <n> via .env, interactive getpass, and _get_password from .env — serve real use cases and must be preserved. The work here is to add better options and improve the weakest spots, not to restrict what operators can do.
The real problem to solve is that dincli currently holds one active account at a time (WALLET_FILE is a single file), and the existing paths for multi-account access (ETH_PRIVATE_KEY_<n> in .env) work well for local testing but have no secure production equivalent. The task is to design and implement multi-account support that works conveniently for everyone — developers and production validators alike — with security that scales to what each user actually needs.
Known issue: _cache_password_if_needed
This function caches the wallet decryption password as plaintext in a file under CONFIG_DIR so users don't have to re-enter it on every command. This is a real security issue (the cached plaintext file is readable by any process with filesystem access) but also a real convenience feature — operators running many sequential commands would otherwise face a password prompt on each one.
The improvement here is not to remove the cache but to move it from disk to memory. A short-lived in-memory TTL cache (e.g. a module-level dict with an expiry timestamp, cleared on process exit) gives the same convenience without writing anything to disk. Explore this as the target design: password prompted once per session, held in process memory for a configurable TTL (e.g. 15 minutes), never written to a file.
What to add:
--keystore <path>option — accept a standard Ethereum JSON keystore file as input (already-encrypted, e.g. generated by OWS oreth-account). The current code already outputs this format viaAccount.encrypt(); accepting it as input closes the loop for validators who manage their keys externally. Prompt for the decryption passphrase viagetpass.- Named multi-account keystore — extend
WALLET_FILEto a named store: multiple encrypted keystores underCONFIG_DIR(e.g.wallet_aggregator.json,wallet_auditor.json), selectable by name via--account <name>. This mirrors the convenience ofETH_PRIVATE_KEY_<n>for dev, but with encryption at rest for production. Adincli system list-accountscommand to show what's registered would complete the UX.
OWS integration exploration:
Alongside the above, assess whether dincli can connect directly to OWS (Open Wallet Standard) as an alternative account backend for operators who want to manage all their keys in one place. OWS is designed as a local agent-accessible wallet layer — if it exposes a programmatic interface (CLI subprocess, local socket, or SDK), dincli could query it for a named account and request a signature without ever holding the raw key itself. This is relevant specifically for multi-account production use: an operator with three validator identities could manage all three in OWS and point dincli at whichever is needed.
Assess feasibility: what interface does OWS expose, can dincli enumerate accounts and request a signed transaction without handling the raw key, and what are the failure modes (OWS not running, account not found, wrong chain)? Write up your findings and a recommendation in the PR description — the outcome shapes whether named multi-keystore or OWS delegation becomes the recommended production path.
Security/convenience tiers — document in the PR and in wallet-setup.md:
| Path | Convenience | Security | Recommended for |
|---|---|---|---|
ETH_PRIVATE_KEY_<n> in .env |
High — multi-account, no prompts | Low — plaintext on disk | Local dev, automated testing |
Interactive getpass + encrypted WALLET_FILE |
Medium — prompt once, in-memory TTL cache | High — key encrypted at rest, password in memory only | Production (current best option) |
--keystore <path> (JSON keystore input) |
Medium — passphrase prompt | High — external keystore, key never re-encoded | Production validators with OWS/external key management |
| OWS delegation (if feasible) | High — named accounts, no raw key in dincli |
Highest — dincli never sees the private key |
Production validators wanting full key isolation |
Flag this PR for Umer review before merge. This is the highest-sensitivity change in the task.
Write Documentation/public/guides/keystore-migration.md:
- What changed: the old
.env/PRIVATE_KEY=pattern vs. the new encrypted keystore - How to migrate an existing key: move it into a keystore file via an
eth-accountone-liner or OWS export (show the exact command) - How to update your operator setup: which env var to replace, where the keystore path goes in
docker-compose.ymlor the operator.env - What persists across container restarts vs. what must be re-entered: the keystore file lives on the bind-mounted volume and survives restarts; the passphrase is never stored and must be entered each time
connect-walletis called
Roadmap ref: Developer/discussion/add-filecoin-support.md — "Now (P3 — can start independently)"
The document at Developer/discussion/add-filecoin-support.md lays out the strategic case for Filecoin-backed storage and evaluates the provider options — Lighthouse, Storacha/Web3.Storage, and Filebase's Filecoin tier — against DIN's architecture. It is a working document written from a protocol design perspective, not a final implementation spec. The implementation decisions — which provider's SDK feels maintainable in practice, where the existing abstraction needs adjusting, what the actual developer experience looks like — are yours to make.
This is an area where DIN is actively evolving, and the choices made here will shape how the network handles storage as it grows. We're bringing you in not just to execute a spec but to apply your judgment: if something in the discussion document doesn't hold up once you're working with the actual APIs, push back and document your reasoning. That kind of grounded input is exactly what helps DIN's technical direction stay practical.
On the blockchain framing: it's largely irrelevant here. The integration point is dincli/services/ipfs.py — a pure Python adapter layer with no contract dependencies, no CID format changes, and no Solidity involved. The storage layer happens to be Filecoin-backed rather than Filebase, but the implementation pattern is the same serverless-API-integration work from your BlinkTrip background: a new adapter class behind an existing interface.
The economic layer — per-task storage budgets, sponsored upload credentials, on-chain accounting — is Umer's domain and is being designed in P3-5.3 (fee mechanism, July). What's needed from you now is the provider adapter itself, so operators can begin using Filecoin-backed storage before the full fee model lands.
Add a Filecoin-backed provider behind the existing custom provider path in dincli/services/ipfs.py:
- Lighthouse is the recommended starting point — simpler API, fast IPFS retrieval gateway, per-account billing with no raw FIL management. Storacha/Web3.Storage is the stronger long-term fit (native UCAN delegation for sponsored uploads), but Lighthouse is the right first adapter given the scope here. If after reading the discussion document you have a different view, flag it before starting.
- Implement
upload(file_path) -> cidandretrieve(cid, dest_path)using the Lighthouse REST API - Operator configuration via env vars:
IPFS_PROVIDER=lighthouse,LIGHTHOUSE_API_KEY=<key>— follow the same pattern as the existingfilebaseprovider - Retrieval can fall back to the standard IPFS HTTP gateway; the CID is a CID regardless of which provider stored it
- No changes to any contract or CID handling code
Read Developer/discussion/add-filecoin-support.md in full before starting. The "Best Filecoin-backed providers" and "Recommended implementation sequence → Now" sections are the most relevant. If anything in the provider comparison doesn't match what you find when working with the actual SDKs, document the discrepancy — that feedback directly informs the P3-5.3 design work.
dincli/services/ipfs_lighthouse.py(or equivalent module name) implementing the adapterDocumentation/public/guides/ipfs.mdupdated with Lighthouse provider configuration steps and theLIGHTHOUSE_API_KEYenv var- Unit tests in
tests/test_ipfs_lighthouse.pycovering: provider selection from env vars, upload mock returning a CID, retrieve mock, error case when API key is missing - A brief note (inline in the PR description or a
Developer/discussion/follow-up comment) on any gaps or surprises found in the Lighthouse/Storacha API versus what the discussion document assumed — this feeds directly into the next design step
By end of Jul 3:
- Plaintext private key patterns removed or replaced in all docs and
.env.examplefiles - Burner wallet setup guide written (
Documentation/public/guides/wallet-setup.md), referencing OWS / openwallet.sh -
dincli system connect-walletsupports--keystore <path>with passphrase prompt — flagged for Umer review before merge - Keystore migration guide written (
Documentation/public/guides/keystore-migration.md) - OWS integration feasibility documented in the PR description
- Lighthouse provider adapter implemented and passing unit tests
-
Documentation/public/guides/ipfs.mdupdated with Lighthouse configuration steps - PR description note on any API gaps or surprises vs. the discussion document
- The
connect-walletkeystore implementation must be reviewed by Umer before merging. Flag the PR with a comment so it doesn't accidentally get merged before he sees it. - Do not add Python-level SIGTERM handling anywhere in this task — T0.2a is explicitly deferred to P4.
- For the OWS / openwallet.sh reference in the wallet guide: link to https://openwallet.sh/ as the recommended tool. No need to bundle OWS into the DIN codebase itself — it's an operator tool, not a framework dependency.
- For the Filecoin adapter: Lighthouse is the recommended starting point but not mandatory — if after reading the discussion document you have a stronger case for Storacha, make it in the PR and we'll align from there.