Skip to content

Instantly share code, notes, and snippets.

@rhazberries
Last active August 14, 2020 13:53
Show Gist options
  • Select an option

  • Save rhazberries/ce98bb87eb3a0f86953078dc06664269 to your computer and use it in GitHub Desktop.

Select an option

Save rhazberries/ce98bb87eb3a0f86953078dc06664269 to your computer and use it in GitHub Desktop.
Get Harmony wallet balance at specified time

Get Balance at Specified Time

Requirements

  • Python 3.6
  • Pyhmy (Harmony Python sdk)

Install Harmony Python sdk

pip3 install pyhmy

Example

python3 get_balance_at_time.py -a [ADDRESS] -t [TIME]
python3 get_balance_at_time.py -a one1fdtcrkpkhm2ppnu05zmddgqvledqh7g6r2tgdy -t "01 01 2020 00:00:00"

[TIME] must follow the specified format "MM DD YYYY HH:MM:SS" (including quotes) and must be the time in UTC (+0000)

To use with Testnet:

python3 get_balance_at_time.py -a [ADDRESS] -t [TIME] -n testnet

Sample Output

$ python3 get_balance_at_time.py -a one1fdtcrkpkhm2ppnu05zmddgqvledqh7g6r2tgdy -t "01 01 2020 00:00:00"
Found block 1941880 at exact time 1577836800 on shard 0!
Could not find block at exact time 1577836800 on shard 1.
Using block right before requested time: 1857713 at 1577836797
Could not find block at exact time 1577836800 on shard 2.
Using block right before requested time: 1897249 at 1577836798
Could not find block at exact time 1577836800 on shard 3.
Using block right before requested time: 1881234 at 1577836796
Fetching account balances...
Account: one1fdtcrkpkhm2ppnu05zmddgqvledqh7g6r2tgdy
Shard 0: 0.0
Shard 1: 217127.60762872297
Shard 2: 0.0
Shard 3: 0.0

Notes

If there is no existing block at the the specified time, the script will use the first block before the time.

You can check the time conversion using a unix time converting website, like this one.

This script just reports balance at given block; it does not check transfers in and out of the account.

#!/usr/bin/env python3
import argparse
from collections import (
namedtuple
)
from datetime import (
datetime
)
from pyhmy import (
account,
blockchain
)
Block = namedtuple('Block', ['number', 'time'])
unit = 1e18
time_format = '%m %d %Y %H:%M:%S %z'
num_shards = 4 # CHANGE IF NUMBER OF SHARDS CHANGES
# Prints time in Unixtime
def find_block_at_time(time, shard, network) -> int:
endpoint = f'https://api.s{shard}.{network}.hmny.io'
start_block = Block(0, 0)
current_block = blockchain.get_block_number(endpoint = endpoint)
end_block = Block(current_block,
int(blockchain.get_block_by_number(current_block, endpoint = endpoint)['timestamp'], 16))
if time > end_block.time:
print(f'[ERROR] Requested time ({time}) greater than current block time ({end_block.time})')
exit(1)
while start_block.number + 1 != end_block.number:
mid = int((end_block.number - start_block.number) / 2) + start_block.number
mid_time = int(blockchain.get_block_by_number(mid, endpoint = endpoint)['timestamp'], 16)
if mid_time > time:
end_block = Block(mid, mid_time)
elif mid_time < time:
start_block = Block(mid, mid_time)
else:
print(f'Found block {mid} at exact time {mid_time} on shard {s}!')
return mid
print(f'Could not find block at exact time {time} on shard {s}.')
print(f'Using block right before requested time: {start_block.number} at {start_block.time}')
return mid
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-a', '--address', required = True, help = 'Wallet address')
parser.add_argument('-t', '--time', required=True, help='Time of block in UTC ("MM DD YYYY HH:MM:SS")')
parser.add_argument('-n', '--network', default = 'mainnet', choices = ['mainnet', 'testnet'], help = 'Network')
args = parser.parse_args()
if not account.is_valid_address(args.address):
print(f'[ERROR] Invalid address given: {args.address}')
exit(1)
try:
converted_time = datetime.strptime(f'{args.time} +0000', time_format)
except ValueError:
print(f'[ERROR] Invalid time format! Required: "MM DD YYYY HH:MM:SS". Given: {args.time}')
exit(1)
network_endpoint = 't' if args.network == 'mainnet' else 'b'
requested_blocks = []
for s in range(num_shards):
requested_blocks.append(find_block_at_time(int(converted_time.timestamp()), s, network_endpoint))
print('Fetching account balances...')
print(f'Account: {args.address}')
for s, b in enumerate(requested_blocks):
endpoint = f'https://api.s{s}.{network_endpoint}.hmny.io'
balance = account.get_balance_by_block(args.address, b, endpoint = endpoint)
print(f'Shard {s}: {balance / unit}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment