-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
398 additions
and
320 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,5 +5,4 @@ delegator_pays_xfer_fee=true | |
[KTTX] | ||
storage_limit=0 | ||
gas_limit=10100 | ||
base=100 | ||
|
||
base=100 |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import subprocess | ||
|
||
from util.client_utils import clear_terminal_chars | ||
|
||
|
||
class SimpleClientManager: | ||
def __init__(self, client_path, verbose=None) -> None: | ||
super().__init__() | ||
self.verbose = verbose | ||
self.client_path = client_path | ||
|
||
def send_request(self, cmd): | ||
whole_cmd = self.client_path + cmd | ||
if self.verbose: | ||
print("Command is |{}|".format(whole_cmd)) | ||
|
||
# execute client | ||
process = subprocess.Popen(whole_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
|
||
bytes = [] | ||
for b in process.stdout: | ||
bytes.append(b) | ||
|
||
process.wait() | ||
|
||
buffer = b''.join(bytes).decode('utf-8') | ||
|
||
if self.verbose: | ||
print("Answer is |{}|".format(buffer)) | ||
|
||
return buffer | ||
|
||
def sign(self, bytes, key_name): | ||
response = self.send_request(" sign bytes 0x03{} for {}".format(bytes, key_name)) | ||
|
||
response = clear_terminal_chars(response) | ||
|
||
for line in response.splitlines(): | ||
if "Signature" in line: | ||
return line.strip("Signature:").strip() | ||
|
||
raise Exception("Signature not found in response '{}'".format(response.replace('\n', ''))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
from unittest import TestCase | ||
|
||
from cli.wallet_client_manager import WalletClientManager | ||
|
||
|
||
class TestWalletClientManager(TestCase): | ||
def test_parse_get_manager_for_contract_response(self): | ||
response = """ | ||
Disclaimer: | ||
The Tezos network is a new blockchain technology. | ||
Users are solely responsible for any risks associated | ||
with usage of the Tezos network. Users should do their | ||
own research to determine if Tezos is the appropriate | ||
platform for their needs and should apply judgement and | ||
care in their network interactions. | ||
tz1PJnnddwa1P5jg5sChddigxfMccK8nwLiV (known as habanoz) | ||
""" | ||
clientManager = WalletClientManager(None) | ||
manager = clientManager.parse_get_manager_for_contract_response(response) | ||
self.assertEqual('tz1PJnnddwa1P5jg5sChddigxfMccK8nwLiV', manager) | ||
|
||
def test_parse_client_list_known_contracts_response(self): | ||
response = """ | ||
Disclaimer: | ||
The Tezos network is a new blockchain technology. | ||
Users are solely responsible for any risks associated | ||
with usage of the Tezos network. Users should do their | ||
own research to determine if Tezos is the appropriate | ||
platform for their needs and should apply judgement and | ||
care in their network interactions. | ||
newcontr: KT1XqEHigP5XumZy9i76QyVd6u93VD4HTqJK | ||
habanoz: tz1fyvFH2pd3V9UEq5psqVokVBYkt7rHTKio | ||
mainnetme: tz1a5GGJeyqeQ4ihZqbiRVcvj5rY5kMAt3Xa | ||
""" | ||
clientManager = WalletClientManager(None) | ||
dict = clientManager.parse_client_list_known_contracts_response(response) | ||
|
||
self.assertTrue(dict['newcontr'] == 'KT1XqEHigP5XumZy9i76QyVd6u93VD4HTqJK') | ||
self.assertTrue(dict['habanoz'] == 'tz1fyvFH2pd3V9UEq5psqVokVBYkt7rHTKio') | ||
self.assertTrue(dict['mainnetme'] == 'tz1a5GGJeyqeQ4ihZqbiRVcvj5rY5kMAt3Xa') | ||
|
||
def test_parse_list_known_addresses_response(self): | ||
response = """ | ||
Disclaimer: | ||
The Tezos network is a new blockchain technology. | ||
Users are solely responsible for any risks associated | ||
with usage of the Tezos network. Users should do their | ||
own research to determine if Tezos is the appropriate | ||
platform for their needs and should apply judgement and | ||
care in their network interactions. | ||
habanoz: tz1fyvFH2pd3V9UEq5psqVokVBYkt7rHTKio (unencrypted sk known) | ||
mainnetme: tz1a5GGJeyqeQ4ihZqbiRVcvj5rY5kMAt3Xa (tcp sk known) | ||
zeronetme: tz1MZ72sJEVen3Qgc7uWvqKhKFJW84bNGd6T (unencrypted sk not known) | ||
""" | ||
|
||
clientManager = WalletClientManager(None) | ||
dict = clientManager.parse_list_known_addresses_response(response) | ||
|
||
habanoz = dict['tz1fyvFH2pd3V9UEq5psqVokVBYkt7rHTKio'] | ||
|
||
self.assertEqual(habanoz['alias'], 'habanoz') | ||
self.assertEqual(habanoz['sk'], True) | ||
|
||
mainnetme = dict['tz1a5GGJeyqeQ4ihZqbiRVcvj5rY5kMAt3Xa'] | ||
|
||
self.assertEqual(mainnetme['alias'], 'mainnetme') | ||
self.assertEqual(mainnetme['sk'], True) | ||
|
||
zeronetme = dict['tz1MZ72sJEVen3Qgc7uWvqKhKFJW84bNGd6T'] | ||
|
||
self.assertEqual(zeronetme['alias'], 'zeronetme') | ||
self.assertEqual(zeronetme['sk'], False) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
from cli.simple_client_manager import SimpleClientManager | ||
from util.address_validator import AddressValidator | ||
from util.client_utils import clear_terminal_chars, not_indicator_line | ||
|
||
|
||
class WalletClientManager(SimpleClientManager): | ||
|
||
def __init__(self, client_path, contr_dict_by_alias=None, | ||
addr_dict_by_pkh=None, managers=None, verbose=None) -> None: | ||
super().__init__(client_path, verbose) | ||
|
||
self.managers = managers | ||
if self.managers is None: | ||
self.managers = dict() | ||
|
||
self.contr_dict_by_alias = contr_dict_by_alias | ||
self.addr_dict_by_pkh = addr_dict_by_pkh | ||
self.address_dict = None | ||
|
||
def get_manager_for_contract(self, pkh): | ||
|
||
if pkh.startswith('tz'): | ||
return pkh | ||
|
||
if pkh in self.managers: | ||
return self.managers[pkh] | ||
|
||
response = self.send_request(" get manager for " + pkh) | ||
|
||
response = clear_terminal_chars(response) | ||
|
||
manager = self.parse_get_manager_for_contract_response(response) | ||
|
||
try: | ||
AddressValidator("manager").validate(manager) | ||
except Exception as e: | ||
raise Exception("Invalid response from client '{}'".format(response),e) | ||
self.managers[pkh] = manager | ||
|
||
return manager | ||
|
||
def parse_get_manager_for_contract_response(self, response): | ||
manager = None | ||
for line in response.splitlines(): | ||
line = line.strip() | ||
if line.startswith("tz"): | ||
line = line.replace(" (", ':') | ||
manager, alias_plus = line.split(":", maxsplit=1) | ||
break | ||
|
||
if self.verbose: | ||
print("Manager address is : {}".format(manager)) | ||
|
||
return manager | ||
|
||
def generate_address_dict(self): | ||
if self.address_dict is not None: | ||
return self.address_dict | ||
|
||
self.address_dict = {} | ||
|
||
if self.contr_dict_by_alias is None: | ||
self.contr_dict_by_alias = self.list_known_contracts_by_alias() | ||
|
||
if self.addr_dict_by_pkh is None: | ||
self.addr_dict_by_pkh = self.list_known_addresses_by_pkh() | ||
|
||
for pkh, dict_alias_sk in self.addr_dict_by_pkh.items(): | ||
self.address_dict[pkh] = {"pkh": pkh, "originated": False, "alias": dict_alias_sk['alias'], | ||
"sk": dict_alias_sk['sk'], "manager": pkh} | ||
|
||
for alias, pkh in self.contr_dict_by_alias.items(): | ||
if pkh.startswith("KT"): | ||
manager = self.get_manager_for_contract(pkh) | ||
manager_sk = self.addr_dict_by_pkh[manager]['sk'] | ||
|
||
self.address_dict[pkh] = {"pkh": pkh, "originated": True, "alias": alias, "sk": manager_sk, | ||
"manager": manager} | ||
|
||
def list_known_contracts_by_alias(self): | ||
response = self.send_request(" list known contracts") | ||
|
||
response = clear_terminal_chars(response) | ||
|
||
dict = self.parse_client_list_known_contracts_response(response) | ||
|
||
return dict | ||
|
||
def parse_client_list_known_contracts_response(self, response): | ||
dict = {} | ||
for line in response.splitlines(): | ||
line = line.strip() | ||
if ":" in line and not_indicator_line(line): | ||
alias, pkh = line.split(":", maxsplit=1) | ||
dict[alias.strip()] = pkh.strip() | ||
if self.verbose: | ||
print("known contracts: {}".format(dict)) | ||
return dict | ||
|
||
def list_known_addresses_by_pkh(self): | ||
|
||
response = self.send_request(" list known addresses") | ||
|
||
response = clear_terminal_chars(response) | ||
|
||
dict = self.parse_list_known_addresses_response(response) | ||
|
||
return dict | ||
|
||
def get_known_contact_by_alias(self, alias): | ||
|
||
if self.contr_dict_by_alias is None: | ||
self.contr_dict_by_alias = self.list_known_contracts_by_alias() | ||
|
||
return self.contr_dict_by_alias[alias] | ||
|
||
def get_known_contacts_by_alias(self): | ||
|
||
if self.contr_dict_by_alias is None: | ||
self.contr_dict_by_alias = self.list_known_contracts_by_alias() | ||
|
||
return self.contr_dict_by_alias | ||
|
||
def parse_list_known_addresses_response(self, response): | ||
dict = {} | ||
|
||
for line in response.splitlines(): | ||
line = line.strip() | ||
if ":" in line and not_indicator_line(line): | ||
alias, pkh_plus_braces = line.split(":", maxsplit=1) | ||
pkh_plus_braces = pkh_plus_braces.replace(' (', ':') | ||
pkh, sk_section = pkh_plus_braces.split(":", maxsplit=1) | ||
sk_known = "sk known" in sk_section | ||
pkh = pkh.strip() | ||
alias = alias.strip() | ||
dict[pkh] = {"alias": alias, "sk": sk_known} | ||
|
||
if self.verbose: | ||
print("known addresses: {}".format(dict)) | ||
|
||
return dict |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.