Skip to content

Commit

Permalink
Expand xbrnetwork cli (#1468)
Browse files Browse the repository at this point in the history
* expand / polish xbr network cli

* polish and bump to dev version
  • Loading branch information
oberstet committed Mar 1, 2021
1 parent 9ca21af commit 9ff8723
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 53 deletions.
2 changes: 1 addition & 1 deletion autobahn/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@
#
###############################################################################

__version__ = '21.2.2'
__version__ = '21.3.1.dev1'
25 changes: 16 additions & 9 deletions autobahn/xbr/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,10 +326,13 @@ async def _do_get_member(self, member_adr):
}
member_data['level'] = MEMBER_LEVEL_TO_STR.get(member_level, None)

self.log.info('Member found:\n\n{member_data}\n', member_data=pformat(member_data))
self.log.info('Member {member_oid} found for address 0x{member_adr} - current member level {member_level}',
member_level=hlval(member_data['level']),
member_oid=hlid(member_data['oid']),
member_adr=hlval(member_data['address']))
else:
self.log.warn('Address 0x{member_adr} is not a member in the XBR network',
member_adr=binascii.b2a_hex(member_adr).decode())
member_adr=hlval(binascii.b2a_hex(member_adr).decode()))

async def _do_get_actor(self, market_oid, actor_adr):
is_member = await self.call('xbr.network.is_member', actor_adr)
Expand Down Expand Up @@ -460,8 +463,9 @@ async def _do_onboard_member_verify(self, vaction_oid, vaction_code):
assert 'created' in result and type(result['created']) == int and result['created'] > 0

member_oid = result['member_oid']
self.log.info('SUCCESS! New XBR Member onboarded: member_oid={member_oid}, result=\n{result}',
member_oid=uuid.UUID(bytes=member_oid), result=pformat(result))
self.log.info('SUCCESS! New XBR Member onboarded: member_oid={member_oid}, transaction={transaction}',
member_oid=hlid(uuid.UUID(bytes=member_oid)),
transaction=hlval('0x' + binascii.b2a_hex(result['transaction']).decode()))

async def _do_create_market(self, member_oid, market_oid, marketmaker, title=None, label=None, homepage=None,
provider_security=0, consumer_security=0, market_fee=0):
Expand Down Expand Up @@ -1152,7 +1156,8 @@ def _main():
sys.exit(0)

# read or create a user profile
profile = load_or_create_profile()
profile = load_or_create_profile(default_url=args.url, default_realm=args.realm,
default_username=args.username, default_email=args.email)

# only start txaio logging after above, which runs click (interactively)
if args.debug:
Expand All @@ -1171,10 +1176,12 @@ def _main():

# allow to override, and add more arguments from the command line
'command': args.command,
'ethkey': binascii.a2b_hex(args.ethkey[2:]) if args.ethkey else None,
'cskey': binascii.a2b_hex(args.cskey[2:]) if args.cskey else None,
'username': args.username,
'email': args.email,

'ethkey': profile.ethkey,
'cskey': profile.cskey,

'market': uuid.UUID(args.market) if args.market else None,
'market_title': args.market_title,
'market_label': args.market_label,
Expand All @@ -1191,11 +1198,11 @@ def _main():
'delegate': binascii.a2b_hex(args.delegate[2:]) if args.delegate else None,
'amount': args.amount or 0,
}
runner = ApplicationRunner(url=args.url, realm=args.realm, extra=extra, serializers=[CBORSerializer()])
runner = ApplicationRunner(url=profile.network_url, realm=profile.network_realm, extra=extra, serializers=[CBORSerializer()])

try:
log.info('Connecting to "{url}" {realm} ..',
url=hlval(args.url), realm=('at realm "' + hlval(args.realm) + '"' if args.realm else ''))
url=hlval(profile.network_url), realm=('at realm "' + hlval(profile.network_realm) + '"' if profile.network_realm else ''))
runner.run(Client, auto_reconnect=False)
except Exception as e:
print(e)
Expand Down
108 changes: 65 additions & 43 deletions autobahn/xbr/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ def __init__(self,
name=None,
ethkey=None,
cskey=None,
username=None,
email=None,
network_url=None,
network_realm=None,
market_url=None,
market_realm=None,
infura_url=None,
Expand All @@ -75,6 +79,10 @@ def __init__(self,
self.name = name
self.ethkey = ethkey
self.cskey = cskey
self.username = username
self.email = email
self.network_url = network_url
self.network_realm = network_realm
self.market_url = market_url
self.market_realm = market_realm
self.infura_url = infura_url
Expand All @@ -86,21 +94,33 @@ def __init__(self,
def parse(path, name, items):
ethkey = None
cskey = None
username = None
email = None
network_url = None
network_realm = None
market_url = None
market_realm = None
infura_network = None
infura_key = None
infura_secret = None
infura_url = None
for k, v in items:
if k == 'market_url':
if k == 'network_url':
network_url = str(v)
elif k == 'network_realm':
network_realm = str(v)
elif k == 'market_url':
market_url = str(v)
elif k == 'market_realm':
market_realm = str(v)
elif k == 'ethkey':
ethkey = binascii.a2b_hex(v[2:])
elif k == 'cskey':
cskey = binascii.a2b_hex(v[2:])
elif k == 'username':
username = str(v)
elif k == 'email':
email = str(v)
elif k == 'infura_network':
infura_network = str(v)
elif k == 'infura_key':
Expand All @@ -111,9 +131,10 @@ def parse(path, name, items):
infura_url = str(v)
else:
# skip unknown attribute
Profile.log.warn('unprocessed config attribute "{}"'.format(k))
print('unprocessed config attribute "{}"'.format(k))

return Profile(path, name, ethkey, cskey, market_url, market_realm, infura_url, infura_network, infura_key, infura_secret)
return Profile(path, name, ethkey, cskey, username, email, network_url, network_realm, market_url, market_realm,
infura_url, infura_network, infura_key, infura_secret)


class UserConfig(object):
Expand Down Expand Up @@ -180,11 +201,11 @@ def convert(self, value, param, ctx):
return value


def prompt_for_wamp_url(msg):
def prompt_for_wamp_url(msg, default=None):
"""
Prompt user for WAMP transport URL (eg "wss://planet.xbr.network/ws").
"""
value = click.prompt(msg, type=WampUrl())
value = click.prompt(msg, type=WampUrl(), default=default)
return value


Expand Down Expand Up @@ -232,7 +253,10 @@ def __init__(self, key_len):
def convert(self, value, param, ctx):
try:
value = hexstr_if_str(to_hex, value)
key = binascii.a2b_hex(value[2:])
if value[:2] in ['0x', '\\x']:
key = binascii.a2b_hex(value[2:])
else:
key = binascii.a2b_hex(value)
if len(key) != self._key_len:
raise ValueError('key length must be {} bytes, but was {} bytes'.format(self._key_len, len(key)))
except Exception as e:
Expand All @@ -241,38 +265,50 @@ def convert(self, value, param, ctx):
return value


def prompt_for_key(msg, key_len):
def prompt_for_key(msg, key_len, default=None):
"""
Prompt user for a binary key of given length (in HEX).
"""
value = click.prompt(msg, type=PrivateKey(key_len))
value = click.prompt(msg, type=PrivateKey(key_len), default=default)
return value


# default configuration stored in $HOME/.xbrnetwork/config.ini
_DEFAULT_CONFIG = """[default]
# username used with this profile
username={username}
# user private Ethereum key
ethkey={ethkey}
# user email used with the profile (e.g. for verification emails)
email={email}
# user private WAMP client key
cskey={cskey}
# XBR network node used as a directory server and gateway to XBR smart contracts
network_url={network_url}
# default XBR market URL to connect to
market_url={market_url}
market_realm={market_realm}
# WAMP realm on network node, usually "xbrnetwork"
network_realm={network_realm}
# user private WAMP-cryptosign key (for client authentication)
cskey={cskey}
# Infura blockchain gateway configuration
infura_url={infura_url}
infura_network={infura_network}
infura_key={infura_key}
infura_secret={infura_secret}
# user private Ethereum key (for signing transactions and e2e data encryption)
ethkey={ethkey}
"""

# # default XBR market URL to connect to
# market_url={market_url}
# market_realm={market_realm}
# # Infura blockchain gateway configuration
# infura_url={infura_url}
# infura_network={infura_network}
# infura_key={infura_key}
# infura_secret={infura_secret}


def load_or_create_profile(dotdir=None, profile=None):
def load_or_create_profile(dotdir=None, profile=None, default_url=None, default_realm=None, default_email=None, default_username=None):
dotdir = dotdir or '~/.xbrnetwork'
profile = profile or 'default'
default_url = default_url or 'wss://planet.xbr.network/ws'
default_realm = default_realm or 'xbrnetwork'

config_dir = os.path.expanduser(dotdir)
if not os.path.isdir(config_dir):
Expand All @@ -283,28 +319,14 @@ def load_or_create_profile(dotdir=None, profile=None):
if not os.path.isfile(config_path):
click.echo('creating new user profile "{}"'.format(style_ok(profile)))
with open(config_path, 'w') as f:
market_url = prompt_for_wamp_url('enter a XBR data market URL')
market_realm = click.prompt('enter the WAMP realm of the XBR data market', type=str)
ethkey = prompt_for_key('your private Etherum key', os.urandom(32))
cskey = prompt_for_key('your private WAMP client key', os.urandom(32))

# infura_url=https://rinkeby.infura.io/v3/40c6...
# infura_network=rinkeby
# infura_key=40c6...
# infura_secret=5511...
infura_network = click.prompt('enter Ethereum network to use', type=str, default='')
if infura_network:
infura_url = click.prompt('enter Infura gateway URL', type=str)
infura_key = click.prompt('your Infura gateway key', type=str)
infura_secret = click.prompt('your Infura gateway secret', type=str)
else:
infura_url = ''
infura_key = ''
infura_secret = ''

f.write(_DEFAULT_CONFIG.format(market_url=market_url, market_realm=market_realm, ethkey=ethkey,
cskey=cskey, infura_url=infura_url, infura_network=infura_network,
infura_key=infura_key, infura_secret=infura_secret))
network_url = prompt_for_wamp_url('enter the WAMP router URL of the network directory node', default=default_url)
network_realm = click.prompt('enter the WAMP realm to join on the network directory node', type=str, default=default_realm)
cskey = prompt_for_key('your private WAMP client key', 32, default='0x' + binascii.b2a_hex(os.urandom(32)).decode())
ethkey = prompt_for_key('your private Etherum key', 32, default='0x' + binascii.b2a_hex(os.urandom(32)).decode())
email = click.prompt('user email used for with profile', type=str, default=default_email)
username = click.prompt('user name used with this profile', type=str, default=default_username)
f.write(_DEFAULT_CONFIG.format(network_url=network_url, network_realm=network_realm, ethkey=ethkey,
cskey=cskey, email=email, username=username))
click.echo('created new local user configuration {}'.format(style_ok(config_path)))

config_obj = UserConfig(config_path)
Expand Down

0 comments on commit 9ff8723

Please sign in to comment.