Your short one-line summary here
Project description
GNOMAN: Guardian of Safes, Master of Keys
GNOMAN is a standalone command-line toolkit for those who demand uncompromising control over digital assets. It’s the forge where wallets, safes, and keys are shaped into reliable, battle-tested tools.
Core Functions
1. Gnosis Safe Management Direct, auditable interaction with your Safe. Deploy new vaults, set thresholds, rotate owners, propose or execute transactions—all without tangled dashboards or risky browser extensions.
2. Wallet Management Generate, rotate, import, or export wallets with full HD derivation tree support. Build hidden branches, use throwaway wallets, store cold, or export JSONs. GNOMAN gives you the flexibility of hardware ecosystems while keeping you in control of the root keys.
3. Key Manager & Backup Secrets are preserved with a strict order: keyring → .env.secure → environment → prompt. Once a key is seen, it is persisted. If one layer fails, the next holds. Backups use AES-GCM encryption for resilience without plaintext leakage.
Why GNOMAN Exists
Crypto tools are often too casual (browser plugins) or too arcane (raw JSON-RPC). GNOMAN bridges the gap—terminal-native, structured, auditable, and forensic-grade. Like the gnomon of a sundial, it stands straight in chaos, casting clear lines of truth.
Features
- Full Safe control: deploy, manage owners, set thresholds.
- Wallet creation, imports, hidden derivations.
- Key persistence and secure backups.
- Interactive menus or fully scriptable flags.
- Verbose debug or silent automation modes.
Security Philosophy
No invisible storage. No silent failures. No hidden assumptions. GNOMAN enforces explicitness, persistence, and resilience—so your keys, safes, and actions remain under your control.
Quick start (first run)
- After making it executable, Run it
python3 gnosis.py
- Banner shows, then you’ll see the Main Menu
1) Safe Manager (Gnosis Safe)
2) Wallet Manager (HD / hidden trees)
3) Key Manager (Secrets)
4) Exit
- Secrets resolution (how prompts work)
- The tool always looks for secrets in this order: keyring ➜ .env/.env.secure ➜ prompt
- If it asks for something like
RPC_URLorOWNER_PRIVATE_KEY, it means it didn’t find it in keyring or env. When you enter it, it is persisted immediately to keyring (primary) and mirrored to .env.secure (chmod 600). Next launch, it won’t ask again unless you delete/rename the keyring entry or change service.
- Keyring “service” name
-
Whenever you use Key Manager to set/get/delete/sync a secret, you’ll be asked for a Service name. Default is
gnoman. Enter a custom service if you want to silo contexts (e.g.,prod,staging,personal). -
Internally, secrets are stored as:
(service, key) -> value. -
If you want the Safe/Wallet subsystems to load from a non-default service every time, set this env before launching:
export KEYRING_SERVICE=prod python3 gnosis.py(Or just keep using the default
gnomanservice in the prompts.)
Key Manager (Secrets)
Main Menu → 3) Key Manager
You’ll use this to seed everything so the app never nags you again.
Typical keys you’ll set:
RPC_URL– your HTTPS RPC endpointCHAIN_ID– e.g.,1for mainnet (optional; defaults to 1)GNOSIS_SAFE– your Safe address (checksummed)OWNER_PRIVATE_KEY– hex (with or without0x, both accepted)
Menu items:
- Add/Update secret: enter key name (e.g.,
RPC_URL), then value, then service (defaultgnoman). This writes to keyring and mirrors into .env.secure. - Retrieve secret: confirm what’s stored (useful to verify typos).
- Delete secret: removes from keyring for that service.
- List
.env.secure: shows a masked view of what’s mirrored locally. - Sync
.env.secure → keyring: bulk import any.env.securepairs into keyring for a chosen service.
Tip: If you ever see a prompt for a value you know is in your keyring, you either typed a different service than where it’s stored, or
KEYRING_SERVICEenv is set to a different service. Stick to one.
Safe Manager (Gnosis Safe)
Main Menu → 1) Safe Manager
On first entry, if needed the tool will prompt for:
RPC_URLGNOSIS_SAFEOWNER_PRIVATE_KEY
It writes them to keyring + .env.secure right away. If any value is invalid (bad address/PK), it prints a clear error and returns you to the Safe menu (no silent exit). All events are logged to the log file (e.g., gnoman.log).
Safe menu actions
- Show Safe info
- Displays: owners (checksummed), threshold, nonce, ETH balance.
- Good sanity check that you’re pointed at the correct Safe.
- Fund Safe with ETH
- Sends ETH from your
OWNER_PRIVATE_KEY(the EOA signer) to the Safe. - Enter an amount like
0.5. Gas is estimated + padded. EIP-1559 compatible.
- Send ERC-20 to Safe
- Prompts for token address, fetches
symbol/decimals(falls back if contract is non-standard), and sends tokens to the Safe viatransfer.
- Execute Safe transaction (execTransaction)
- Prompts for
to,value (ETH),data (0x…), andoperation (0 or 1). - Computes the exact SafeTx hash via
getTransactionHash(...). - Signs that hash with your
OWNER_PRIVATE_KEYand submitsexecTransaction. - If your Safe has threshold > 1 and you only have one sig, you’ll need to run a multi-sig collection flow (this CLI supports the single-sig immediate execution path; for multi-sig you can still use this to compute and sign then feed additional signatures by extending the packed sig flow—happy to wire that next if you want).
- Admin: Add owner
- Adds an owner, preserving the current threshold.
- Admin: Remove owner
- Removes an owner. Requires prevOwner address (Safe maintains a linked list). If you don’t know the previous, you can get it from the Safe’s
getOwners()plus on-chain linked list order. (If that’s a pain, I can expose a helper that finds the correctprevOwnerfor you.)
- Admin: Change threshold
- Sets a new
threshold(must be ≥1 and ≤ number of owners).
- Guard: Enable 24h withdrawal hold
- This uses
setGuard(guardAddress)on the Safe. - You’ll be prompted for the DelayGuard address (the contract you deploy—see below). The address is persisted as
SAFE_DELAY_GUARD. - After enabling, any execTransaction will be forced to queue for 24 hours before it can succeed.
- Guard: Disable withdrawal hold
- Calls
setGuard(0x0). Removes the delay enforcement.
- Guard: Show guard status
- Reads
getGuard()and prints the active guard address (or “none”).
- Back
- Returns to the main menu.
How the 24-hour hold actually behaves
- With the guard active, the first attempt to execute any Safe transaction will revert with a message like
DelayGuard: queued, try again after 24h. That revert is expected — it’s how the guard records/queues the tx hash & timestamp. - Re-submit the exact same transaction (same calldata, same to/value/data/op & gas fields) after 24 hours. It will then execute normally.
- If you alter anything (e.g., value or calldata), it’s a different hash and will be queued again.
Pro move: Use the Safe menu option (4) to build the tx. If you’ll re-run it after 24h, keep the exact same parameters.
Deploying the DelayGuard
If you used the provided DelayGuard.sol:
- Deploy it with the Safe address in the constructor (via Remix/Foundry/Hardhat).
- Take the deployed address and enable it using menu item 8.
- If you later want to switch back to instant withdrawals, disable with 9.
Wallet Manager (HD / Hidden trees)
Main Menu → 2) Wallet Manager
The wallet subsystem is local-first and supports both private key and mnemonic (BIP-39) flows. It doesn’t co-mingle with the Safe — different worlds, clean separation.
Storage model
- Encrypted store:
wallets.enc(AES-GCM). - On start, it asks for Master password to decrypt (or creates a new store).
- Inside the store, each wallet entry can contain either a private key or a mnemonic + derivation path.
- You may optionally store mnemonic in keyring as well (prompted).
Menus
-
Import mnemonic (default acct 0)
- Paste your seed phrase.
- It derives account 0 at
m/44'/60'/0'/0/0and prints that address. - You can also choose to save the mnemonic to keyring (recommended if you want the Tool to auto-use it later without re-typing the master password).
-
Scan first N accounts
- Looks at
m/44'/60'/0'/0/0 .. m/44'/60'/0'/0/(N-1)and prints addresses. - This is how you find “that address I used years ago” without needing to remember the index.
- Looks at
-
Derive specific path
- Enter any path (e.g.,
m/44'/60'/0'/0/7, or hidden tree likem/44'/60'/1337'/9/0). - It shows the address for that path.
- The concept of a “hidden tree” is just agreeing on a non-standard account branch. This menu lets you derive them all day without users needing to know the theory — they just paste a path string and get an address.
- Enter any path (e.g.,
-
Export discovered addresses to JSON
- Writes
hd_export.jsonwith every path/address you scanned (plus labels if you added any). Great for audits or migrations.
- Writes
-
Back
TIP: If you imported a mnemonic elsewhere and ended up on, say, path
/0/1instead of/0/0, that’s totally normal. Many wallets choose different defaults. Use Scan to locate the right one, or Derive to hit a specific path. Once found, label it in your system and use it consistently.
Example end-to-end flows
A) Seed everything once so it never prompts again
-
Main → Key Manager → Add/Update:
RPC_URL = https://your.providerGNOSIS_SAFE = 0xYourSafe...OWNER_PRIVATE_KEY = <hex>(with or without0x)- (Optional)
CHAIN_ID = 1
-
Back to Main → Safe Manager → 1) Show Safe info You should see owners/threshold/nonce/balance immediately.
B) Turn on 24-hour hold
- Deploy
DelayGuard.solwith your Safe’s address. - Safe Manager → 8) Guard: Enable → paste guard address. The guard is now active.
- Try any Safe tx (e.g., fund a contract from Safe): first attempt reverts with “queued”.
- Re-submit the same tx after 24 hours → it executes.
C) Import a mnemonic and locate a known address
- Wallet Manager → 1) Import mnemonic → paste phrase.
- Choose whether to store mnemonic in keyring.
- Wallet Manager → 2) Scan first N → try N=20.
- Find the address you recognize.
- (Optional) Derive a specific path to jump directly.
Troubleshooting
-
“It’s asking for RPC_URL again.” You likely have secrets in a different keyring service than you’re using now.
- Check with Key Manager → Retrieve secret → Service name =
gnoman(or the one you used). - Or set
export KEYRING_SERVICE=that_servicebefore running. - The tool always prefers keyring; if nothing found there, it checks
.env/.env.secure; if nothing, it prompts.
- Check with Key Manager → Retrieve secret → Service name =
-
“It exited after I typed a secret.” The current build does not exit on successful secret entry. If you see an exit:
- You probably hit an invalid address (non-checksummed/short) or invalid private key; the tool logs the precise reason and returns to menu.
- Check the log file in your working directory (e.g.,
gnoman.log). Errors include stack context and the function that failed.
-
“Guard enabled, but tx still executes instantly.”
- Ensure the Safe’s guard shows your guard address (Safe Manager → 10).
- Ensure your guard was deployed with your Safe address in its constructor.
- You must retry the same tx after 24 hours — first attempt always reverts to queue it.
-
“Remove owner asks for prevOwner — what is that?” Gnosis Safe keeps a linked list of owners.
prevOwneris the address that comes “before” the one you’re removing in that list. If you don’t know it, I can add a helper to find it for you programmatically.
Security tips (the “don’t burn yourself” section)
- Owner private key is hot in this CLI. Use minimal balances on the EOA — keep the bulk of assets in the Safe.
- When enabling the guard, make sure you don’t lock yourself out of urgent actions. You can always disable the guard (with current threshold/owners), but the 24-hour delay will apply to that call, too, once queued. Plan signers accordingly.
.env.secureis permissioned600, but it’s still a file. Keyring is your primary secret store.
Where to go next
You’re fully armed now:
- Keyring primed,
.env.securemirrored, no recurrent prompts. - Safe Manager can fund, send tokens, execute tx, manage owners/threshold, and toggle the 24h guard.
- Wallet Manager handles HD derivations, “hidden tree” paths, imports/exports, and encrypted local storage.
Got it — here’s a “License” section you can drop into your README, docs, or site. It points directly to your LICENSE.md (the terms you wrote) and LICENSEE.md (the roster or registry of who actually holds signed paper licenses). It keeps the same weighty GNOMAN vibe:
License
GNOMAN is proprietary software. No person, entity, or organization may use, copy, or execute GNOMAN without an original paper license signed in ink by the Licensor.
- 📜 Full License Terms — the complete GNOMAN License Agreement.
- 🖋 Licensed Parties — current holders of license get this.
Electronic signatures, receipts, or downloads do not constitute a license. If your name does not appear in the LICENSEE.md registry, you have no rights to GNOMAN.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gnoman_cli-0.1.3.tar.gz.
File metadata
- Download URL: gnoman_cli-0.1.3.tar.gz
- Upload date:
- Size: 27.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b439b44d975da7b2ae2975091057879a0f37cb1b527977b4d859d6931f6e1762
|
|
| MD5 |
b5226927cd142c29e9f92ed82c684b34
|
|
| BLAKE2b-256 |
cce2de7e2b3290f24b848b07a2af03e24e4e2b6821cc7ceb7590fc8cf1393a18
|
File details
Details for the file gnoman_cli-0.1.3-py3-none-any.whl.
File metadata
- Download URL: gnoman_cli-0.1.3-py3-none-any.whl
- Upload date:
- Size: 22.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e6e72fd0dd11bc7ae3bd9130d7c6357eea362e601f07a784961dcd67e1b79288
|
|
| MD5 |
ef4bbbcff010ad6b5d8e3059be9b7d4d
|
|
| BLAKE2b-256 |
87a58a53a86a8dfee496bb1dc386129648955bff4e20fda6bd3ee72010d4ac5f
|