Compare commits
10 Commits
lash/docs-
...
lash/more-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68a01565c9
|
||
|
|
b5a01b28ac
|
||
|
|
926c954d6e
|
||
|
|
d24fea2d4f
|
||
|
|
d3f6d1138d
|
||
|
|
2c567cbded
|
||
|
|
28ee4f7197
|
||
|
|
eedb63212d
|
||
|
|
99cac32ced
|
||
| 7deeee2c84 |
18
CHANGELOG
18
CHANGELOG
@@ -1,16 +1,26 @@
|
||||
- 0.0.20
|
||||
* Add edit option for some long flag aliases of short flags: -a, -e, -s and -y
|
||||
- 0.0.19
|
||||
* Passphrase file option to unlock keyfile for CLI tooling
|
||||
- 0.0.18
|
||||
* Upgrade hexathon skipping buggy compact hex method
|
||||
- 0.0.17
|
||||
* Add loglevel environment variable
|
||||
- 0.0.16
|
||||
* Allow query string in query url
|
||||
- 0.0.14
|
||||
* Add option to skip ssl verification on rpc
|
||||
- 0.0.5
|
||||
* Move eth code to separate package
|
||||
- 0.0.4-unreleased
|
||||
- 0.0.4
|
||||
* Add pack tx from already signed tx struct
|
||||
* Add http auth handling for jsonrpc connections
|
||||
* Add customizable jsonrpc id generator (to allow for buggy server id handling)
|
||||
- 0.0.3-unreleased
|
||||
- 0.0.3
|
||||
* Remove erc20 module (to new external package)
|
||||
- 0.0.2-unreleased
|
||||
- 0.0.2
|
||||
*
|
||||
- 0.0.1-unreleased
|
||||
- 0.0.1
|
||||
* Add eth tx decode
|
||||
* Add eth balance query with erc20 option
|
||||
* Add eth checksum address
|
||||
|
||||
@@ -5,6 +5,7 @@ import enum
|
||||
import os
|
||||
import select
|
||||
import sys
|
||||
import re
|
||||
|
||||
# local imports
|
||||
from .base import (
|
||||
@@ -30,16 +31,31 @@ def stdin_arg():
|
||||
return v.rstrip()
|
||||
return None
|
||||
|
||||
_default_long_args = {
|
||||
'-a': '--recipient',
|
||||
'-e': '--executable-address',
|
||||
'-s': '--send',
|
||||
'-y': '--key-file',
|
||||
}
|
||||
|
||||
_default_dest = {
|
||||
'-a': 'recipient',
|
||||
'-e': 'executable_address',
|
||||
}
|
||||
|
||||
class ArgumentParser(argparse.ArgumentParser):
|
||||
"""Extends the standard library argument parser to construct arguments based on configuration flags.
|
||||
|
||||
The extended class is set up to facilitate piping of single positional arguments via stdin. For this reason, positional arguments should be added using the locally defined add_positional method instead of add_argument.
|
||||
|
||||
Long flag aliases for short flags are editable using the arg_long argument. Editing a non-existent short flag will produce no error and have no effect. Adding a long flag for a short flag that does not have an alias will also not have effect.
|
||||
|
||||
Calls chainlib.cli.args.ArgumentParser.process_flags with arg_flags and env arguments, see the method's documentation for further details.
|
||||
|
||||
:param arg_flags: Argument flag bit vector to generate configuration values for.
|
||||
:type arg_flags: chainlib.cli.Flag
|
||||
:param arg_long: Change long flag alias for given short flags. Example value: {'-a': '--addr', '-e': '--contract'}
|
||||
:type arg_long: dict
|
||||
:param env: Environment variables
|
||||
:type env: dict
|
||||
:param usage: Usage string, passed to parent
|
||||
@@ -50,11 +66,23 @@ class ArgumentParser(argparse.ArgumentParser):
|
||||
:type epilog: str
|
||||
"""
|
||||
|
||||
def __init__(self, arg_flags=0x0f, env=os.environ, usage=None, description=None, epilog=None, *args, **kwargs):
|
||||
def __init__(self, arg_flags=0x0f, arg_long={}, env=os.environ, usage=None, description=None, epilog=None, *args, **kwargs):
|
||||
super(ArgumentParser, self).__init__(usage=usage, description=description, epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter, *args, **kwargs)
|
||||
|
||||
self.process_flags(arg_flags, env)
|
||||
self.pos_args = []
|
||||
self.long_args = _default_long_args
|
||||
self.arg_dest = _default_dest
|
||||
|
||||
re_long = r'^--[a-z\-]+$'
|
||||
for k in arg_long.keys():
|
||||
if re.match(re_long, arg_long[k]) == None:
|
||||
raise ValueError('invalid long arg {}'.format(arg_long[k]))
|
||||
self.long_args[k] = arg_long[k]
|
||||
dest = arg_long[k][2:]
|
||||
dest = dest.replace('-', '_')
|
||||
self.arg_dest[k] = dest
|
||||
|
||||
self.process_flags(arg_flags, env)
|
||||
|
||||
|
||||
def add_positional(self, name, type=str, help=None, append=False, required=True):
|
||||
@@ -96,7 +124,6 @@ class ArgumentParser(argparse.ArgumentParser):
|
||||
for arg in self.pos_args:
|
||||
if arg[3]:
|
||||
if arg[4]:
|
||||
logg.debug('argumen')
|
||||
self.add_argument(arg[0], nargs='+', type=arg[1], help=arg[2])
|
||||
else:
|
||||
self.add_argument(arg[0], type=arg[1], help=arg[2])
|
||||
@@ -139,6 +166,7 @@ class ArgumentParser(argparse.ArgumentParser):
|
||||
:type env: dict
|
||||
"""
|
||||
if arg_flags & Flag.VERBOSE:
|
||||
self.add_argument('--no-logs', dest='no_logs',action='store_true', help='Turn off all logging')
|
||||
self.add_argument('-v', action='store_true', help='Be verbose')
|
||||
self.add_argument('-vv', action='store_true', help='Be more verbose')
|
||||
if arg_flags & Flag.CONFIG:
|
||||
@@ -164,9 +192,10 @@ class ArgumentParser(argparse.ArgumentParser):
|
||||
if arg_flags & Flag.SEQ:
|
||||
self.add_argument('--seq', action='store_true', help='Use sequential rpc ids')
|
||||
if arg_flags & Flag.KEY_FILE:
|
||||
self.add_argument('-y', '--key-file', dest='y', type=str, help='Keystore file to use for signing or address')
|
||||
self.add_argument('-y', self.long_args['-y'], dest='y', type=str, help='Keystore file to use for signing or address')
|
||||
self.add_argument('--passphrase-file', dest='passphrase_file', type=str, help='File containing passphrase for keystore')
|
||||
if arg_flags & Flag.SEND:
|
||||
self.add_argument('-s', '--send', dest='s', action='store_true', help='Send to network')
|
||||
self.add_argument('-s', self.long_args['-s'], dest='s', action='store_true', help='Send to network')
|
||||
if arg_flags & Flag.RAW:
|
||||
self.add_argument('--raw', action='store_true', help='Do not decode output')
|
||||
if arg_flags & (Flag.SIGN | Flag.NONCE):
|
||||
@@ -177,6 +206,6 @@ class ArgumentParser(argparse.ArgumentParser):
|
||||
if arg_flags & argflag_std_target == 0:
|
||||
arg_flags |= Flag.WALLET
|
||||
if arg_flags & Flag.EXEC:
|
||||
self.add_argument('-e', '--exectuable-address', dest='executable_address', type=str, help='contract address')
|
||||
self.add_argument('-e', self.long_args['-e'], dest=self.arg_dest['-e'], type=str, help='contract address')
|
||||
if arg_flags & Flag.WALLET:
|
||||
self.add_argument('-a', '--recipient', dest='recipient', type=str, help='recipient address')
|
||||
self.add_argument('-a', self.long_args['-a'], dest=self.arg_dest['-a'], type=str, help='recipient address')
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import stat
|
||||
|
||||
# external imports
|
||||
import confini
|
||||
@@ -102,14 +103,51 @@ class Config(confini.Config):
|
||||
:rtype: confini.Config
|
||||
:return: Processed configuation
|
||||
"""
|
||||
env_prefix = getattr(args, 'env_prefix', None)
|
||||
env_prefix_str = env_prefix
|
||||
if env_prefix_str == None:
|
||||
env_prefix_str = ''
|
||||
else:
|
||||
env_prefix_str += '_'
|
||||
|
||||
env_loglevel_key_str = env_prefix_str + 'LOGLEVEL'
|
||||
env_loglevel = os.environ.get(env_loglevel_key_str)
|
||||
|
||||
if logger == None:
|
||||
logger = logging.getLogger()
|
||||
|
||||
if arg_flags & Flag.CONFIG:
|
||||
if env_loglevel != None:
|
||||
env_loglevel = env_loglevel.lower()
|
||||
if env_loglevel == '0' or env_loglevel == 'no' or env_loglevel == 'none' or env_loglevel == 'disable' or env_loglevel == 'disabled' or env_loglevel == 'off':
|
||||
logging.disable()
|
||||
elif env_loglevel == '1' or env_loglevel == 'err' or env_loglevel == 'error':
|
||||
logger.setLevel(logging.ERROR)
|
||||
elif env_loglevel == '2' or env_loglevel == 'warning' or env_loglevel == 'warn':
|
||||
logger.setLevel(logging.WARNING)
|
||||
elif env_loglevel == '3' or env_loglevel == 'info':
|
||||
logger.setLevel(logging.INFO)
|
||||
else:
|
||||
valid_level = False
|
||||
try:
|
||||
num_loglevel = int(env_loglevel)
|
||||
valid_level = True
|
||||
except:
|
||||
if env_loglevel == 'debug':
|
||||
valid_level = True
|
||||
|
||||
if not valid_level:
|
||||
raise ValueError('unknown loglevel {} set in environment variable {}'.format(env_loglevel, env_loglevel_key_str))
|
||||
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
if arg_flags & Flag.VERBOSE:
|
||||
if args.vv:
|
||||
logger.setLevel(logging.DEBUG)
|
||||
elif args.v:
|
||||
logger.setLevel(logging.INFO)
|
||||
if args.no_logs:
|
||||
logging.disable()
|
||||
|
||||
override_config_dirs = []
|
||||
config_dir = [cls.default_base_config_dir]
|
||||
@@ -160,7 +198,6 @@ class Config(confini.Config):
|
||||
# default_config_dir = default_parent_config_dir
|
||||
# config_dir = default_config_dir
|
||||
# override_config_dirs = []
|
||||
env_prefix = getattr(args, 'env_prefix', None)
|
||||
|
||||
config = confini.Config(config_dir, env_prefix=env_prefix, override_dirs=override_config_dirs)
|
||||
config.process()
|
||||
@@ -176,7 +213,15 @@ class Config(confini.Config):
|
||||
args_override['CHAIN_SPEC'] = getattr(args, 'i')
|
||||
if arg_flags & Flag.KEY_FILE:
|
||||
args_override['WALLET_KEY_FILE'] = getattr(args, 'y')
|
||||
|
||||
fp = getattr(args, 'passphrase_file')
|
||||
if fp != None:
|
||||
st = os.stat(fp)
|
||||
if stat.S_IMODE(st.st_mode) & (stat.S_IRWXO | stat.S_IRWXG) > 0:
|
||||
logg.warning('others than owner have access on password file')
|
||||
f = open(fp, 'r')
|
||||
args_override['WALLET_PASSPHRASE'] = f.read()
|
||||
f.close()
|
||||
config.censor('PASSPHRASE', 'WALLET')
|
||||
config.dict_override(args_override, 'cli args')
|
||||
|
||||
if arg_flags & Flag.PROVIDER:
|
||||
|
||||
@@ -133,6 +133,9 @@ class RPCConnection:
|
||||
self.location = os.path.join('{}://'.format(url_parsed.scheme), location)
|
||||
self.location = urljoin(self.location, url_parsed.path)
|
||||
|
||||
if url_parsed.query != '':
|
||||
self.location = urljoin(self.location, '?' + url_parsed.query)
|
||||
|
||||
logg.debug('parsed url {} to location {}'.format(url, self.location))
|
||||
|
||||
|
||||
@@ -319,7 +322,7 @@ class JSONRPCHTTPConnection(HTTPConnection):
|
||||
)
|
||||
ho = build_opener(handler)
|
||||
install_opener(ho)
|
||||
|
||||
|
||||
try:
|
||||
r = urlopen(
|
||||
req,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
funga~=0.5.1
|
||||
pysha3==1.0.2
|
||||
hexathon~=0.1.0
|
||||
hexathon~=0.1.3
|
||||
confini~=0.5.3
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
; Config::Simple 4.59
|
||||
; Mon Nov 8 05:19:17 2021
|
||||
|
||||
[metadata]
|
||||
name=chainlib
|
||||
license=WTFPL2
|
||||
author_email=dev@holbrook.no
|
||||
description=Generic blockchain access library and tooling
|
||||
version=0.0.14
|
||||
version=0.0.20
|
||||
url=https://gitlab.com/chaintools/chainlib
|
||||
author=Louis Holbrook
|
||||
|
||||
|
||||
Reference in New Issue
Block a user