Skip to main content

Balsnap

A light-weight python library that help take balance snapshots of multiple tokens and accounts at once.

Features:

  • Light-weight: less than 200 lines of code.
  • Easy to use and modify: delivered with documentations.
  • Fast: using multicall to reduce JSON RPC requests.

Any suggestion or possible improvement on this project is welcomed and appreciated! You can create a issue to contact me!

Installation

Pypi

pip install balsnap

Build from source

git clone https://github.com/Soptq/balsnap.git
pip install -e balsnap

Quick Start

Simple example

import os
from brownie import network
from brownie.network.account import Account
from brownie.network.contract import Contract
from balsnap import SnapshotAccount, BalSnap

# Constant
MULTICALL2_ADDRESS = "0x5ba1e12693dc8f9c48aad8770482f4739beed696"
WEB3_INFURA_PROJECT_ID = "YOUR_INFURA_ID"
ETHERSCAN_TOKEN = "YOUR_ETHERSCAN_TOKEN"

# Set up the brownie network
os.environ["ETHERSCAN_TOKEN"] = ETHERSCAN_TOKEN
os.environ["WEB3_INFURA_PROJECT_ID"] = WEB3_INFURA_PROJECT_ID
network.connect('mainnet')  # ATTENTION: here is mainnet!

# Initialize an Account() instance by providing an address
account = Account('0xF5D6849f0d1D5E84b047F157990cF016c046a433')
# Or just an address
# account = '0xF5D6849f0d1D5E84b047F157990cF016c046a433'

# Initialize an Contract() instance by providing an address
contract = Contract.from_explorer("0x6b175474e89094c44da98b954eedeac495271d0f")  # DAI
# Or just an address as well
# contract = "0x6b175474e89094c44da98b954eedeac495271d0f"

# Build account-contract pair
snapshot_account = SnapshotAccount(account, contract)

# Initialize BalSnap()
balsnap = BalSnap(multicall2_address=MULTICALL2_ADDRESS)
# Add pair
balsnap.add_snapshot_account(snapshot_account)
# Take snapshot
balsnap.snapshot()
# Visualize the result
balsnap.print_table()

# ... YOUR TRANSACTION

# Take another snapshot
balsnap.snapshot()
# Visualize the result
balsnap.print_table()

output:

+---------------+--------------------+------------------+---------------------+
|    Account    |      Contract      |     Balance      |         Time        |
+---------------+--------------------+------------------+---------------------+
| 0xF5D6...a433 | DAI(0x6B17...1d0F) | 909.082000603966 | 2021-08-09 22:19:44 |
+---------------+--------------------+------------------+---------------------+

+---------------+--------------------+------------------+---------------------+
|    Account    |      Contract      |     Balance      |         Time        |
+---------------+--------------------+------------------+---------------------+
| 0xF5D6...a433 | DAI(0x6B17...1d0F) | 999.082000603966 | 2021-08-09 23:14:11 |
+---------------+--------------------+------------------+---------------------+

Take multiple snapshots at once

import os
from brownie import network

from balsnap import BalSnap, create_snapshot_accounts

# Constant
MULTICALL2_ADDRESS = "0x5ba1e12693dc8f9c48aad8770482f4739beed696"
WEB3_INFURA_PROJECT_ID = "YOUR_INFURA_ID"
ETHERSCAN_TOKEN = "YOUR_ETHERSCAN_TOKEN"

# Set up the brownie network
os.environ["ETHERSCAN_TOKEN"] = ETHERSCAN_TOKEN
os.environ["WEB3_INFURA_PROJECT_ID"] = WEB3_INFURA_PROJECT_ID
network.connect('mainnet')  # ATTENTION: here is mainnet!

account_1 = "0xF5D6849f0d1D5E84b047F157990cF016c046a433"
account_2 = '0x43CC25B1fB6435d8d893fCf308de5C300a568BE2'

contract_1 = "0x6b175474e89094c44da98b954eedeac495271d0f"  # DAI
contract_2 = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"  # USDC

# create_snapshot_accounts() method will perform cartesian product on accounts
# and contracts and return a SnapshotAccount List. You can only manually create
# this list simplying by instializing SnapshotAccount instance and appending it
# to a list.
snapshot_accounts = create_snapshot_accounts([account_1, account_2],
                                             [contract_1, contract_2])

balsnap = BalSnap(multicall2_address=MULTICALL2_ADDRESS)
balsnap.add_snapshot_accounts(snapshot_accounts)
balsnap.snapshot()
balsnap.print_table()

output:

+---------------+---------------------+-------------------+---------------------+
|    Account    |       Contract      |      Balance      |         Time        |
+---------------+---------------------+-------------------+---------------------+
| 0xF5D6...a433 |  DAI(0x6B17...1d0F) |  909.082000603966 | 2021-08-09 22:26:28 |
| 0xF5D6...a433 | USDC(0xA0b8...eB48) |     45.334263     | 2021-08-09 22:26:29 |
| 0x43CC...8BE2 |  DAI(0x6B17...1d0F) | 3126.039500865128 | 2021-08-09 22:26:28 |
| 0x43CC...8BE2 | USDC(0xA0b8...eB48) |    87564.905951   | 2021-08-09 22:26:29 |
+---------------+---------------------+-------------------+---------------------+

Filter

You can filter some account addresses and contract address when visualizing.

balsnap.print_table(account_address_filtered="0x43CC25B1fB6435d8d893fCf308de5C300a568BE2")

output:

+---------------+---------------------+-------------------+---------------------+
|    Account    |       Contract      |      Balance      |         Time        |
+---------------+---------------------+-------------------+---------------------+
| 0xF5D6...a433 |  DAI(0x6B17...1d0F) |  909.082000603966 | 2021-08-09 22:26:28 |
| 0xF5D6...a433 | USDC(0xA0b8...eB48) |     45.334263     | 2021-08-09 22:26:29 |
+---------------+---------------------+-------------------+---------------------+

Metadata

Release files for balsnap 0.3.1

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

Source distribution (sdist)

Source distribution for balsnap 0.3.1
File Size Uploaded Provenance Actions
balsnap-0.3.1.tar.gz 7.0 kB Without provenance Details for balsnap-0.3.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for balsnap 0.3.1
File Interpreter ABI Platform Actions
balsnap-0.3.1-py3-none-any.whl Python 3 none any Details for balsnap-0.3.1-py3-none-any.whl

Total release size: 13.5 kB

Release files / balsnap-0.3.1.tar.gz

Download URL balsnap-0.3.1.tar.gz
Size 7.0 kB
Tags Source
SHA-256 checksum
How to use checksums
eddd07acf8201f9f4fc72e10d8b86cdcfd42257da9d6cecdfe80faf40c201541
BLAKE2b-256 checksum
How to use checksums
365ee06da2f10c855d08b44b9a7d720bca1f6b2772214e76513bc05efab84e60
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/4.6.3 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.9.6

Release files / balsnap-0.3.1-py3-none-any.whl

Download URL balsnap-0.3.1-py3-none-any.whl
Size 6.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
af628fc1d896e6f8ea96f70b755f262530dd2b19dd999de2f7a394343015ad44
BLAKE2b-256 checksum
How to use checksums
7e5d4b12055c7fd23a8dcdaad13bce5ca314f971a266cc23f81d59c6535be05b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/4.6.3 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.9.6

Security for balsnap 0.3.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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