hive-nectar 0.0.2__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 (86) hide show
  1. hive_nectar-0.0.2.dist-info/METADATA +182 -0
  2. hive_nectar-0.0.2.dist-info/RECORD +86 -0
  3. hive_nectar-0.0.2.dist-info/WHEEL +4 -0
  4. hive_nectar-0.0.2.dist-info/entry_points.txt +2 -0
  5. hive_nectar-0.0.2.dist-info/licenses/LICENSE.txt +23 -0
  6. nectar/__init__.py +32 -0
  7. nectar/account.py +4371 -0
  8. nectar/amount.py +475 -0
  9. nectar/asciichart.py +270 -0
  10. nectar/asset.py +82 -0
  11. nectar/block.py +446 -0
  12. nectar/blockchain.py +1178 -0
  13. nectar/blockchaininstance.py +2284 -0
  14. nectar/blockchainobject.py +221 -0
  15. nectar/blurt.py +563 -0
  16. nectar/cli.py +6285 -0
  17. nectar/comment.py +1217 -0
  18. nectar/community.py +513 -0
  19. nectar/constants.py +111 -0
  20. nectar/conveyor.py +309 -0
  21. nectar/discussions.py +1709 -0
  22. nectar/exceptions.py +149 -0
  23. nectar/hive.py +546 -0
  24. nectar/hivesigner.py +420 -0
  25. nectar/imageuploader.py +72 -0
  26. nectar/instance.py +129 -0
  27. nectar/market.py +1013 -0
  28. nectar/memo.py +449 -0
  29. nectar/message.py +357 -0
  30. nectar/nodelist.py +444 -0
  31. nectar/price.py +557 -0
  32. nectar/profile.py +65 -0
  33. nectar/rc.py +308 -0
  34. nectar/snapshot.py +726 -0
  35. nectar/steem.py +582 -0
  36. nectar/storage.py +53 -0
  37. nectar/transactionbuilder.py +622 -0
  38. nectar/utils.py +545 -0
  39. nectar/version.py +2 -0
  40. nectar/vote.py +557 -0
  41. nectar/wallet.py +472 -0
  42. nectar/witness.py +617 -0
  43. nectarapi/__init__.py +11 -0
  44. nectarapi/exceptions.py +123 -0
  45. nectarapi/graphenerpc.py +589 -0
  46. nectarapi/node.py +178 -0
  47. nectarapi/noderpc.py +229 -0
  48. nectarapi/rpcutils.py +97 -0
  49. nectarapi/version.py +2 -0
  50. nectarbase/__init__.py +14 -0
  51. nectarbase/ledgertransactions.py +75 -0
  52. nectarbase/memo.py +243 -0
  53. nectarbase/objects.py +429 -0
  54. nectarbase/objecttypes.py +22 -0
  55. nectarbase/operationids.py +102 -0
  56. nectarbase/operations.py +1297 -0
  57. nectarbase/signedtransactions.py +48 -0
  58. nectarbase/transactions.py +11 -0
  59. nectarbase/version.py +2 -0
  60. nectargrapheneapi/__init__.py +6 -0
  61. nectargraphenebase/__init__.py +27 -0
  62. nectargraphenebase/account.py +846 -0
  63. nectargraphenebase/aes.py +52 -0
  64. nectargraphenebase/base58.py +192 -0
  65. nectargraphenebase/bip32.py +494 -0
  66. nectargraphenebase/bip38.py +134 -0
  67. nectargraphenebase/chains.py +149 -0
  68. nectargraphenebase/dictionary.py +3 -0
  69. nectargraphenebase/ecdsasig.py +326 -0
  70. nectargraphenebase/objects.py +123 -0
  71. nectargraphenebase/objecttypes.py +6 -0
  72. nectargraphenebase/operationids.py +3 -0
  73. nectargraphenebase/operations.py +23 -0
  74. nectargraphenebase/prefix.py +11 -0
  75. nectargraphenebase/py23.py +38 -0
  76. nectargraphenebase/signedtransactions.py +201 -0
  77. nectargraphenebase/types.py +419 -0
  78. nectargraphenebase/unsignedtransactions.py +283 -0
  79. nectargraphenebase/version.py +2 -0
  80. nectarstorage/__init__.py +38 -0
  81. nectarstorage/base.py +306 -0
  82. nectarstorage/exceptions.py +16 -0
  83. nectarstorage/interfaces.py +237 -0
  84. nectarstorage/masterpassword.py +239 -0
  85. nectarstorage/ram.py +30 -0
  86. nectarstorage/sqlite.py +334 -0
nectar/blurt.py ADDED
@@ -0,0 +1,563 @@
1
+ # -*- coding: utf-8 -*-
2
+ import logging
3
+ import math
4
+ from datetime import date, datetime, timezone
5
+
6
+ from nectar.blockchaininstance import BlockChainInstance
7
+ from nectar.constants import STEEM_100_PERCENT, STEEM_VOTE_REGENERATION_SECONDS
8
+ from nectargraphenebase.chains import known_chains
9
+ from nectargraphenebase.py23 import string_types
10
+
11
+ from .amount import Amount
12
+ from .utils import formatToTimeStamp
13
+
14
+ log = logging.getLogger(__name__)
15
+
16
+
17
+ class Blurt(BlockChainInstance):
18
+ """Connect to the Blurt network.
19
+
20
+ :param str node: Node to connect to *(optional)*
21
+ :param str rpcuser: RPC user *(optional)*
22
+ :param str rpcpassword: RPC password *(optional)*
23
+ :param bool nobroadcast: Do **not** broadcast a transaction!
24
+ *(optional)*
25
+ :param bool unsigned: Do **not** sign a transaction! *(optional)*
26
+ :param bool debug: Enable Debugging *(optional)*
27
+ :param keys: Predefine the wif keys to shortcut the
28
+ wallet database *(optional)*
29
+ :type keys: array, dict, string
30
+ :param wif: Predefine the wif keys to shortcut the
31
+ wallet database *(optional)*
32
+ :type wif: array, dict, string
33
+ :param bool offline: Boolean to prevent connecting to network (defaults
34
+ to ``False``) *(optional)*
35
+ :param int expiration: Delay in seconds until transactions are supposed
36
+ to expire *(optional)* (default is 30)
37
+ :param str blocking: Wait for broadcasted transactions to be included
38
+ in a block and return full transaction (can be "head" or
39
+ "irreversible")
40
+ :param bool bundle: Do not broadcast transactions right away, but allow
41
+ to bundle operations. It is not possible to send out more than one
42
+ vote operation and more than one comment operation in a single broadcast *(optional)*
43
+ :param bool appbase: Use the new appbase rpc protocol on nodes with version
44
+ 0.19.4 or higher. The settings has no effect on nodes with version of 0.19.3 or lower.
45
+ :param int num_retries: Set the maximum number of reconnects to the nodes before
46
+ NumRetriesReached is raised. Disabled for -1. (default is -1)
47
+ :param int num_retries_call: Repeat num_retries_call times a rpc call on node error (default is 5)
48
+ :param int timeout: Timeout setting for https nodes (default is 60)
49
+ :param bool use_sc2: When True, a steemconnect object is created. Can be used for
50
+ broadcast posting op or creating hot_links (default is False)
51
+ :param SteemConnect steemconnect: A SteemConnect object can be set manually, set use_sc2 to True
52
+ :param dict custom_chains: custom chain which should be added to the known chains
53
+
54
+ Three wallet operation modes are possible:
55
+
56
+ * **Wallet Database**: Here, the steemlibs load the keys from the
57
+ locally stored wallet SQLite database (see ``storage.py``).
58
+ To use this mode, simply call ``Steem()`` without the
59
+ ``keys`` parameter
60
+ * **Providing Keys**: Here, you can provide the keys for
61
+ your accounts manually. All you need to do is add the wif
62
+ keys for the accounts you want to use as a simple array
63
+ using the ``keys`` parameter to ``Steem()``.
64
+ * **Force keys**: This more is for advanced users and
65
+ requires that you know what you are doing. Here, the
66
+ ``keys`` parameter is a dictionary that overwrite the
67
+ ``active``, ``owner``, ``posting`` or ``memo`` keys for
68
+ any account. This mode is only used for *foreign*
69
+ signatures!
70
+
71
+ If no node is provided, it will connect to default nodes of
72
+ http://geo.steem.pl. Default settings can be changed with:
73
+
74
+ .. code-block:: python
75
+
76
+ blurt = Blurt(<host>)
77
+
78
+ where ``<host>`` starts with ``https://``, ``ws://`` or ``wss://``.
79
+
80
+ The purpose of this class it to simplify interaction with
81
+ Blurt.
82
+
83
+ The idea is to have a class that allows to do this:
84
+
85
+ .. code-block:: python
86
+
87
+ >>> from nectar import Blurt
88
+ >>> blurt = Blurt()
89
+ >>> print(blurt.get_blockchain_version()) # doctest: +SKIP
90
+
91
+ This class also deals with edits, votes and reading content.
92
+
93
+ Example for adding a custom chain:
94
+
95
+ .. code-block:: python
96
+
97
+ from nectar import Steem
98
+ stm = Steem(node=["https://mytstnet.com"], custom_chains={"MYTESTNET":
99
+ {'chain_assets': [{'asset': 'SBD', 'id': 0, 'precision': 3, 'symbol': 'SBD'},
100
+ {'asset': 'STEEM', 'id': 1, 'precision': 3, 'symbol': 'STEEM'},
101
+ {'asset': 'VESTS', 'id': 2, 'precision': 6, 'symbol': 'VESTS'}],
102
+ 'chain_id': '79276aea5d4877d9a25892eaa01b0adf019d3e5cb12a97478df3298ccdd01674',
103
+ 'min_version': '0.0.0',
104
+ 'prefix': 'MTN'}
105
+ }
106
+ )
107
+
108
+ """
109
+
110
+ def get_network(self, use_stored_data=True, config=None):
111
+ """Identify the network
112
+
113
+ :param bool use_stored_data: if True, stored data will be returned. If stored data are
114
+ empty or old, refresh_data() is used.
115
+
116
+ :returns: Network parameters
117
+ :rtype: dictionary
118
+ """
119
+ if use_stored_data:
120
+ self.refresh_data("config")
121
+ return self.data["network"]
122
+
123
+ if self.rpc is None:
124
+ return known_chains["BLURT"]
125
+ try:
126
+ return self.rpc.get_network(props=config)
127
+ except:
128
+ return known_chains["BLURT"]
129
+
130
+ def rshares_to_token_backed_dollar(
131
+ self, rshares, not_broadcasted_vote=False, use_stored_data=True
132
+ ):
133
+ return self.rshares_to_bbd(
134
+ rshares, not_broadcasted_vote=not_broadcasted_vote, use_stored_data=use_stored_data
135
+ )
136
+
137
+ def rshares_to_bbd(self, rshares, not_broadcasted_vote=False, use_stored_data=True):
138
+ """Calculates the current SBD value of a vote"""
139
+ payout = float(rshares) * self.get_bbd_per_rshares(
140
+ use_stored_data=use_stored_data,
141
+ not_broadcasted_vote_rshares=rshares if not_broadcasted_vote else 0,
142
+ )
143
+ return payout
144
+
145
+ def get_bbd_per_rshares(self, not_broadcasted_vote_rshares=0, use_stored_data=True):
146
+ """Returns the current rshares to SBD ratio"""
147
+ reward_fund = self.get_reward_funds(use_stored_data=use_stored_data)
148
+ reward_balance = float(Amount(reward_fund["reward_balance"], blockchain_instance=self))
149
+ recent_claims = float(reward_fund["recent_claims"]) + not_broadcasted_vote_rshares
150
+
151
+ fund_per_share = reward_balance / (recent_claims)
152
+ median_price = self.get_median_price(use_stored_data=use_stored_data)
153
+ if median_price is None:
154
+ return 0
155
+ return fund_per_share
156
+
157
+ def get_blurt_per_mvest(self, time_stamp=None, use_stored_data=True):
158
+ """Returns the MVEST to BLURT ratio
159
+
160
+ :param int time_stamp: (optional) if set, return an estimated
161
+ BLURT per MVEST ratio for the given time stamp. If unset the
162
+ current ratio is returned (default). (can also be a datetime object)
163
+ """
164
+ if self.offline and time_stamp is None:
165
+ time_stamp = datetime.now(timezone.utc)
166
+
167
+ if time_stamp is not None:
168
+ if isinstance(time_stamp, (datetime, date)):
169
+ time_stamp = formatToTimeStamp(time_stamp)
170
+ a = 2.1325476281078992e-05
171
+ b = -31099.685481490847
172
+ a2 = 2.9019227739473682e-07
173
+ b2 = 48.41432402074669
174
+
175
+ if time_stamp < (b2 - b) / (a - a2):
176
+ return a * time_stamp + b
177
+ else:
178
+ return a2 * time_stamp + b2
179
+ global_properties = self.get_dynamic_global_properties(use_stored_data=use_stored_data)
180
+
181
+ return float(
182
+ Amount(global_properties["total_vesting_fund_blurt"], blockchain_instance=self)
183
+ ) / (
184
+ float(Amount(global_properties["total_vesting_shares"], blockchain_instance=self)) / 1e6
185
+ )
186
+
187
+ def vests_to_bp(self, vests, timestamp=None, use_stored_data=True):
188
+ """Converts vests to BP
189
+
190
+ :param amount.Amount vests/float vests: Vests to convert
191
+ :param int timestamp: (Optional) Can be used to calculate
192
+ the conversion rate from the past
193
+
194
+ """
195
+ if isinstance(vests, Amount):
196
+ vests = float(vests)
197
+ return (
198
+ float(vests)
199
+ / 1e6
200
+ * self.get_blurt_per_mvest(timestamp, use_stored_data=use_stored_data)
201
+ )
202
+
203
+ def bp_to_vests(self, sp, timestamp=None, use_stored_data=True):
204
+ """Converts BP to vests
205
+
206
+ :param float bp: Blurt power to convert
207
+ :param datetime timestamp: (Optional) Can be used to calculate
208
+ the conversion rate from the past
209
+ """
210
+ return sp * 1e6 / self.get_blurt_per_mvest(timestamp, use_stored_data=use_stored_data)
211
+
212
+ def vests_to_token_power(self, vests, timestamp=None, use_stored_data=True):
213
+ return self.vests_to_bp(vests, timestamp=timestamp, use_stored_data=use_stored_data)
214
+
215
+ def token_power_to_vests(self, token_power, timestamp=None, use_stored_data=True):
216
+ return self.bp_to_vests(token_power, timestamp=timestamp, use_stored_data=use_stored_data)
217
+
218
+ def get_token_per_mvest(self, time_stamp=None, use_stored_data=True):
219
+ return self.get_blurt_per_mvest(time_stamp=time_stamp, use_stored_data=use_stored_data)
220
+
221
+ def token_power_to_token_backed_dollar(
222
+ self,
223
+ token_power,
224
+ post_rshares=0,
225
+ voting_power=STEEM_100_PERCENT,
226
+ vote_pct=STEEM_100_PERCENT,
227
+ not_broadcasted_vote=True,
228
+ use_stored_data=True,
229
+ ):
230
+ return self.bp_to_bbd(
231
+ token_power,
232
+ post_rshares=post_rshares,
233
+ voting_power=voting_power,
234
+ vote_pct=vote_pct,
235
+ not_broadcasted_vote=not_broadcasted_vote,
236
+ use_stored_data=use_stored_data,
237
+ )
238
+
239
+ def bp_to_bbd(
240
+ self,
241
+ sp,
242
+ post_rshares=0,
243
+ voting_power=STEEM_100_PERCENT,
244
+ vote_pct=STEEM_100_PERCENT,
245
+ not_broadcasted_vote=True,
246
+ use_stored_data=True,
247
+ ):
248
+ """Obtain the resulting equivalent BBD vote value from Blurt power
249
+
250
+ :param number steem_power: Blurt Power
251
+ :param int post_rshares: rshares of post which is voted
252
+ :param int voting_power: voting power (100% = 10000)
253
+ :param int vote_pct: voting percentage (100% = 10000)
254
+ :param bool not_broadcasted_vote: not_broadcasted or already broadcasted vote (True = not_broadcasted vote).
255
+
256
+ Only impactful for very big votes. Slight modification to the value calculation, as the not_broadcasted
257
+ vote rshares decreases the reward pool.
258
+ """
259
+ vesting_shares = int(self.bp_to_vests(sp, use_stored_data=use_stored_data))
260
+ return self.vests_to_bbd(
261
+ vesting_shares,
262
+ post_rshares=post_rshares,
263
+ voting_power=voting_power,
264
+ vote_pct=vote_pct,
265
+ not_broadcasted_vote=not_broadcasted_vote,
266
+ use_stored_data=use_stored_data,
267
+ )
268
+
269
+ def vests_to_bbd(
270
+ self,
271
+ vests,
272
+ post_rshares=0,
273
+ voting_power=STEEM_100_PERCENT,
274
+ vote_pct=STEEM_100_PERCENT,
275
+ not_broadcasted_vote=True,
276
+ use_stored_data=True,
277
+ ):
278
+ """Obtain the resulting BBD vote value from vests
279
+
280
+ :param number vests: vesting shares
281
+ :param int post_rshares: rshares of post which is voted
282
+ :param int voting_power: voting power (100% = 10000)
283
+ :param int vote_pct: voting percentage (100% = 10000)
284
+ :param bool not_broadcasted_vote: not_broadcasted or already broadcasted vote (True = not_broadcasted vote).
285
+
286
+ Only impactful for very big votes. Slight modification to the value calculation, as the not_broadcasted
287
+ vote rshares decreases the reward pool.
288
+ """
289
+ vote_rshares = self.vests_to_rshares(
290
+ vests, post_rshares=post_rshares, voting_power=voting_power, vote_pct=vote_pct
291
+ )
292
+ return self.rshares_to_bbd(
293
+ vote_rshares, not_broadcasted_vote=not_broadcasted_vote, use_stored_data=use_stored_data
294
+ )
295
+
296
+ def _max_vote_denom(self, use_stored_data=True):
297
+ # get props
298
+ global_properties = self.get_dynamic_global_properties(use_stored_data=use_stored_data)
299
+ vote_power_reserve_rate = global_properties["vote_power_reserve_rate"]
300
+ max_vote_denom = vote_power_reserve_rate * STEEM_VOTE_REGENERATION_SECONDS
301
+ return max_vote_denom
302
+
303
+ def _calc_resulting_vote(
304
+ self, voting_power=STEEM_100_PERCENT, vote_pct=STEEM_100_PERCENT, use_stored_data=True
305
+ ):
306
+ # determine voting power used
307
+ used_power = int((voting_power * abs(vote_pct)) / STEEM_100_PERCENT * (60 * 60 * 24))
308
+ max_vote_denom = self._max_vote_denom(use_stored_data=use_stored_data)
309
+ used_power = int((used_power + max_vote_denom - 1) / max_vote_denom)
310
+ return used_power
311
+
312
+ def bp_to_rshares(
313
+ self,
314
+ steem_power,
315
+ post_rshares=0,
316
+ voting_power=STEEM_100_PERCENT,
317
+ vote_pct=STEEM_100_PERCENT,
318
+ use_stored_data=True,
319
+ ):
320
+ """Obtain the r-shares from Steem power
321
+
322
+ :param number steem_power: Steem Power
323
+ :param int post_rshares: rshares of post which is voted
324
+ :param int voting_power: voting power (100% = 10000)
325
+ :param int vote_pct: voting percentage (100% = 10000)
326
+
327
+ """
328
+ # calculate our account voting shares (from vests)
329
+ vesting_shares = int(self.bp_to_vests(steem_power, use_stored_data=use_stored_data))
330
+ return self.vests_to_rshares(
331
+ vesting_shares,
332
+ post_rshares=post_rshares,
333
+ voting_power=voting_power,
334
+ vote_pct=vote_pct,
335
+ use_stored_data=use_stored_data,
336
+ )
337
+
338
+ def vests_to_rshares(
339
+ self,
340
+ vests,
341
+ post_rshares=0,
342
+ voting_power=STEEM_100_PERCENT,
343
+ vote_pct=STEEM_100_PERCENT,
344
+ subtract_dust_threshold=True,
345
+ use_stored_data=True,
346
+ ):
347
+ """Obtain the r-shares from vests
348
+
349
+ :param number vests: vesting shares
350
+ :param int post_rshares: rshares of post which is voted
351
+ :param int voting_power: voting power (100% = 10000)
352
+ :param int vote_pct: voting percentage (100% = 10000)
353
+
354
+ """
355
+ used_power = self._calc_resulting_vote(
356
+ voting_power=voting_power, vote_pct=vote_pct, use_stored_data=use_stored_data
357
+ )
358
+ # calculate vote rshares
359
+ rshares = int(math.copysign(vests * 1e6 * used_power / STEEM_100_PERCENT, vote_pct))
360
+ if subtract_dust_threshold:
361
+ if abs(rshares) <= self.get_dust_threshold(use_stored_data=use_stored_data):
362
+ return 0
363
+ rshares -= math.copysign(
364
+ self.get_dust_threshold(use_stored_data=use_stored_data), vote_pct
365
+ )
366
+ rshares = self._calc_vote_claim(rshares, post_rshares)
367
+ return rshares
368
+
369
+ def bbd_to_rshares(self, sbd, not_broadcasted_vote=False, use_stored_data=True):
370
+ """Obtain the r-shares from SBD
371
+
372
+ :param sbd: SBD
373
+ :type sbd: str, int, amount.Amount
374
+ :param bool not_broadcasted_vote: not_broadcasted or already broadcasted vote (True = not_broadcasted vote).
375
+ Only impactful for very high amounts of SBD. Slight modification to the value calculation, as the not_broadcasted
376
+ vote rshares decreases the reward pool.
377
+
378
+ """
379
+ if isinstance(sbd, Amount):
380
+ sbd = Amount(sbd, blockchain_instance=self)
381
+ elif isinstance(sbd, string_types):
382
+ sbd = Amount(sbd, blockchain_instance=self)
383
+ else:
384
+ sbd = Amount(sbd, self.token_symbol, blockchain_instance=self)
385
+ if sbd["symbol"] != self.token_symbol:
386
+ raise AssertionError("Should input Blurt, not any other asset!")
387
+
388
+ # If the vote was already broadcasted we can assume the blockchain values to be true
389
+ if not not_broadcasted_vote:
390
+ return int(float(sbd) / self.get_bbd_per_rshares(use_stored_data=use_stored_data))
391
+
392
+ # If the vote wasn't broadcasted (yet), we have to calculate the rshares while considering
393
+ # the change our vote is causing to the recent_claims. This is more important for really
394
+ # big votes which have a significant impact on the recent_claims.
395
+ reward_fund = self.get_reward_funds(use_stored_data=use_stored_data)
396
+ median_price = self.get_median_price(use_stored_data=use_stored_data)
397
+ recent_claims = int(reward_fund["recent_claims"])
398
+ reward_balance = Amount(reward_fund["reward_balance"], blockchain_instance=self)
399
+ reward_pool_sbd = median_price * reward_balance
400
+ if sbd > reward_pool_sbd:
401
+ raise ValueError("Provided more SBD than available in the reward pool.")
402
+
403
+ # This is the formula we can use to determine the "true" rshares.
404
+ # We get this formula by some math magic using the previous used formulas
405
+ # FundsPerShare = (balance / (claims + newShares)) * Price
406
+ # newShares = amount / FundsPerShare
407
+ # We can now resolve both formulas for FundsPerShare and set the formulas to be equal
408
+ # (balance / (claims + newShares)) * price = amount / newShares
409
+ # Now we resolve for newShares resulting in:
410
+ # newShares = claims * amount / (balance * price - amount)
411
+ rshares = (
412
+ recent_claims
413
+ * float(sbd)
414
+ / ((float(reward_balance) * float(median_price)) - float(sbd))
415
+ )
416
+ return int(rshares)
417
+
418
+ def rshares_to_vote_pct(
419
+ self,
420
+ rshares,
421
+ post_rshares=0,
422
+ steem_power=None,
423
+ vests=None,
424
+ voting_power=STEEM_100_PERCENT,
425
+ use_stored_data=True,
426
+ ):
427
+ """Obtain the voting percentage for a desired rshares value
428
+ for a given Steem Power or vesting shares and voting_power
429
+ Give either steem_power or vests, not both.
430
+ When the output is greater than 10000 or less than -10000,
431
+ the given absolute rshares are too high
432
+
433
+ Returns the required voting percentage (100% = 10000)
434
+
435
+ :param number rshares: desired rshares value
436
+ :param number steem_power: Steem Power
437
+ :param number vests: vesting shares
438
+ :param int voting_power: voting power (100% = 10000)
439
+
440
+ """
441
+ if steem_power is None and vests is None:
442
+ raise ValueError("Either steem_power or vests has to be set!")
443
+ if steem_power is not None and vests is not None:
444
+ raise ValueError("Either steem_power or vests has to be set. Not both!")
445
+ if steem_power is not None:
446
+ vests = int(self.bp_to_vests(steem_power, use_stored_data=use_stored_data) * 1e6)
447
+
448
+ if self.hardfork >= 20:
449
+ rshares += math.copysign(
450
+ self.get_dust_threshold(use_stored_data=use_stored_data), rshares
451
+ )
452
+
453
+ if post_rshares >= 0 and rshares > 0:
454
+ rshares = math.copysign(
455
+ self._calc_revert_vote_claim(abs(rshares), post_rshares), rshares
456
+ )
457
+ elif post_rshares < 0 and rshares < 0:
458
+ rshares = math.copysign(
459
+ self._calc_revert_vote_claim(abs(rshares), abs(post_rshares)), rshares
460
+ )
461
+ elif post_rshares < 0 and rshares > 0:
462
+ rshares = math.copysign(self._calc_revert_vote_claim(abs(rshares), 0), rshares)
463
+ elif post_rshares > 0 and rshares < 0:
464
+ rshares = math.copysign(
465
+ self._calc_revert_vote_claim(abs(rshares), post_rshares), rshares
466
+ )
467
+
468
+ max_vote_denom = self._max_vote_denom(use_stored_data=use_stored_data)
469
+
470
+ used_power = int(math.ceil(abs(rshares) * STEEM_100_PERCENT / vests))
471
+ used_power = used_power * max_vote_denom
472
+
473
+ vote_pct = used_power * STEEM_100_PERCENT / (60 * 60 * 24) / voting_power
474
+ return int(math.copysign(vote_pct, rshares))
475
+
476
+ def bbd_to_vote_pct(
477
+ self,
478
+ sbd,
479
+ post_rshares=0,
480
+ steem_power=None,
481
+ vests=None,
482
+ voting_power=STEEM_100_PERCENT,
483
+ not_broadcasted_vote=True,
484
+ use_stored_data=True,
485
+ ):
486
+ """Obtain the voting percentage for a desired SBD value
487
+ for a given Steem Power or vesting shares and voting power
488
+ Give either Steem Power or vests, not both.
489
+ When the output is greater than 10000 or smaller than -10000,
490
+ the SBD value is too high.
491
+
492
+ Returns the required voting percentage (100% = 10000)
493
+
494
+ :param sbd: desired SBD value
495
+ :type sbd: str, int, amount.Amount
496
+ :param number steem_power: Steem Power
497
+ :param number vests: vesting shares
498
+ :param bool not_broadcasted_vote: not_broadcasted or already broadcasted vote (True = not_broadcasted vote).
499
+ Only impactful for very high amounts of SBD. Slight modification to the value calculation, as the not_broadcasted
500
+ vote rshares decreases the reward pool.
501
+
502
+ """
503
+ if isinstance(sbd, Amount):
504
+ sbd = Amount(sbd, blockchain_instance=self)
505
+ elif isinstance(sbd, string_types):
506
+ sbd = Amount(sbd, blockchain_instance=self)
507
+ else:
508
+ sbd = Amount(sbd, self.token_symbol, blockchain_instance=self)
509
+ if sbd["symbol"] != self.token_symbol:
510
+ raise AssertionError()
511
+ rshares = self.bbd_to_rshares(
512
+ sbd, not_broadcasted_vote=not_broadcasted_vote, use_stored_data=use_stored_data
513
+ )
514
+ return self.rshares_to_vote_pct(
515
+ rshares,
516
+ post_rshares=post_rshares,
517
+ steem_power=steem_power,
518
+ vests=vests,
519
+ voting_power=voting_power,
520
+ use_stored_data=use_stored_data,
521
+ )
522
+
523
+ @property
524
+ def chain_params(self):
525
+ if self.offline or self.rpc is None:
526
+ return known_chains["BLURT"]
527
+ else:
528
+ return self.get_network()
529
+
530
+ @property
531
+ def hardfork(self):
532
+ if self.offline or self.rpc is None:
533
+ versions = known_chains["BLURT"]["min_version"]
534
+ else:
535
+ hf_prop = self.get_hardfork_properties()
536
+ if "current_hardfork_version" in hf_prop:
537
+ versions = hf_prop["current_hardfork_version"]
538
+ else:
539
+ versions = self.get_blockchain_version()
540
+ return int(versions.split(".")[1])
541
+
542
+ @property
543
+ def is_blurt(self):
544
+ config = self.get_config()
545
+ if config is None:
546
+ return True
547
+ return "BLURT_CHAIN_ID" in self.get_config()
548
+
549
+ @property
550
+ def bbd_symbol(self):
551
+ """get the current chains symbol for SBD (e.g. "TBD" on testnet)"""
552
+ # some networks (e.g. whaleshares) do not have SBD
553
+ return None
554
+
555
+ @property
556
+ def steem_symbol(self):
557
+ """get the current chains symbol for STEEM (e.g. "TESTS" on testnet)"""
558
+ return self._get_asset_symbol(1)
559
+
560
+ @property
561
+ def vests_symbol(self):
562
+ """get the current chains symbol for VESTS"""
563
+ return self._get_asset_symbol(2)