Skip to main content

Chained Accounts

CI

A thin framework to help applications and users manage multiple ethereum accounts on multiple chains.

Motivation

Blockchain applications are becoming more cross-chain and multi-chain, therefore having a need to manage multiple user accounts on different chains. Users need an easy way to configure an application to use their private keys, including specifying which EVM chains they can be used on. Applications also need easy access to user private keys while providing a way to handle them securely, rather than storing them in plain text.

Overview

Each ChainedAccount:

  • has a user-friendly name
  • can be associated with one or more EVM chains.
  • is encrypted in a local keystore using the eth_keyfile package.

Applications can easily access the keystore and search for accounts by name, EVM chain, and address.

ChainedAccount objects remain encrypted by default, and can be lazily unlocked and cached when access is needed to the private key.

Note: This package does not directly perform any encryption/decryption, but relies on the https://github.com/ethereum/eth-account package.

** USE AT YOUR OWN RISK **

Installation

pip install chained_accounts

Examples

Create an account for use on either Ethereum Mainnet or Rinkeby testnet.

Python

from chained_accounts import ChainedAccount, find_accounts

key1 = "0x57fe7105302229455bcfd58a8b531b532d7a2bb3b50e1026afa455cd332bf706"
ChainedAccount.add("my-eth-acct", [1, 4], key1, password="foo")

acc = find_accounts(chain_id=1)[0]
print(f"Address: {acc.address}")
print(f"Chains: {acc.chains}")

acc.unlock("foo")
print(f"Private key: {acc.key.hex()}")
ChainedAccount('my-eth-acct')
Address: 0xcd19cf65af3a3aea1f44a7cb0257fc7455f245f0
Chains: [1, 4]
Private key: 0x57fe7105302229455bcfd58a8b531b532d7a2bb3b50e1026afa455cd332bf706

Command Line

>> chained add my-eth-acct 0x57fe7105302229455bcfd58a8b531b532d7a2bb3b50e1026afa455cd332bf706 1 4
Enter encryption password for my-eth-acct: 
Confirm password:
Added new account my-eth-acct (address= 0xcd19cf65af3a3aea1f44a7cb0257fc7455f245f0) for use on chains (1, 4)
>> chained find
Found 1 accounts.
Account name: my-eth-acct, address: 0xcd19cf65af3a3aea1f44a7cb0257fc7455f245f0, chain IDs: [1, 4]

User Guide

All ChainedAccount features are available through Python or the Command Line Interface (CLI).

Adding a new account

The following example demonstrates adding two accounts to the keystore. The first account is for use on either ethereum mainnet or Rinkeby testnet. The second account is for use on Polygon mainnet. For a list of valid chain identifiers, see www.chainlist.org.

from chained_accounts import ChainedAccount

key = '0x57fe7105302229455bcfd58a8b531b532d7a2bb3b50e1026afa455cd332bf706'
ChainedAccount.add('my-eth-acct', chains=[1, 4], key=key, password='foo')

key = '0x7a3d4adc3b6fb4520893e9b486b67a730e0d879a421342f788dc3dc273543267'
ChainedAccount.add('my-matic-acct', chains=137, key=key, password='bar')

or, from the CLI:

>> chained add my-eth-acct 0x57fe7105302229455bcfd58a8b531b532d7a2bb3b50e1026afa455cd332bf706 1 4
Enter encryption password for my-eth-acct: 
Confirm password:
Added new account my-eth-acct (address= 0xcd19cf65af3a3aea1f44a7cb0257fc7455f245f0) for use on chains (1, 4)

>> chained add my-matic-acct 0x7a3d4adc3b6fb4520893e9b486b67a730e0d879a421342f788dc3dc273543267 137
Enter encryption password for my-matic-acct: 
Confirm password: 
Added new account my-matic-acct (address= 0xc1b6c5d803c45b8d1097d07df0c816157db6f00c) for use on chains (137,)

Getting accounts from the keystore

Accounts can be accessed by name using ChainedAccount.get(name), or can be found by searching the keystore using find_accounts(). The following example demonstrates how an application can search for a user account to use on Ethereum mainnet.

acc = find_accounts(chain_id=1)[0]
print(f"Address: {acc.address}")
print(f"Chains: {acc.chains}")
ChainedAccount('my-eth-acct')
Address: 0xcd19cf65af3a3aea1f44a7cb0257fc7455f245f0
Chains: [1, 4]

Or, from the command line (find all accounts):

>> chained find
Found 2 accounts.
Account name: my-eth-acct, address: 0xcd19cf65af3a3aea1f44a7cb0257fc7455f245f0, chain IDs: [1, 4]
Account name: my-matic-acct, address: 0xc1b6c5d803c45b8d1097d07df0c816157db6f00c, chain IDs: [137]

Accessing private keys

Note that the ChainedAccount private key remains encrypted until the account is unlocked with a password.

assert not ChainedAccount.get('my-eth-acct').is_unlocked

To unlock and access the private key:

acc = ChainedAccount.get('my-eth-acct')
acc.unlock('foo')
print(f"Private key: {acc.key.hex()}")
Private key: 0x57fe7105302229455bcfd58a8b531b532d7a2bb3b50e1026afa455cd332bf706

Development

Developer Mode Installation

pip install -e ".[dev]"

Running tests

pytest

Code checks

All code should pass the following checks prior to submitting.

ruff check src/ tests/
ruff format --check src/ tests/

Metadata

Release files for chained-accounts 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chained-accounts 0.1.0
File Size Uploaded
chained_accounts-0.1.0.tar.gz 10.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for chained-accounts 0.1.0
File Interpreter ABI Platform
chained_accounts-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 18.7 kB

Release files / chained_accounts-0.1.0.tar.gz

Download URL chained_accounts-0.1.0.tar.gz
Size 10.1 kB
Tags Source
SHA-256 checksum
How to use checksums
544355e47eee4ac4e4ffd2969da249b13d31b27697b1bce78606dcd0d5b7c16a
BLAKE2b-256 checksum
How to use checksums
abe8e8218c07ece1d21ccb21f2f0723b0ef7cf0ef6ae1968d2538ab3baa51d76
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 5, 2026.

Transparency log

Release files / chained_accounts-0.1.0-py3-none-any.whl

Download URL chained_accounts-0.1.0-py3-none-any.whl
Size 8.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e94c3119db86b867626d2a07cebac174bbe1056b5eee1be3d7d6294dc32a2850
BLAKE2b-256 checksum
How to use checksums
5a93cc4159b392a036c9a2c50265912341c0244984a5b61bf2ce12db208e393f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page