hive-nectar 0.0.11__py3-none-any.whl → 0.1.0__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 (56) hide show
  1. {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/METADATA +10 -11
  2. hive_nectar-0.1.0.dist-info/RECORD +88 -0
  3. nectar/__init__.py +1 -4
  4. nectar/account.py +791 -685
  5. nectar/amount.py +82 -21
  6. nectar/asset.py +1 -2
  7. nectar/block.py +34 -22
  8. nectar/blockchain.py +111 -143
  9. nectar/blockchaininstance.py +396 -247
  10. nectar/blockchainobject.py +33 -5
  11. nectar/cli.py +1058 -1349
  12. nectar/comment.py +313 -181
  13. nectar/community.py +39 -43
  14. nectar/constants.py +1 -14
  15. nectar/discussions.py +793 -139
  16. nectar/hive.py +137 -77
  17. nectar/hivesigner.py +106 -68
  18. nectar/imageuploader.py +33 -23
  19. nectar/instance.py +31 -79
  20. nectar/market.py +128 -264
  21. nectar/memo.py +40 -13
  22. nectar/message.py +23 -10
  23. nectar/nodelist.py +115 -81
  24. nectar/price.py +80 -61
  25. nectar/profile.py +6 -3
  26. nectar/rc.py +45 -25
  27. nectar/snapshot.py +285 -163
  28. nectar/storage.py +16 -5
  29. nectar/transactionbuilder.py +132 -41
  30. nectar/utils.py +37 -17
  31. nectar/version.py +1 -1
  32. nectar/vote.py +171 -30
  33. nectar/wallet.py +26 -19
  34. nectar/witness.py +153 -54
  35. nectarapi/graphenerpc.py +147 -133
  36. nectarapi/noderpc.py +12 -6
  37. nectarapi/rpcutils.py +12 -6
  38. nectarapi/version.py +1 -1
  39. nectarbase/ledgertransactions.py +24 -1
  40. nectarbase/objects.py +17 -6
  41. nectarbase/operations.py +160 -90
  42. nectarbase/signedtransactions.py +38 -2
  43. nectarbase/version.py +1 -1
  44. nectargraphenebase/account.py +295 -17
  45. nectargraphenebase/chains.py +0 -135
  46. nectargraphenebase/ecdsasig.py +152 -176
  47. nectargraphenebase/types.py +18 -4
  48. nectargraphenebase/unsignedtransactions.py +1 -1
  49. nectargraphenebase/version.py +1 -1
  50. hive_nectar-0.0.11.dist-info/RECORD +0 -91
  51. nectar/blurt.py +0 -562
  52. nectar/conveyor.py +0 -308
  53. nectar/steem.py +0 -581
  54. {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/WHEEL +0 -0
  55. {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/entry_points.txt +0 -0
  56. {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/licenses/LICENSE.txt +0 -0
nectar/message.py CHANGED
@@ -50,11 +50,17 @@ timestamp={meta[timestamp]}
50
50
  {MESSAGE_SPLIT[3]}"""
51
51
 
52
52
  def __init__(self, message, blockchain_instance=None, *args, **kwargs):
53
- if blockchain_instance is None:
54
- if kwargs.get("steem_instance"):
55
- blockchain_instance = kwargs["steem_instance"]
56
- elif kwargs.get("hive_instance"):
57
- blockchain_instance = kwargs["hive_instance"]
53
+ """
54
+ Initialize the message handler, normalize line endings, and set up signing context.
55
+
56
+ Parameters:
57
+ message (str): The raw message text to be signed or verified. Line endings are normalized to LF.
58
+
59
+ Description:
60
+ - Assigns self.blockchain to the provided blockchain_instance or to shared_blockchain_instance() when none is given.
61
+ - Normalizes CRLF ("\r\n") to LF ("\n") and stores the result in self.message.
62
+ - Initializes signing/verification context attributes: signed_by_account, signed_by_name, meta, and plain_message to None.
63
+ """
58
64
  self.blockchain = blockchain_instance or shared_blockchain_instance()
59
65
  self.message = message.replace("\r\n", "\n")
60
66
  self.signed_by_account = None
@@ -183,11 +189,18 @@ class MessageV2(object):
183
189
  """Allow to sign and verify Messages that are sigend with a private key"""
184
190
 
185
191
  def __init__(self, message, blockchain_instance=None, *args, **kwargs):
186
- if blockchain_instance is None:
187
- if kwargs.get("steem_instance"):
188
- blockchain_instance = kwargs["steem_instance"]
189
- elif kwargs.get("hive_instance"):
190
- blockchain_instance = kwargs["hive_instance"]
192
+ """
193
+ Initialize the message handler and set up default signing context.
194
+
195
+ Parameters:
196
+ message (str): The raw message text to be signed or verified.
197
+
198
+ Description:
199
+ Stores the provided message and sets up the signing context attributes
200
+ (signed_by_account, signed_by_name, meta, plain_message) to None.
201
+ If no blockchain instance is supplied, assigns a shared blockchain instance
202
+ via shared_blockchain_instance().
203
+ """
191
204
  self.blockchain = blockchain_instance or shared_blockchain_instance()
192
205
 
193
206
  self.message = message
nectar/nodelist.py CHANGED
@@ -10,12 +10,24 @@ log = logging.getLogger(__name__)
10
10
 
11
11
 
12
12
  def node_answer_time(node):
13
+ """
14
+ Measure the RPC/network response time to a Hive node.
15
+
16
+ Parameters:
17
+ node (str): Node endpoint (URL or host) to ping.
18
+
19
+ Returns:
20
+ float: Elapsed time in seconds for a single `get_network` call. Returns float('inf') if an error occurred while contacting the node.
21
+
22
+ Raises:
23
+ KeyboardInterrupt: Re-raised if the operation is interrupted by the user.
24
+ """
13
25
  try:
14
26
  from nectar.blockchaininstance import BlockChainInstance
15
27
 
16
- stm_local = BlockChainInstance(node=node, num_retries=2, num_retries_call=2, timeout=10)
28
+ hv_local = BlockChainInstance(node=node, num_retries=2, num_retries_call=2, timeout=10)
17
29
  start = timer()
18
- stm_local.get_network(use_stored_data=False)
30
+ hv_local.get_network(use_stored_data=False)
19
31
  stop = timer()
20
32
  rpc_answer_time = stop - start
21
33
  except KeyboardInterrupt:
@@ -27,7 +39,7 @@ def node_answer_time(node):
27
39
 
28
40
 
29
41
  class NodeList(list):
30
- """Returns HIVE/STEEM nodes as list
42
+ """Returns Hive nodes as list
31
43
 
32
44
  .. code-block:: python
33
45
 
@@ -38,15 +50,14 @@ class NodeList(list):
38
50
  """
39
51
 
40
52
  def __init__(self):
53
+ """
54
+ Initialize the NodeList with a built-in default set of Hive node metadata.
55
+
56
+ Creates the list with prepopulated node dictionaries (url, version, type, owner, hive, score)
57
+ and passes them to the parent list constructor. The default entries are Hive-focused
58
+ (appbase and testnet types) and intended as the initial internal node registry.
59
+ """
41
60
  nodes = [
42
- {
43
- "url": "https://api.steemit.com",
44
- "version": "0.20.2",
45
- "type": "appbase",
46
- "owner": "steemit",
47
- "hive": False,
48
- "score": 50,
49
- },
50
61
  {
51
62
  "url": "https://api.hive.blog",
52
63
  "version": "1.27.8",
@@ -177,14 +188,24 @@ class NodeList(list):
177
188
  super(NodeList, self).__init__(new_nodes)
178
189
 
179
190
  def get_node_answer_time(self, node_list=None, verbose=False):
180
- """Pings all nodes and measure the answer time
181
-
182
- .. code-block:: python
183
-
184
- from nectar.nodelist import NodeList
185
- nl = NodeList()
186
- nl.update_nodes()
187
- nl.ping_nodes()
191
+ """
192
+ Return a list of reachable node endpoints sorted by measured RPC latency.
193
+
194
+ Pings each URL in node_list (or every URL known to this NodeList if node_list is None)
195
+ using node_answer_time and returns a list of dicts sorted by increasing latency.
196
+ Each dict contains:
197
+ - "url": the node endpoint string
198
+ - "delay_ms": measured round-trip delay in milliseconds
199
+
200
+ Parameters:
201
+ node_list (iterable[str] | None): Specific node URLs to test. If None, all URLs
202
+ from this NodeList are tested.
203
+ verbose (bool): If True, logs each node's measured delay.
204
+
205
+ Behavior notes:
206
+ - URLs not present in this NodeList are treated as unreachable and omitted from the result.
207
+ - Nodes that fail measurement are treated as infinite latency and are excluded from the returned list.
208
+ - A KeyboardInterrupt during measurements stops further pinging; the interrupted entry is treated as unreachable.
188
209
  """
189
210
  ping_times = []
190
211
  if node_list is None:
@@ -214,27 +235,39 @@ class NodeList(list):
214
235
  sorted_nodes.append({"url": node_list[i], "delay_ms": ping_times[i] * 1000})
215
236
  return sorted_nodes
216
237
 
217
- def update_nodes(self, weights=None, blockchain_instance=None, **kwargs):
218
- """Reads metadata from nectarflower and recalculates the nodes score
219
-
220
- :param list/dict weight: can be used to weight the different benchmarks
221
- :type weight: list, dict
222
-
223
- .. code-block:: python
224
-
225
- from nectar.nodelist import NodeList
226
- nl = NodeList()
227
- weights = [0, 0.1, 0.2, 1]
228
- nl.update_nodes(weights)
229
- weights = {'block': 0.1, 'history': 0.1, 'apicall': 1, 'config': 1}
230
- nl.update_nodes(weights)
238
+ def update_nodes(self, weights=None, blockchain_instance=None):
231
239
  """
232
- if blockchain_instance is None:
233
- if kwargs.get("steem_instance"):
234
- blockchain_instance = kwargs["steem_instance"]
235
- elif kwargs.get("hive_instance"):
236
- blockchain_instance = kwargs["hive_instance"]
237
- steem = blockchain_instance or shared_blockchain_instance()
240
+ Update the internal node list and recalculated scores using nectarflower metadata.
241
+
242
+ Fetches the "nectarflower" account's json_metadata (up to 5 attempts) and uses its
243
+ "report", "failing_nodes", and "parameter" sections to recalculate each node's
244
+ score and metadata (version, hive). If metadata cannot be retrieved after
245
+ retries, the method logs a warning and returns without modifying the list.
246
+
247
+ Weights:
248
+ - weights may be None, a list, or a dict.
249
+ - None: benchmarks are weighted uniformly.
250
+ - list: values are assigned in order to discovered benchmark names and normalized by their sum.
251
+ - dict: keys are benchmark names; values are normalized by their sum. Any benchmark not present in the provided dict receives weight 0.
252
+ The code derives benchmark names from metadata.parameters.benchmarks when available,
253
+ otherwise from keys present in report entries (excluding obvious non-benchmark fields).
254
+
255
+ Scoring rules:
256
+ - For each report entry, per-benchmark ranks are converted to scores (0–100),
257
+ multiplied by the benchmark weights, and summed to produce a node score.
258
+ - If a report entry contains a numeric "weighted_score", that value takes precedence.
259
+ - Nodes listed in failing_nodes receive a score of -1.
260
+ - Nodes present in the internal list but missing from the report receive score 0.
261
+ - Nodes present in the report but missing from the internal list are appended to the final list (with fields populated from the report).
262
+ - Nodes listed in failing_nodes but absent elsewhere are appended with score -1.
263
+
264
+ Side effects:
265
+ - Replaces the NodeList contents (in-place) with the newly computed list of nodes.
266
+ - Uses the provided blockchain_instance or a shared blockchain instance to fetch metadata and advance RPC state on transient errors.
267
+
268
+ No return value.
269
+ """
270
+ bc = blockchain_instance or shared_blockchain_instance()
238
271
 
239
272
  metadata = None
240
273
  account = None
@@ -242,7 +275,7 @@ class NodeList(list):
242
275
  while metadata is None and cnt < 5:
243
276
  cnt += 1
244
277
  try:
245
- account = Account("nectarflower", blockchain_instance=steem)
278
+ account = Account("nectarflower", blockchain_instance=bc)
246
279
  # Metadata is stored in the account's json_metadata field (not posting_json_metadata)
247
280
  raw_meta = account.get("json_metadata") or ""
248
281
  try:
@@ -251,7 +284,7 @@ class NodeList(list):
251
284
  metadata = None
252
285
  except Exception as e:
253
286
  log.warning(f"Error fetching metadata (attempt {cnt}): {str(e)}")
254
- steem.rpc.next()
287
+ bc.rpc.next()
255
288
  account = None
256
289
  metadata = None
257
290
 
@@ -412,7 +445,7 @@ class NodeList(list):
412
445
 
413
446
  def get_nodes(
414
447
  self,
415
- hive=False,
448
+ hive=True,
416
449
  exclude_limited=False,
417
450
  dev=False,
418
451
  testnet=False,
@@ -423,17 +456,25 @@ class NodeList(list):
423
456
  normal=True,
424
457
  appbase=True,
425
458
  ):
426
- """Returns nodes as list
427
-
428
- :param bool hive: When True, only HIVE nodes will be returned
429
- :param bool exclude_limited: When True, limited nodes are excluded
430
- :param bool dev: when True, dev nodes with version 0.19.11 are included
431
- :param bool testnet: when True, testnet nodes are included
432
- :param bool testnetdev: When True, testnet-dev nodes are included
433
- :param bool not_working: When True, all nodes including not working ones will be returned
434
- :param bool normal: deprecated
435
- :param bool appbase: deprecated
436
-
459
+ """
460
+ Return a list of node URLs filtered and sorted by score (descending).
461
+
462
+ Filters nodes by type (normal, appbase, appbase-dev, testnet, testnet-dev, appbase-limited), by whether they are Hive nodes, by protocol (https/wss), and by working status. Nodes with score < 0 are excluded unless not_working=True. The resulting list is sorted by each node's "score" in descending order.
463
+
464
+ Parameters that add non-obvious behavior:
465
+ hive (bool): If True (default) return only nodes marked as Hive; set to False to include non-Hive entries (note: the bundled node data is Hive-focused).
466
+ exclude_limited (bool): If True, exclude nodes of type "appbase-limited".
467
+ dev (bool): If True, include "appbase-dev" nodes (legacy/dev nodes, historically version 0.19.11).
468
+ testnet (bool): If True, include "testnet" nodes.
469
+ testnetdev (bool): If True, include "testnet-dev" nodes.
470
+ wss (bool): If False, exclude URLs that start with "wss".
471
+ https (bool): If False, exclude URLs that start with "https".
472
+ not_working (bool): If True, include nodes with negative scores (not working).
473
+ normal (bool): Include "normal" nodes when True. (Deprecated)
474
+ appbase (bool): Include "appbase" nodes when True. (Deprecated)
475
+
476
+ Returns:
477
+ list[str]: Filtered node URLs sorted by node["score"] descending.
437
478
  """
438
479
  node_list = []
439
480
  node_type_list = []
@@ -451,6 +492,7 @@ class NodeList(list):
451
492
  node_type_list.append("appbase-limited")
452
493
  for node in self:
453
494
  if node["type"] in node_type_list and (node["score"] >= 0 or not_working):
495
+ # Hive-only by default; legacy callers can still pass hive=False but list is Hive-only
454
496
  if hive != node["hive"]:
455
497
  continue
456
498
  if not https and node["url"][:5] == "https":
@@ -464,11 +506,19 @@ class NodeList(list):
464
506
  ]
465
507
 
466
508
  def get_hive_nodes(self, testnet=False, not_working=False, wss=True, https=True):
467
- """Returns hive only nodes as list
509
+ """
510
+ Return a list of Hive node URLs filtered and ordered by score.
468
511
 
469
- :param bool testnet: when True, testnet nodes are included
470
- :param bool not_working: When True, all nodes including not working ones will be returned
512
+ Filters internal nodes to Hive-only entries and returns their URLs sorted by score (highest first).
471
513
 
514
+ Parameters:
515
+ testnet (bool): If True, include only nodes whose type is "testnet". If False, include only non-testnet nodes.
516
+ not_working (bool): If True, include nodes with negative scores (typically non-working). If False, exclude them.
517
+ wss (bool): If True, include nodes with WSS (wss://) URLs; if False, exclude WSS endpoints.
518
+ https (bool): If True, include nodes with HTTPS (https://) URLs; if False, exclude HTTPS endpoints.
519
+
520
+ Returns:
521
+ list[str]: Sorted list of node URLs (strings) matching the filters.
472
522
  """
473
523
  node_list = []
474
524
 
@@ -490,33 +540,17 @@ class NodeList(list):
490
540
  node["url"] for node in sorted(node_list, key=lambda self: self["score"], reverse=True)
491
541
  ]
492
542
 
493
- def get_steem_nodes(self, testnet=False, not_working=False, wss=True, https=True):
494
- """Returns steem only nodes as list
495
-
496
- :param bool testnet: when True, testnet nodes are included
497
- :param bool not_working: When True, all nodes including not working ones will be returned
498
-
543
+ def get_testnet(self, testnet=True, testnetdev=False):
499
544
  """
500
- node_list = []
545
+ Return a list of testnet node URLs.
501
546
 
502
- for node in self:
503
- if node["hive"]:
504
- continue
505
- if node["score"] < 0 and not not_working:
506
- continue
507
- if (testnet and node["type"] == "testnet") or (
508
- not testnet and node["type"] != "testnet"
509
- ):
510
- if not https and node["url"][:5] == "https":
511
- continue
512
- if not wss and node["url"][:3] == "wss":
513
- continue
514
- node_list.append(node)
547
+ Calls get_nodes with normal and appbase disabled to return nodes belonging to the testnet(s).
515
548
 
516
- return [
517
- node["url"] for node in sorted(node_list, key=lambda self: self["score"], reverse=True)
518
- ]
549
+ Parameters:
550
+ testnet (bool): If True include nodes marked as `testnet`. If False, include non-testnet nodes.
551
+ testnetdev (bool): If True include nodes marked as `testnet-dev` (development testnet).
519
552
 
520
- def get_testnet(self, testnet=True, testnetdev=False):
521
- """Returns testnet nodes"""
553
+ Returns:
554
+ list: Sorted list of node URL strings matching the requested testnet filters.
555
+ """
522
556
  return self.get_nodes(normal=False, appbase=False, testnet=testnet, testnetdev=testnetdev)
nectar/price.py CHANGED
@@ -4,23 +4,12 @@ from fractions import Fraction
4
4
 
5
5
  from nectar.instance import shared_blockchain_instance
6
6
 
7
- from .amount import Amount
7
+ from .amount import Amount, check_asset
8
8
  from .asset import Asset
9
9
  from .exceptions import InvalidAssetException
10
10
  from .utils import assets_from_string, formatTimeString
11
11
 
12
12
 
13
- def check_asset(other, self, stm):
14
- if isinstance(other, dict) and "asset" in other and isinstance(self, dict) and "asset" in self:
15
- if not Asset(other["asset"], blockchain_instance=stm) == Asset(
16
- self["asset"], blockchain_instance=stm
17
- ):
18
- raise AssertionError()
19
- else:
20
- if not other == self:
21
- raise AssertionError()
22
-
23
-
24
13
  class Price(dict):
25
14
  """This class deals with all sorts of prices of any pair of assets to
26
15
  simplify dealing with the tuple::
@@ -37,7 +26,7 @@ class Price(dict):
37
26
  :param list args: Allows to deal with different representations of a price
38
27
  :param Asset base: Base asset
39
28
  :param Asset quote: Quote asset
40
- :param Steem blockchain_instance: Steem instance
29
+ :param Hive blockchain_instance: Hive instance
41
30
  :returns: All data required to represent a price
42
31
  :rtype: dictionary
43
32
 
@@ -53,16 +42,16 @@ class Price(dict):
53
42
  * ``args`` being a list of ``[quote, base]`` both being instances of ``str`` (``amount symbol``)
54
43
  * ``base`` and ``quote`` being instances of :class:`nectar.asset.Amount`
55
44
 
56
- This allows instanciations like:
45
+ This allows instantiations like:
57
46
 
58
- * ``Price("0.315 SBD/STEEM")``
59
- * ``Price(0.315, base="SBD", quote="STEEM")``
60
- * ``Price(0.315, base=Asset("SBD"), quote=Asset("STEEM"))``
61
- * ``Price({"base": {"amount": 1, "asset_id": "SBD"}, "quote": {"amount": 10, "asset_id": "SBD"}})``
62
- * ``Price(quote="10 STEEM", base="1 SBD")``
63
- * ``Price("10 STEEM", "1 SBD")``
64
- * ``Price(Amount("10 STEEM"), Amount("1 SBD"))``
65
- * ``Price(1.0, "SBD/STEEM")``
47
+ * ``Price("0.315 HBD/HIVE")``
48
+ * ``Price(0.315, base="HBD", quote="HIVE")``
49
+ * ``Price(0.315, base=Asset("HBD"), quote=Asset("HIVE"))``
50
+ * ``Price({"base": {"amount": 1, "asset_id": "HBD"}, "quote": {"amount": 10, "asset_id": "HBD"}})``
51
+ * ``Price(quote="10 HIVE", base="1 HBD")``
52
+ * ``Price("10 HIVE", "1 HBD")``
53
+ * ``Price(Amount("10 HIVE"), Amount("1 HBD"))``
54
+ * ``Price(1.0, "HBD/HIVE")``
66
55
 
67
56
  Instances of this class can be used in regular mathematical expressions
68
57
  (``+-*/%``) such as:
@@ -70,12 +59,12 @@ class Price(dict):
70
59
  .. code-block:: python
71
60
 
72
61
  >>> from nectar.price import Price
73
- >>> from nectar import Steem
74
- >>> stm = Steem("https://api.steemit.com")
75
- >>> Price("0.3314 SBD/STEEM", blockchain_instance=stm) * 2
76
- 0.662804 SBD/STEEM
77
- >>> Price(0.3314, "SBD", "STEEM", blockchain_instance=stm)
78
- 0.331402 SBD/STEEM
62
+ >>> from nectar import Hive
63
+ >>> hv = Hive("https://api.hive.blog")
64
+ >>> Price("0.3314 HBD/HIVE", blockchain_instance=hv) * 2
65
+ 0.662804 HBD/HIVE
66
+ >>> Price(0.3314, "HBD", "HIVE", blockchain_instance=hv)
67
+ 0.331402 HBD/HIVE
79
68
 
80
69
  """
81
70
 
@@ -86,13 +75,38 @@ class Price(dict):
86
75
  quote=None,
87
76
  base_asset=None, # to identify sell/buy
88
77
  blockchain_instance=None,
89
- **kwargs,
90
78
  ):
91
- if blockchain_instance is None:
92
- if kwargs.get("steem_instance"):
93
- blockchain_instance = kwargs["steem_instance"]
94
- elif kwargs.get("hive_instance"):
95
- blockchain_instance = kwargs["hive_instance"]
79
+ """
80
+ Initialize a Price object representing a ratio between a base and quote asset.
81
+
82
+ This constructor accepts multiple input forms and normalizes them into internal
83
+ "base" and "quote" Amount entries. Supported usages:
84
+ - price: str like "X BASE/QUOTE" with no base/quote: parses symbols and creates
85
+ Amounts from the fractional representation of X.
86
+ - price: dict with "base" and "quote": loads Amounts directly (raises AssertionError
87
+ if a top-level "price" key is present).
88
+ - price: numeric (float/int/Decimal) with base and quote provided as Asset or
89
+ symbol strings: converts the numeric value to a Fraction and builds Amounts.
90
+ - price: str representing an Amount and base: when price is a string and base is
91
+ a symbol string, price and base are used to build quote/base Amounts.
92
+ - price and base as Amount instances: accepts Amount objects directly.
93
+ - price is None with base and quote as symbol strings or Amounts: loads assets
94
+ or Amounts respectively.
95
+
96
+ Parameters (not exhaustive):
97
+ - price: numeric, str, dict, or Amount — the price or a representation used to
98
+ derive base/quote Amounts.
99
+ - base: Asset, Amount, or str — identifies the base side (or a symbol string
100
+ used to parse both symbols when combined with a numeric price).
101
+ - quote: Asset, Amount, or str — identifies the quote side.
102
+ - base_asset: optional; used only as an identifier flag for buy/sell contexts.
103
+ - blockchain_instance: blockchain context used to construct Asset/Amount (omitted
104
+ from param listing as a shared service).
105
+
106
+ Raises:
107
+ - AssertionError: if a dict `price` includes a top-level "price" key.
108
+ - ValueError: if the combination of inputs cannot be parsed into base and quote.
109
+ """
96
110
  self.blockchain = blockchain_instance or shared_blockchain_instance()
97
111
  if price == "":
98
112
  price = None
@@ -112,7 +126,7 @@ class Price(dict):
112
126
  elif price is not None and isinstance(price, dict) and "base" in price and "quote" in price:
113
127
  if "price" in price:
114
128
  raise AssertionError("You cannot provide a 'price' this way")
115
- # Regular 'price' objects according to steem-core
129
+ # Regular 'price' objects according to hive-core
116
130
  # base_id = price["base"]["asset_id"]
117
131
  # if price["base"]["asset_id"] == base_id:
118
132
  self["base"] = Amount(price["base"], blockchain_instance=self.blockchain)
@@ -201,18 +215,18 @@ class Price(dict):
201
215
  return self["base"]["symbol"], self["quote"]["symbol"]
202
216
 
203
217
  def as_base(self, base):
204
- """Returns the price instance so that the base asset is ``base``.
205
-
206
- .. note:: This makes a copy of the object!
218
+ """
219
+ Return a copy of this Price expressed with the given asset as the base.
207
220
 
208
- .. code-block:: python
221
+ If `base` matches the current base symbol this returns a shallow copy.
222
+ If `base` matches the current quote symbol this returns a copy with base and quote inverted.
223
+ Raises InvalidAssetException if `base` is neither the base nor the quote of this price.
209
224
 
210
- >>> from nectar.price import Price
211
- >>> from nectar import Steem
212
- >>> stm = Steem("https://api.steemit.com")
213
- >>> Price("0.3314 SBD/STEEM", blockchain_instance=stm).as_base("STEEM")
214
- 3.017483 STEEM/SBD
225
+ Parameters:
226
+ base (str): Asset symbol to use as the base (e.g., "HIVE" or "HBD").
215
227
 
228
+ Returns:
229
+ Price: A new Price instance whose base asset is `base`.
216
230
  """
217
231
  if base == self["base"]["symbol"]:
218
232
  return self.copy()
@@ -222,18 +236,21 @@ class Price(dict):
222
236
  raise InvalidAssetException
223
237
 
224
238
  def as_quote(self, quote):
225
- """Returns the price instance so that the quote asset is ``quote``.
239
+ """
240
+ Return a Price instance expressed with the given quote asset symbol.
226
241
 
227
- .. note:: This makes a copy of the object!
242
+ If `quote` matches the current quote symbol, returns a copy of this Price.
243
+ If `quote` matches the current base symbol, returns a copied, inverted Price.
244
+ A new object is always returned (the original is not modified).
228
245
 
229
- .. code-block:: python
246
+ Parameters:
247
+ quote (str): Asset symbol to use as the quote (e.g., "HBD" or "HIVE").
230
248
 
231
- >>> from nectar.price import Price
232
- >>> from nectar import Steem
233
- >>> stm = Steem("https://api.steemit.com")
234
- >>> Price("0.3314 SBD/STEEM", blockchain_instance=stm).as_quote("SBD")
235
- 3.017483 STEEM/SBD
249
+ Returns:
250
+ Price: A Price object with `quote` as the quote asset.
236
251
 
252
+ Raises:
253
+ InvalidAssetException: If `quote` does not match either the current base or quote symbol.
237
254
  """
238
255
  if quote == self["quote"]["symbol"]:
239
256
  return self.copy()
@@ -243,16 +260,18 @@ class Price(dict):
243
260
  raise InvalidAssetException
244
261
 
245
262
  def invert(self):
246
- """Invert the price (e.g. go from ``SBD/STEEM`` into ``STEEM/SBD``)
263
+ """
264
+ Invert the price in place, swapping base and quote assets (e.g., HBD/HIVE -> HIVE/HBD).
247
265
 
248
- .. code-block:: python
266
+ Returns:
267
+ self: The same Price instance after inversion.
249
268
 
269
+ Example:
250
270
  >>> from nectar.price import Price
251
- >>> from nectar import Steem
252
- >>> stm = Steem("https://api.steemit.com")
253
- >>> Price("0.3314 SBD/STEEM", blockchain_instance=stm).invert()
254
- 3.017483 STEEM/SBD
255
-
271
+ >>> from nectar import Hive
272
+ >>> hv = Hive("https://api.hive.blog")
273
+ >>> Price("0.3314 HBD/HIVE", blockchain_instance=hv).invert()
274
+ 3.017483 HIVE/HBD
256
275
  """
257
276
  tmp = self["quote"]
258
277
  self["quote"] = self["base"]
@@ -451,7 +470,7 @@ class Order(Price):
451
470
  ratio of base and quote) but instead has those amounts represent the
452
471
  amounts of an actual order!
453
472
 
454
- :param Steem blockchain_instance: Steem instance
473
+ :param Hive blockchain_instance: Hive instance
455
474
 
456
475
  .. note::
457
476
 
@@ -504,7 +523,7 @@ class FilledOrder(Price):
504
523
  ratio of base and quote) but instead has those amounts represent the
505
524
  amounts of an actually filled order!
506
525
 
507
- :param Steem blockchain_instance: Steem instance
526
+ :param Hive blockchain_instance: Hive instance
508
527
 
509
528
  .. note:: Instances of this class come with an additional ``date`` key
510
529
  that shows when the order has been filled!
nectar/profile.py CHANGED
@@ -39,12 +39,15 @@ class DotDict(dict):
39
39
 
40
40
  class Profile(DotDict):
41
41
  """This class is a template to model a user's on-chain
42
- profile according to
43
-
44
- * https://github.com/adcpm/steemscript
42
+ profile according to Hive profile metadata conventions.
45
43
  """
46
44
 
47
45
  def __init__(self, *args, **kwargs):
46
+ """
47
+ Initialize a Profile by delegating to the DotDict initializer.
48
+
49
+ This constructor accepts the same arguments as DotDict (e.g., dot-separated key/value pairs, a dict, or a JSON string) and performs no additional processing.
50
+ """
48
51
  super(Profile, self).__init__(*args, **kwargs)
49
52
 
50
53
  def __str__(self):