hive-nectar 0.0.5__py3-none-any.whl → 0.0.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of hive-nectar might be problematic. Click here for more details.

Files changed (49) hide show
  1. {hive_nectar-0.0.5.dist-info → hive_nectar-0.0.7.dist-info}/METADATA +6 -3
  2. hive_nectar-0.0.7.dist-info/RECORD +91 -0
  3. nectar/account.py +43 -47
  4. nectar/amount.py +6 -11
  5. nectar/block.py +8 -9
  6. nectar/blockchain.py +10 -11
  7. nectar/blockchaininstance.py +4 -4
  8. nectar/blockchainobject.py +5 -6
  9. nectar/blurt.py +3 -4
  10. nectar/cli.py +14 -14
  11. nectar/comment.py +10 -11
  12. nectar/community.py +4 -5
  13. nectar/conveyor.py +3 -4
  14. nectar/exceptions.py +30 -24
  15. nectar/hive.py +3 -4
  16. nectar/hivesigner.py +2 -2
  17. nectar/imageuploader.py +2 -3
  18. nectar/price.py +6 -13
  19. nectar/rc.py +1 -2
  20. nectar/steem.py +3 -4
  21. nectar/transactionbuilder.py +12 -3
  22. nectar/version.py +1 -1
  23. nectar/vote.py +8 -9
  24. nectar/wallet.py +1 -1
  25. nectarapi/exceptions.py +20 -14
  26. nectarapi/graphenerpc.py +49 -76
  27. nectarapi/version.py +1 -1
  28. nectarbase/ledgertransactions.py +2 -3
  29. nectarbase/memo.py +9 -10
  30. nectarbase/objects.py +4 -5
  31. nectarbase/operations.py +3 -7
  32. nectarbase/version.py +1 -1
  33. nectargraphenebase/__init__.py +0 -1
  34. nectargraphenebase/account.py +16 -37
  35. nectargraphenebase/base58.py +5 -8
  36. nectargraphenebase/bip32.py +5 -11
  37. nectargraphenebase/bip38.py +6 -7
  38. nectargraphenebase/ecdsasig.py +32 -37
  39. nectargraphenebase/objects.py +6 -7
  40. nectargraphenebase/signedtransactions.py +10 -9
  41. nectargraphenebase/types.py +9 -19
  42. nectargraphenebase/unsignedtransactions.py +21 -28
  43. nectargraphenebase/version.py +1 -1
  44. nectarstorage/masterpassword.py +2 -3
  45. hive_nectar-0.0.5.dist-info/RECORD +0 -92
  46. nectargraphenebase/py23.py +0 -38
  47. {hive_nectar-0.0.5.dist-info → hive_nectar-0.0.7.dist-info}/WHEEL +0 -0
  48. {hive_nectar-0.0.5.dist-info → hive_nectar-0.0.7.dist-info}/entry_points.txt +0 -0
  49. {hive_nectar-0.0.5.dist-info → hive_nectar-0.0.7.dist-info}/licenses/LICENSE.txt +0 -0
nectar/hive.py CHANGED
@@ -6,7 +6,6 @@ from datetime import date, datetime, timezone
6
6
  from nectar.blockchaininstance import BlockChainInstance
7
7
  from nectar.constants import STEEM_100_PERCENT
8
8
  from nectargraphenebase.chains import known_chains
9
- from nectargraphenebase.py23 import string_types
10
9
 
11
10
  from .amount import Amount
12
11
  from .utils import formatToTimeStamp
@@ -124,7 +123,7 @@ class Hive(BlockChainInstance):
124
123
  return known_chains["HIVE"]
125
124
  try:
126
125
  return self.rpc.get_network(props=config)
127
- except:
126
+ except Exception:
128
127
  return known_chains["HIVE"]
129
128
 
130
129
  def rshares_to_token_backed_dollar(
@@ -362,7 +361,7 @@ class Hive(BlockChainInstance):
362
361
  """
363
362
  if isinstance(hbd, Amount):
364
363
  hbd = Amount(hbd, blockchain_instance=self)
365
- elif isinstance(hbd, string_types):
364
+ elif isinstance(hbd, str):
366
365
  hbd = Amount(hbd, blockchain_instance=self)
367
366
  else:
368
367
  hbd = Amount(hbd, self.hbd_symbol, blockchain_instance=self)
@@ -486,7 +485,7 @@ class Hive(BlockChainInstance):
486
485
  """
487
486
  if isinstance(hbd, Amount):
488
487
  hbd = Amount(hbd, blockchain_instance=self)
489
- elif isinstance(hbd, string_types):
488
+ elif isinstance(hbd, str):
490
489
  hbd = Amount(hbd, blockchain_instance=self)
491
490
  else:
492
491
  hbd = Amount(hbd, self.hbd_symbol, blockchain_instance=self)
nectar/hivesigner.py CHANGED
@@ -33,7 +33,7 @@ class HiveSigner(object):
33
33
  from nectar import Steem
34
34
  from nectar.HiveSigner import HiveSigner
35
35
  from nectar.comment import Comment
36
- hs = HiveSigner(client_id="nectar.app")
36
+ hs = HiveSigner(client_id="nectarflower")
37
37
  steem = Steem(HiveSigner=hs)
38
38
  steem.wallet.unlock("supersecret-passphrase")
39
39
  post = Comment("author/permlink", blockchain_instance=steem)
@@ -377,7 +377,7 @@ class HiveSigner(object):
377
377
  try:
378
378
  amount = Amount(value, blockchain_instance=self.blockchain)
379
379
  params[key] = str(amount)
380
- except:
380
+ except Exception:
381
381
  amount = None
382
382
  elif isinstance(value, bool):
383
383
  if value:
nectar/imageuploader.py CHANGED
@@ -6,7 +6,6 @@ import requests
6
6
 
7
7
  from nectar.account import Account
8
8
  from nectargraphenebase.ecdsasig import sign_message
9
- from nectargraphenebase.py23 import py23_bytes, string_types
10
9
 
11
10
  from .instance import shared_blockchain_instance
12
11
 
@@ -55,14 +54,14 @@ class ImageUploader(object):
55
54
  for authority in account["posting"]["key_auths"]:
56
55
  posting_wif = self.steem.wallet.getPrivateKeyForPublicKey(authority[0])
57
56
 
58
- if isinstance(image, string_types):
57
+ if isinstance(image, str):
59
58
  image_data = open(image, "rb").read()
60
59
  elif isinstance(image, io.BytesIO):
61
60
  image_data = image.read()
62
61
  else:
63
62
  image_data = image
64
63
 
65
- message = py23_bytes(self.challenge, "ascii") + image_data
64
+ message = bytes(self.challenge, "ascii") + image_data
66
65
  signature = sign_message(message, posting_wif)
67
66
  signature_in_hex = hexlify(signature).decode("ascii")
68
67
 
nectar/price.py CHANGED
@@ -3,7 +3,6 @@ from decimal import Decimal
3
3
  from fractions import Fraction
4
4
 
5
5
  from nectar.instance import shared_blockchain_instance
6
- from nectargraphenebase.py23 import integer_types, string_types
7
6
 
8
7
  from .amount import Amount
9
8
  from .asset import Asset
@@ -97,7 +96,7 @@ class Price(dict):
97
96
  self.blockchain = blockchain_instance or shared_blockchain_instance()
98
97
  if price == "":
99
98
  price = None
100
- if price is not None and isinstance(price, string_types) and not base and not quote:
99
+ if price is not None and isinstance(price, str) and not base and not quote:
101
100
  price, assets = price.split(" ")
102
101
  base_symbol, quote_symbol = assets_from_string(assets)
103
102
  base = Asset(base_symbol, blockchain_instance=self.blockchain)
@@ -131,9 +130,7 @@ class Price(dict):
131
130
  amount=frac.numerator, asset=base, blockchain_instance=self.blockchain
132
131
  )
133
132
 
134
- elif (
135
- price is not None and isinstance(base, string_types) and isinstance(quote, string_types)
136
- ):
133
+ elif price is not None and isinstance(base, str) and isinstance(quote, str):
137
134
  base = Asset(base, blockchain_instance=self.blockchain)
138
135
  quote = Asset(quote, blockchain_instance=self.blockchain)
139
136
  frac = Fraction(float(price)).limit_denominator(10 ** base["precision"])
@@ -144,12 +141,10 @@ class Price(dict):
144
141
  amount=frac.numerator, asset=base, blockchain_instance=self.blockchain
145
142
  )
146
143
 
147
- elif price is None and isinstance(base, string_types) and isinstance(quote, string_types):
144
+ elif price is None and isinstance(base, str) and isinstance(quote, str):
148
145
  self["quote"] = Amount(quote, blockchain_instance=self.blockchain)
149
146
  self["base"] = Amount(base, blockchain_instance=self.blockchain)
150
- elif (
151
- price is not None and isinstance(price, string_types) and isinstance(base, string_types)
152
- ):
147
+ elif price is not None and isinstance(price, str) and isinstance(base, str):
153
148
  self["quote"] = Amount(price, blockchain_instance=self.blockchain)
154
149
  self["base"] = Amount(base, blockchain_instance=self.blockchain)
155
150
  # len(args) > 1
@@ -163,10 +158,8 @@ class Price(dict):
163
158
  self["base"] = base
164
159
 
165
160
  elif (
166
- isinstance(price, float)
167
- or isinstance(price, integer_types)
168
- or isinstance(price, Decimal)
169
- ) and isinstance(base, string_types):
161
+ isinstance(price, float) or isinstance(price, int) or isinstance(price, Decimal)
162
+ ) and isinstance(base, str):
170
163
  base_symbol, quote_symbol = assets_from_string(base)
171
164
  base = Asset(base_symbol, blockchain_instance=self.blockchain)
172
165
  quote = Asset(quote_symbol, blockchain_instance=self.blockchain)
nectar/rc.py CHANGED
@@ -9,7 +9,6 @@ from nectar.constants import (
9
9
  from nectarbase import operations
10
10
  from nectarbase.objects import Operation
11
11
  from nectarbase.signedtransactions import Signed_Transaction
12
- from nectargraphenebase.py23 import py23_bytes
13
12
 
14
13
  from .instance import shared_blockchain_instance
15
14
 
@@ -38,7 +37,7 @@ class RC(object):
38
37
  operations=ops,
39
38
  )
40
39
  tx = tx.sign([wif], chain=prefix)
41
- txWire = hexlify(py23_bytes(tx)).decode("ascii")
40
+ txWire = hexlify(bytes(tx)).decode("ascii")
42
41
  tx_size = len(txWire)
43
42
  return tx_size
44
43
 
nectar/steem.py CHANGED
@@ -6,7 +6,6 @@ from datetime import date, datetime, timezone
6
6
  from nectar.blockchaininstance import BlockChainInstance
7
7
  from nectar.constants import STEEM_100_PERCENT, STEEM_VOTE_REGENERATION_SECONDS
8
8
  from nectargraphenebase.chains import known_chains
9
- from nectargraphenebase.py23 import string_types
10
9
 
11
10
  from .amount import Amount
12
11
  from .utils import formatToTimeStamp
@@ -124,7 +123,7 @@ class Steem(BlockChainInstance):
124
123
  return known_chains["STEEM"]
125
124
  try:
126
125
  return self.rpc.get_network(props=config)
127
- except:
126
+ except Exception:
128
127
  return known_chains["STEEM"]
129
128
 
130
129
  def rshares_to_token_backed_dollar(
@@ -393,7 +392,7 @@ class Steem(BlockChainInstance):
393
392
  """
394
393
  if isinstance(sbd, Amount):
395
394
  sbd = Amount(sbd, blockchain_instance=self)
396
- elif isinstance(sbd, string_types):
395
+ elif isinstance(sbd, str):
397
396
  sbd = Amount(sbd, blockchain_instance=self)
398
397
  else:
399
398
  sbd = Amount(sbd, self.sbd_symbol, blockchain_instance=self)
@@ -517,7 +516,7 @@ class Steem(BlockChainInstance):
517
516
  """
518
517
  if isinstance(sbd, Amount):
519
518
  sbd = Amount(sbd, blockchain_instance=self)
520
- elif isinstance(sbd, string_types):
519
+ elif isinstance(sbd, str):
521
520
  sbd = Amount(sbd, blockchain_instance=self)
522
521
  else:
523
522
  sbd = Amount(sbd, self.sbd_symbol, blockchain_instance=self)
@@ -279,7 +279,7 @@ class TransactionBuilder(dict):
279
279
  try:
280
280
  PrivateKey(wif, prefix=self.blockchain.prefix)
281
281
  self.wifs.add(wif)
282
- except:
282
+ except Exception:
283
283
  raise InvalidWifError
284
284
 
285
285
  def clearWifs(self):
@@ -427,7 +427,7 @@ class TransactionBuilder(dict):
427
427
  # try:
428
428
  # ledgertx = Ledger_Transaction(**self.json(with_prefix=True))
429
429
  # ledgertx.add_custom_chains(self.blockchain.custom_chains)
430
- # except:
430
+ # except Exception:
431
431
  # raise ValueError("Invalid TransactionBuilder Format")
432
432
  # ledgertx.sign(self.path, chain=self.blockchain.chain_params)
433
433
  self.ledgertx.sign(self.path, chain=self.blockchain.chain_params)
@@ -438,7 +438,16 @@ class TransactionBuilder(dict):
438
438
  raise MissingKeyError
439
439
 
440
440
  self.tx.sign(self.wifs, chain=self.blockchain.chain_params)
441
- self["signatures"].extend(self.tx.json().get("signatures"))
441
+ # Defensive: ensure self["signatures"] is a list before extend
442
+ if isinstance(self["signatures"], str):
443
+ log.warning(
444
+ "self['signatures'] was a string, converting to list to avoid AttributeError."
445
+ )
446
+ self["signatures"] = [self["signatures"]]
447
+ sigs = self.tx.json().get("signatures")
448
+ if isinstance(sigs, str):
449
+ sigs = [sigs]
450
+ self["signatures"].extend(sigs)
442
451
  return self.tx
443
452
 
444
453
  def verify_authority(self):
nectar/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """THIS FILE IS GENERATED FROM nectar PYPROJECT.TOML."""
2
2
 
3
- version = "0.0.5"
3
+ version = "0.0.7"
nectar/vote.py CHANGED
@@ -5,7 +5,6 @@ from datetime import date, datetime, timezone
5
5
  from prettytable import PrettyTable
6
6
 
7
7
  from nectarapi.exceptions import InvalidParameters, UnknownKey
8
- from nectargraphenebase.py23 import integer_types, string_types
9
8
 
10
9
  from .account import Account
11
10
  from .blockchainobject import BlockchainObject
@@ -42,7 +41,7 @@ class Vote(BlockchainObject):
42
41
  elif kwargs.get("hive_instance"):
43
42
  blockchain_instance = kwargs["hive_instance"]
44
43
  self.blockchain = blockchain_instance or shared_blockchain_instance()
45
- if isinstance(voter, string_types) and authorperm is not None:
44
+ if isinstance(voter, str) and authorperm is not None:
46
45
  [author, permlink] = resolve_authorperm(authorperm)
47
46
  self["voter"] = voter
48
47
  self["author"] = author
@@ -138,20 +137,20 @@ class Vote(BlockchainObject):
138
137
  "reputation",
139
138
  ]
140
139
  for p in parse_int:
141
- if p in vote and isinstance(vote.get(p), string_types):
140
+ if p in vote and isinstance(vote.get(p), str):
142
141
  vote[p] = int(vote.get(p, "0"))
143
142
 
144
- if "time" in vote and isinstance(vote.get("time"), string_types) and vote.get("time") != "":
143
+ if "time" in vote and isinstance(vote.get("time"), str) and vote.get("time") != "":
145
144
  vote["time"] = formatTimeString(vote.get("time", "1970-01-01T00:00:00"))
146
145
  elif (
147
146
  "timestamp" in vote
148
- and isinstance(vote.get("timestamp"), string_types)
147
+ and isinstance(vote.get("timestamp"), str)
149
148
  and vote.get("timestamp") != ""
150
149
  ):
151
150
  vote["time"] = formatTimeString(vote.get("timestamp", "1970-01-01T00:00:00"))
152
151
  elif (
153
152
  "last_update" in vote
154
- and isinstance(vote.get("last_update"), string_types)
153
+ and isinstance(vote.get("last_update"), str)
155
154
  and vote.get("last_update") != ""
156
155
  ):
157
156
  vote["last_update"] = formatTimeString(vote.get("last_update", "1970-01-01T00:00:00"))
@@ -178,7 +177,7 @@ class Vote(BlockchainObject):
178
177
  "reputation",
179
178
  ]
180
179
  for p in parse_int:
181
- if p in output and isinstance(output[p], integer_types):
180
+ if p in output and isinstance(output[p], int):
182
181
  output[p] = str(output[p])
183
182
  return json.loads(str(json.dumps(output)))
184
183
 
@@ -456,7 +455,7 @@ class ActiveVotes(VotesObject):
456
455
  authorperm["author"], authorperm["permlink"], api="condenser"
457
456
  )
458
457
  authorperm = authorperm["authorperm"]
459
- elif isinstance(authorperm, string_types):
458
+ elif isinstance(authorperm, str):
460
459
  [author, permlink] = resolve_authorperm(authorperm)
461
460
  if self.blockchain.rpc.get_use_appbase():
462
461
  self.blockchain.rpc.set_next_node_on_empty_reply(False)
@@ -534,7 +533,7 @@ class AccountVotes(VotesObject):
534
533
  time = x.get("last_update", "")
535
534
  if time != "":
536
535
  x["time"] = time
537
- if time != "" and isinstance(time, string_types):
536
+ if time != "" and isinstance(time, str):
538
537
  d_time = formatTimeString(time)
539
538
  elif isinstance(time, datetime):
540
539
  d_time = time
nectar/wallet.py CHANGED
@@ -409,7 +409,7 @@ class Wallet(object):
409
409
  else:
410
410
  try:
411
411
  account = Account(name, blockchain_instance=self.blockchain)
412
- except:
412
+ except Exception:
413
413
  return
414
414
  return {
415
415
  "name": account["name"],
nectarapi/exceptions.py CHANGED
@@ -19,37 +19,43 @@ def decodeRPCErrorMsg(e):
19
19
  return str(e)
20
20
 
21
21
 
22
- class UnauthorizedError(Exception):
22
+ class NectarApiException(Exception):
23
+ """NectarApiException base Exception."""
24
+
25
+ pass
26
+
27
+
28
+ class UnauthorizedError(NectarApiException):
23
29
  """UnauthorizedError Exception."""
24
30
 
25
31
  pass
26
32
 
27
33
 
28
- class RPCConnection(Exception):
34
+ class RPCConnection(NectarApiException):
29
35
  """RPCConnection Exception."""
30
36
 
31
37
  pass
32
38
 
33
39
 
34
- class RPCError(Exception):
40
+ class RPCError(NectarApiException):
35
41
  """RPCError Exception."""
36
42
 
37
43
  pass
38
44
 
39
45
 
40
- class RPCErrorDoRetry(Exception):
46
+ class RPCErrorDoRetry(NectarApiException):
41
47
  """RPCErrorDoRetry Exception."""
42
48
 
43
49
  pass
44
50
 
45
51
 
46
- class NumRetriesReached(Exception):
52
+ class NumRetriesReached(NectarApiException):
47
53
  """NumRetriesReached Exception."""
48
54
 
49
55
  pass
50
56
 
51
57
 
52
- class CallRetriesReached(Exception):
58
+ class CallRetriesReached(NectarApiException):
53
59
  """CallRetriesReached Exception. Only for internal use"""
54
60
 
55
61
  pass
@@ -91,33 +97,33 @@ class FilteredItemNotFound(RPCError):
91
97
  pass
92
98
 
93
99
 
94
- class InvalidEndpointUrl(Exception):
100
+ class InvalidEndpointUrl(NectarApiException):
95
101
  pass
96
102
 
97
103
 
98
- class InvalidParameters(Exception):
104
+ class InvalidParameters(NectarApiException):
99
105
  pass
100
106
 
101
107
 
102
- class SupportedByHivemind(Exception):
108
+ class SupportedByHivemind(NectarApiException):
103
109
  pass
104
110
 
105
111
 
106
- class UnnecessarySignatureDetected(Exception):
112
+ class UnnecessarySignatureDetected(NectarApiException):
107
113
  pass
108
114
 
109
115
 
110
- class WorkingNodeMissing(Exception):
116
+ class WorkingNodeMissing(NectarApiException):
111
117
  pass
112
118
 
113
119
 
114
- class TimeoutException(Exception):
120
+ class TimeoutException(NectarApiException):
115
121
  pass
116
122
 
117
123
 
118
- class VotedBeforeWaitTimeReached(Exception):
124
+ class VotedBeforeWaitTimeReached(NectarApiException):
119
125
  pass
120
126
 
121
127
 
122
- class UnknownTransaction(Exception):
128
+ class UnknownTransaction(NectarApiException):
123
129
  pass
nectarapi/graphenerpc.py CHANGED
@@ -46,7 +46,7 @@ log = logging.getLogger(__name__)
46
46
 
47
47
 
48
48
  class SessionInstance(object):
49
- """Singelton for the Session Instance"""
49
+ """Singleton for the Session Instance"""
50
50
 
51
51
  instance = None
52
52
 
@@ -59,7 +59,7 @@ def set_session_instance(instance):
59
59
  def shared_session_instance():
60
60
  """Get session instance"""
61
61
  if REQUEST_MODULE is None:
62
- raise Exception()
62
+ raise Exception("Requests module is not available.")
63
63
  if not SessionInstance.instance:
64
64
  SessionInstance.instance = requests.Session()
65
65
  return SessionInstance.instance
@@ -68,7 +68,7 @@ def shared_session_instance():
68
68
  def create_ws_instance(use_ssl=True, enable_multithread=True):
69
69
  """Get websocket instance"""
70
70
  if WEBSOCKET_MODULE is None:
71
- raise Exception()
71
+ raise Exception("WebSocket module is not available.")
72
72
  if use_ssl:
73
73
  ssl_defaults = ssl.get_default_verify_paths()
74
74
  sslopt_ca_certs = {"ca_certs": ssl_defaults.cafile}
@@ -79,47 +79,24 @@ def create_ws_instance(use_ssl=True, enable_multithread=True):
79
79
 
80
80
  class GrapheneRPC(object):
81
81
  """
82
- This class allows to call API methods synchronously, without callbacks.
82
+ This class allows calling API methods synchronously, without callbacks.
83
83
 
84
84
  It logs warnings and errors.
85
85
 
86
86
  :param str urls: Either a single Websocket/Http URL, or a list of URLs
87
87
  :param str user: Username for Authentication
88
88
  :param str password: Password for Authentication
89
- :param int num_retries: Try x times to num_retries to a node on disconnect, -1 for indefinitely (default is 100)
90
- :param int num_retries_call: Repeat num_retries_call times a rpc call on node error (default is 5)
91
- :param int timeout: Timeout setting for https nodes (default is 60)
92
- :param bool autoconnect: When set to false, connection is performed on the first rpc call (default is True)
93
- :param bool use_condenser: Use the old condenser_api rpc protocol on nodes with version
94
- 0.19.4 or higher. The settings has no effect on nodes with version of 0.19.3 or lower.
95
- :param bool use_tor: When set to true, 'socks5h://localhost:9050' is set as proxy
96
- :param dict custom_chains: custom chain which should be added to the known chains
97
-
98
- Available APIs:
99
-
100
- * database
101
- * network_node
102
- * network_broadcast
103
-
104
- Usage:
105
-
106
- .. code-block:: python
107
-
108
- from nectarapi.graphenerpc import GrapheneRPC
109
- ws = GrapheneRPC("wss://steemd.pevo.science","","")
110
- print(ws.get_account_count())
111
-
112
- ws = GrapheneRPC("https://api.steemit.com","","")
113
- print(ws.get_account_count())
114
-
115
- .. note:: This class allows to call methods available via
116
- websocket. If you want to use the notification
117
- subsystem, please use ``GrapheneWebsocket`` instead.
118
-
89
+ :param int num_retries: Number of retries for node connection (default is 100)
90
+ :param int num_retries_call: Number of retries for RPC calls on node error (default is 5)
91
+ :param int timeout: Timeout setting for HTTP nodes (default is 60)
92
+ :param bool autoconnect: Automatically connect on initialization (default is True)
93
+ :param bool use_condenser: Use the old condenser_api RPC protocol
94
+ :param bool use_tor: Use Tor proxy for connections
95
+ :param dict custom_chains: Custom chains to add to known chains
119
96
  """
120
97
 
121
98
  def __init__(self, urls, user=None, password=None, **kwargs):
122
- """Init."""
99
+ """Initialize the RPC client."""
123
100
  self.rpc_methods = {"offline": -1, "ws": 0, "jsonrpc": 1, "wsappbase": 2, "appbase": 3}
124
101
  self.current_rpc = self.rpc_methods["ws"]
125
102
  self._request_id = 0
@@ -454,11 +431,12 @@ class GrapheneRPC(object):
454
431
  :raises ValueError: if the server does not respond in proper JSON format
455
432
  :raises RPCError: if the server returns an error
456
433
  """
457
- log.debug(json.dumps(payload))
434
+ log.debug(f"Payload: {json.dumps(payload)}")
458
435
  if self.nodes.working_nodes_count == 0:
459
- raise WorkingNodeMissing
436
+ raise WorkingNodeMissing("No working nodes available.")
460
437
  if self.url is None:
461
438
  raise RPCConnection("RPC is not connected!")
439
+
462
440
  reply = {}
463
441
  response = None
464
442
  while True:
@@ -488,13 +466,9 @@ class GrapheneRPC(object):
488
466
  except KeyboardInterrupt:
489
467
  raise
490
468
  except WebSocketConnectionClosedException as e:
491
- if self.nodes.num_retries_call_reached:
492
- self.nodes.increase_error_cnt()
493
- self.nodes.sleep_and_check_retries(str(e), sleep=False, call_retry=False)
494
- self.rpcconnect()
495
- else:
496
- # self.nodes.sleep_and_check_retries(str(e), sleep=True, call_retry=True)
497
- self.rpcconnect(next_url=False)
469
+ self.nodes.increase_error_cnt()
470
+ self.nodes.sleep_and_check_retries(str(e), sleep=False, call_retry=False)
471
+ self.rpcconnect()
498
472
  except ConnectionError as e:
499
473
  self.nodes.increase_error_cnt()
500
474
  self.nodes.sleep_and_check_retries(str(e), sleep=False, call_retry=False)
@@ -508,48 +482,47 @@ class GrapheneRPC(object):
508
482
  self.nodes.sleep_and_check_retries(str(e), sleep=False, call_retry=False)
509
483
  self.rpcconnect()
510
484
 
511
- ret = {}
512
485
  try:
513
486
  if response is None:
514
- ret = json.loads(reply, strict=False, encoding="utf-8")
487
+ try:
488
+ ret = json.loads(reply, strict=False)
489
+ except ValueError:
490
+ log.error(f"Non-JSON response: {reply} Node: {self.url}")
491
+ self._check_for_server_error(reply)
492
+ raise RPCError("Invalid response format")
515
493
  else:
516
494
  ret = response.json()
517
495
  except ValueError:
518
496
  self._check_for_server_error(reply)
519
497
 
520
- log.debug(json.dumps(reply))
498
+ log.debug(f"Reply: {json.dumps(reply)}")
521
499
 
522
500
  if isinstance(ret, dict) and "error" in ret:
523
- if "detail" in ret["error"]:
524
- raise RPCError(ret["error"]["detail"])
525
- else:
526
- raise RPCError(ret["error"]["message"])
527
- else:
528
- if isinstance(ret, list):
529
- ret_list = []
530
- for r in ret:
531
- if isinstance(r, dict) and "error" in r:
532
- if "detail" in r["error"]:
533
- raise RPCError(r["error"]["detail"])
534
- else:
535
- raise RPCError(r["error"]["message"])
536
- elif isinstance(r, dict) and "result" in r:
537
- ret_list.append(r["result"])
538
- else:
539
- ret_list.append(r)
540
- self.nodes.reset_error_cnt_call()
541
- return ret_list
542
- elif isinstance(ret, dict) and "result" in ret:
543
- self.nodes.reset_error_cnt_call()
544
- return ret["result"]
545
- elif isinstance(ret, int):
546
- raise RPCError(
547
- "Client returned invalid format. Expected JSON! Output: %s" % (str(ret))
501
+ if isinstance(ret["error"], dict):
502
+ error_message = ret["error"].get(
503
+ "detail", ret["error"].get("message", "Unknown error")
548
504
  )
549
- else:
550
- self.nodes.reset_error_cnt_call()
551
- return ret
552
- return ret
505
+ raise RPCError(error_message)
506
+ elif isinstance(ret, list):
507
+ ret_list = []
508
+ for r in ret:
509
+ if isinstance(r, dict) and "error" in r:
510
+ error_message = r["error"].get(
511
+ "detail", r["error"].get("message", "Unknown error")
512
+ )
513
+ raise RPCError(error_message)
514
+ elif isinstance(r, dict) and "result" in r:
515
+ ret_list.append(r["result"])
516
+ else:
517
+ ret_list.append(r)
518
+ self.nodes.reset_error_cnt_call()
519
+ return ret_list
520
+ elif isinstance(ret, dict) and "result" in ret:
521
+ self.nodes.reset_error_cnt_call()
522
+ return ret["result"]
523
+ else:
524
+ log.error(f"Unexpected response format: {ret} Node: {self.url}")
525
+ raise RPCError(f"Unexpected response format: {ret}")
553
526
 
554
527
  # End of Deprecated methods
555
528
  ####################################################################
nectarapi/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """THIS FILE IS GENERATED FROM nectar PYPROJECT.TOML."""
2
2
 
3
- version = "0.0.5"
3
+ version = "0.0.7"
@@ -3,7 +3,6 @@ import logging
3
3
 
4
4
  from nectargraphenebase.account import PublicKey
5
5
  from nectargraphenebase.chains import known_chains
6
- from nectargraphenebase.py23 import py23_bytes
7
6
  from nectargraphenebase.types import (
8
7
  Array,
9
8
  Signature,
@@ -54,7 +53,7 @@ class Ledger_Transaction(GrapheneUnsigned_Transaction):
54
53
  dongle = getDongle(True)
55
54
  apdu_list = self.build_apdu(path, chain)
56
55
  for apdu in apdu_list:
57
- result = dongle.exchange(py23_bytes(apdu))
56
+ result = dongle.exchange(bytes(apdu))
58
57
  dongle.close()
59
58
  sigs = []
60
59
  signature = result
@@ -67,7 +66,7 @@ class Ledger_Transaction(GrapheneUnsigned_Transaction):
67
66
 
68
67
  dongle = getDongle(True)
69
68
  apdu = self.build_apdu_pubkey(path, request_screen_approval)
70
- result = dongle.exchange(py23_bytes(apdu))
69
+ result = dongle.exchange(bytes(apdu))
71
70
  dongle.close()
72
71
  offset = 1 + result[0]
73
72
  address = result[offset + 1 : offset + 1 + result[offset]]