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.
- {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/METADATA +10 -11
- hive_nectar-0.1.0.dist-info/RECORD +88 -0
- nectar/__init__.py +1 -4
- nectar/account.py +791 -685
- nectar/amount.py +82 -21
- nectar/asset.py +1 -2
- nectar/block.py +34 -22
- nectar/blockchain.py +111 -143
- nectar/blockchaininstance.py +396 -247
- nectar/blockchainobject.py +33 -5
- nectar/cli.py +1058 -1349
- nectar/comment.py +313 -181
- nectar/community.py +39 -43
- nectar/constants.py +1 -14
- nectar/discussions.py +793 -139
- nectar/hive.py +137 -77
- nectar/hivesigner.py +106 -68
- nectar/imageuploader.py +33 -23
- nectar/instance.py +31 -79
- nectar/market.py +128 -264
- nectar/memo.py +40 -13
- nectar/message.py +23 -10
- nectar/nodelist.py +115 -81
- nectar/price.py +80 -61
- nectar/profile.py +6 -3
- nectar/rc.py +45 -25
- nectar/snapshot.py +285 -163
- nectar/storage.py +16 -5
- nectar/transactionbuilder.py +132 -41
- nectar/utils.py +37 -17
- nectar/version.py +1 -1
- nectar/vote.py +171 -30
- nectar/wallet.py +26 -19
- nectar/witness.py +153 -54
- nectarapi/graphenerpc.py +147 -133
- nectarapi/noderpc.py +12 -6
- nectarapi/rpcutils.py +12 -6
- nectarapi/version.py +1 -1
- nectarbase/ledgertransactions.py +24 -1
- nectarbase/objects.py +17 -6
- nectarbase/operations.py +160 -90
- nectarbase/signedtransactions.py +38 -2
- nectarbase/version.py +1 -1
- nectargraphenebase/account.py +295 -17
- nectargraphenebase/chains.py +0 -135
- nectargraphenebase/ecdsasig.py +152 -176
- nectargraphenebase/types.py +18 -4
- nectargraphenebase/unsignedtransactions.py +1 -1
- nectargraphenebase/version.py +1 -1
- hive_nectar-0.0.11.dist-info/RECORD +0 -91
- nectar/blurt.py +0 -562
- nectar/conveyor.py +0 -308
- nectar/steem.py +0 -581
- {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/WHEEL +0 -0
- {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/entry_points.txt +0 -0
- {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/licenses/LICENSE.txt +0 -0
nectar/conveyor.py
DELETED
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
import base64
|
|
3
|
-
import hashlib
|
|
4
|
-
import json
|
|
5
|
-
import random
|
|
6
|
-
import struct
|
|
7
|
-
from binascii import hexlify
|
|
8
|
-
from datetime import datetime, timezone
|
|
9
|
-
|
|
10
|
-
import requests
|
|
11
|
-
|
|
12
|
-
from nectargraphenebase.ecdsasig import sign_message
|
|
13
|
-
|
|
14
|
-
from .account import Account
|
|
15
|
-
from .instance import shared_blockchain_instance
|
|
16
|
-
|
|
17
|
-
try:
|
|
18
|
-
from urllib.parse import urljoin
|
|
19
|
-
except ImportError:
|
|
20
|
-
from urlparse import urljoin
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class Conveyor(object):
|
|
24
|
-
"""Class to access Steemit Conveyor instances:
|
|
25
|
-
https://github.com/steemit/conveyor
|
|
26
|
-
|
|
27
|
-
Description from the official documentation:
|
|
28
|
-
|
|
29
|
-
* Feature flags: "Feature flags allows our apps (condenser mainly) to
|
|
30
|
-
hide certain features behind flags."
|
|
31
|
-
* User data: "Conveyor is the central point for storing sensitive user
|
|
32
|
-
data (email, phone, etc). No other services should store this data
|
|
33
|
-
and should instead query for it here every time."
|
|
34
|
-
* User tags: "Tagging mechanism for other services, allows defining and
|
|
35
|
-
assigning tags to accounts (or other identifiers) and querying for
|
|
36
|
-
them."
|
|
37
|
-
|
|
38
|
-
Not contained in the documentation, but implemented and working:
|
|
39
|
-
|
|
40
|
-
* Draft handling: saving, listing and removing post drafts
|
|
41
|
-
consisting of a post title and a body.
|
|
42
|
-
|
|
43
|
-
The underlying RPC authentication and request signing procedure is
|
|
44
|
-
described here: https://github.com/steemit/rpc-auth
|
|
45
|
-
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
def __init__(self, url="https://conveyor.steemit.com", blockchain_instance=None, **kwargs):
|
|
49
|
-
"""Initialize a Conveyor instance
|
|
50
|
-
:param str url: (optional) URL to the Conveyor API, defaults to
|
|
51
|
-
https://conveyor.steemit.com
|
|
52
|
-
:param nectar.steem.Steem blockchain_instance: Steem instance
|
|
53
|
-
|
|
54
|
-
"""
|
|
55
|
-
|
|
56
|
-
self.url = url
|
|
57
|
-
if blockchain_instance is None:
|
|
58
|
-
if kwargs.get("steem_instance"):
|
|
59
|
-
blockchain_instance = kwargs["steem_instance"]
|
|
60
|
-
elif kwargs.get("hive_instance"):
|
|
61
|
-
blockchain_instance = kwargs["hive_instance"]
|
|
62
|
-
self.steem = blockchain_instance or shared_blockchain_instance()
|
|
63
|
-
self.id = 0
|
|
64
|
-
self.ENCODING = "utf-8"
|
|
65
|
-
self.TIMEFORMAT = "%Y-%m-%dT%H:%M:%S.%f"
|
|
66
|
-
self.K = hashlib.sha256(bytes("steem_jsonrpc_auth", self.ENCODING)).digest()
|
|
67
|
-
|
|
68
|
-
def prehash_message(self, timestamp, account, method, params, nonce):
|
|
69
|
-
"""Prepare a hash for the Conveyor API request with SHA256 according
|
|
70
|
-
to https://github.com/steemit/rpc-auth
|
|
71
|
-
Hashing of `second` is then done inside `ecdsasig.sign_message()`.
|
|
72
|
-
|
|
73
|
-
:param str timestamp: valid iso8601 datetime ending in "Z"
|
|
74
|
-
:param str account: valid steem blockchain account name
|
|
75
|
-
:param str method: Conveyor method name to be called
|
|
76
|
-
:param bytes param: base64 encoded request parameters
|
|
77
|
-
:param bytes nonce: random 8 bytes
|
|
78
|
-
|
|
79
|
-
"""
|
|
80
|
-
first = hashlib.sha256(bytes(timestamp + account + method + params, self.ENCODING))
|
|
81
|
-
return self.K + first.digest() + nonce
|
|
82
|
-
|
|
83
|
-
def _request(self, account, method, params, key):
|
|
84
|
-
"""Assemble the request, hash it, sign it and send it to the Conveyor
|
|
85
|
-
instance. Returns the server response as JSON.
|
|
86
|
-
|
|
87
|
-
:param str account: account name
|
|
88
|
-
:param str method: Conveyor method name to be called
|
|
89
|
-
:param dict params: request parameters as `dict`
|
|
90
|
-
:param str key: Steem posting key for signing
|
|
91
|
-
|
|
92
|
-
"""
|
|
93
|
-
params_bytes = bytes(json.dumps(params), self.ENCODING)
|
|
94
|
-
params_enc = base64.b64encode(params_bytes).decode(self.ENCODING)
|
|
95
|
-
timestamp = datetime.now(timezone.utc).strftime(self.TIMEFORMAT)[:-3] + "Z"
|
|
96
|
-
nonce_int = random.getrandbits(64)
|
|
97
|
-
nonce_bytes = struct.pack(">Q", nonce_int) # 64bit ULL, big endian
|
|
98
|
-
nonce_str = "%016x" % (nonce_int)
|
|
99
|
-
|
|
100
|
-
message = self.prehash_message(timestamp, account, method, params_enc, nonce_bytes)
|
|
101
|
-
signature = sign_message(message, key)
|
|
102
|
-
signature_hex = hexlify(signature).decode(self.ENCODING)
|
|
103
|
-
|
|
104
|
-
request = {
|
|
105
|
-
"jsonrpc": "2.0",
|
|
106
|
-
"id": self.id,
|
|
107
|
-
"method": method,
|
|
108
|
-
"params": {
|
|
109
|
-
"__signed": {
|
|
110
|
-
"account": account,
|
|
111
|
-
"nonce": nonce_str,
|
|
112
|
-
"params": params_enc,
|
|
113
|
-
"signatures": [signature_hex],
|
|
114
|
-
"timestamp": timestamp,
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
}
|
|
118
|
-
r = requests.post(self.url, data=json.dumps(request))
|
|
119
|
-
self.id += 1
|
|
120
|
-
return r.json()
|
|
121
|
-
|
|
122
|
-
def _conveyor_method(self, account, signing_account, method, params):
|
|
123
|
-
"""Wrapper function to handle account and key lookups
|
|
124
|
-
|
|
125
|
-
:param str account: name of the addressed account
|
|
126
|
-
:param str signing_account: name of the account to sign the request
|
|
127
|
-
:param method: Conveyor method name to be called
|
|
128
|
-
:params dict params: request parameters as `dict`
|
|
129
|
-
|
|
130
|
-
"""
|
|
131
|
-
account = Account(account, blockchain_instance=self.steem)
|
|
132
|
-
if signing_account is None:
|
|
133
|
-
signer = account
|
|
134
|
-
else:
|
|
135
|
-
signer = Account(signing_account, blockchain_instance=self.steem)
|
|
136
|
-
if "posting" not in signer:
|
|
137
|
-
signer.refresh()
|
|
138
|
-
if "posting" not in signer:
|
|
139
|
-
raise AssertionError("Could not access posting permission")
|
|
140
|
-
for authority in signer["posting"]["key_auths"]:
|
|
141
|
-
posting_wif = self.steem.wallet.getPrivateKeyForPublicKey(authority[0])
|
|
142
|
-
return self._request(account["name"], method, params, posting_wif)
|
|
143
|
-
|
|
144
|
-
def get_user_data(self, account, signing_account=None):
|
|
145
|
-
"""Get the account's email address and phone number. The request has to be
|
|
146
|
-
signed by the requested account or an admin account.
|
|
147
|
-
|
|
148
|
-
:param str account: requested account
|
|
149
|
-
:param str signing_account: (optional) account to sign the
|
|
150
|
-
request. If unset, `account` is used.
|
|
151
|
-
|
|
152
|
-
Example:
|
|
153
|
-
|
|
154
|
-
.. code-block:: python
|
|
155
|
-
|
|
156
|
-
from nectar import Steem
|
|
157
|
-
from nectar.conveyor import Conveyor
|
|
158
|
-
s = Steem(keys=["5JPOSTINGKEY"])
|
|
159
|
-
c = Conveyor(blockchain_instance=s)
|
|
160
|
-
print(c.get_user_data('accountname'))
|
|
161
|
-
|
|
162
|
-
"""
|
|
163
|
-
account = Account(account, blockchain_instance=self.steem)
|
|
164
|
-
user_data = self._conveyor_method(
|
|
165
|
-
account, signing_account, "conveyor.get_user_data", [account["name"]]
|
|
166
|
-
)
|
|
167
|
-
if "result" in user_data:
|
|
168
|
-
return user_data["result"]
|
|
169
|
-
else:
|
|
170
|
-
return user_data
|
|
171
|
-
|
|
172
|
-
def set_user_data(self, account, params, signing_account=None):
|
|
173
|
-
"""Set the account's email address and phone number. The request has to be
|
|
174
|
-
signed by an admin account.
|
|
175
|
-
|
|
176
|
-
:param str account: requested account
|
|
177
|
-
:param dict param: user data to be set
|
|
178
|
-
:param str signing_account: (optional) account to sign the
|
|
179
|
-
request. If unset, `account` is used.
|
|
180
|
-
|
|
181
|
-
Example:
|
|
182
|
-
|
|
183
|
-
.. code-block:: python
|
|
184
|
-
|
|
185
|
-
from nectar import Steem
|
|
186
|
-
from nectar.conveyor import Conveyor
|
|
187
|
-
s = Steem(keys=["5JADMINPOSTINGKEY"])
|
|
188
|
-
c = Conveyor(blockchain_instance=s)
|
|
189
|
-
userdata = {'email': 'foo@bar.com', 'phone':'+123456789'}
|
|
190
|
-
c.set_user_data('accountname', userdata, 'adminaccountname')
|
|
191
|
-
|
|
192
|
-
"""
|
|
193
|
-
return self._conveyor_method(account, signing_account, "conveyor.set_user_data", [params])
|
|
194
|
-
|
|
195
|
-
def get_feature_flags(self, account, signing_account=None):
|
|
196
|
-
"""Get the account's feature flags. The request has to be signed by the
|
|
197
|
-
requested account or an admin account.
|
|
198
|
-
|
|
199
|
-
:param str account: requested account
|
|
200
|
-
:param str signing_account: (optional) account to sign the
|
|
201
|
-
request. If unset, `account` is used.
|
|
202
|
-
|
|
203
|
-
Example:
|
|
204
|
-
|
|
205
|
-
.. code-block:: python
|
|
206
|
-
|
|
207
|
-
from nectar import Steem
|
|
208
|
-
from nectar.conveyor import Conveyor
|
|
209
|
-
s = Steem(keys=["5JPOSTINGKEY"])
|
|
210
|
-
c = Conveyor(blockchain_instance=s)
|
|
211
|
-
print(c.get_feature_flags('accountname'))
|
|
212
|
-
|
|
213
|
-
"""
|
|
214
|
-
account = Account(account, blockchain_instance=self.steem)
|
|
215
|
-
feature_flags = self._conveyor_method(
|
|
216
|
-
account, signing_account, "conveyor.get_feature_flags", [account["name"]]
|
|
217
|
-
)
|
|
218
|
-
if "result" in feature_flags:
|
|
219
|
-
return feature_flags["result"]
|
|
220
|
-
else:
|
|
221
|
-
return feature_flags
|
|
222
|
-
|
|
223
|
-
def get_feature_flag(self, account, flag, signing_account=None):
|
|
224
|
-
"""Test if a specific feature flag is set for an account. The request
|
|
225
|
-
has to be signed by the requested account or an admin account.
|
|
226
|
-
|
|
227
|
-
:param str account: requested account
|
|
228
|
-
:param str flag: flag to be tested
|
|
229
|
-
:param str signing_account: (optional) account to sign the
|
|
230
|
-
request. If unset, `account` is used.
|
|
231
|
-
|
|
232
|
-
Example:
|
|
233
|
-
|
|
234
|
-
.. code-block:: python
|
|
235
|
-
|
|
236
|
-
from nectar import Steem
|
|
237
|
-
from nectar.conveyor import Conveyor
|
|
238
|
-
s = Steem(keys=["5JPOSTINGKEY"])
|
|
239
|
-
c = Conveyor(blockchain_instance=s)
|
|
240
|
-
print(c.get_feature_flag('accountname', 'accepted_tos'))
|
|
241
|
-
|
|
242
|
-
"""
|
|
243
|
-
account = Account(account, blockchain_instance=self.steem)
|
|
244
|
-
return self._conveyor_method(
|
|
245
|
-
account, signing_account, "conveyor.get_feature_flag", [account["name"], flag]
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
def save_draft(self, account, title, body):
|
|
249
|
-
"""Save a draft in the Conveyor database
|
|
250
|
-
|
|
251
|
-
:param str account: requested account
|
|
252
|
-
:param str title: draft post title
|
|
253
|
-
:param str body: draft post body
|
|
254
|
-
|
|
255
|
-
"""
|
|
256
|
-
account = Account(account, blockchain_instance=self.steem)
|
|
257
|
-
draft = {"title": title, "body": body}
|
|
258
|
-
return self._conveyor_method(account, None, "conveyor.save_draft", [account["name"], draft])
|
|
259
|
-
|
|
260
|
-
def list_drafts(self, account):
|
|
261
|
-
"""List all saved drafts from `account`
|
|
262
|
-
|
|
263
|
-
:param str account: requested account
|
|
264
|
-
|
|
265
|
-
Sample output:
|
|
266
|
-
|
|
267
|
-
.. code-block:: js
|
|
268
|
-
|
|
269
|
-
{
|
|
270
|
-
'jsonrpc': '2.0', 'id': 2, 'result': [
|
|
271
|
-
{'title': 'draft-title', 'body': 'draft-body',
|
|
272
|
-
'uuid': '06497e1e-ac30-48cb-a069-27e1672924c9'}
|
|
273
|
-
]
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
"""
|
|
277
|
-
account = Account(account, blockchain_instance=self.steem)
|
|
278
|
-
return self._conveyor_method(account, None, "conveyor.list_drafts", [account["name"]])
|
|
279
|
-
|
|
280
|
-
def remove_draft(self, account, uuid):
|
|
281
|
-
"""Remove a draft from the Conveyor database
|
|
282
|
-
|
|
283
|
-
:param str account: requested account
|
|
284
|
-
:param str uuid: draft identifier as returned from
|
|
285
|
-
`list_drafts`
|
|
286
|
-
|
|
287
|
-
"""
|
|
288
|
-
account = Account(account, blockchain_instance=self.steem)
|
|
289
|
-
return self._conveyor_method(
|
|
290
|
-
account, None, "conveyor.remove_draft", [account["name"], uuid]
|
|
291
|
-
)
|
|
292
|
-
|
|
293
|
-
def healthcheck(self):
|
|
294
|
-
"""Get the Conveyor status
|
|
295
|
-
|
|
296
|
-
Sample output:
|
|
297
|
-
|
|
298
|
-
.. code-block:: js
|
|
299
|
-
|
|
300
|
-
{
|
|
301
|
-
'ok': True, 'version': '1.1.1-4d28e36-1528725174',
|
|
302
|
-
'date': '2018-07-21T12:12:25.502Z'
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
"""
|
|
306
|
-
url = urljoin(self.url, "/.well-known/healthcheck.json")
|
|
307
|
-
r = requests.get(url)
|
|
308
|
-
return r.json()
|