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
@@ -0,0 +1,283 @@
1
+ # -*- coding: utf-8 -*-
2
+ import hashlib
3
+ import json
4
+ import logging
5
+ from binascii import hexlify, unhexlify
6
+ from collections import OrderedDict
7
+
8
+ import ecdsa
9
+ from asn1crypto.core import OctetString
10
+
11
+ from nectargraphenebase.py23 import py23_bytes
12
+
13
+ from .bip32 import parse_path
14
+ from .chains import known_chains
15
+ from .objects import Operation, isArgsThisClass
16
+ from .py23 import py23_chr, string_types
17
+ from .types import (
18
+ Array,
19
+ JsonObj,
20
+ Optional,
21
+ PointInTime,
22
+ Set,
23
+ Signature,
24
+ String,
25
+ Uint16,
26
+ Uint32,
27
+ Varint32,
28
+ )
29
+
30
+ log = logging.getLogger(__name__)
31
+
32
+
33
+ class GrapheneObjectASN1(object):
34
+ """Core abstraction class
35
+
36
+ This class is used for any JSON reflected object in Graphene.
37
+
38
+ * ``instance.__json__()``: encodes data into json format
39
+ * ``bytes(instance)``: encodes data into wire format
40
+ * ``str(instances)``: dumps json object as string
41
+
42
+ """
43
+
44
+ def __init__(self, data=None):
45
+ self.data = data
46
+
47
+ def __bytes__(self):
48
+ if self.data is None:
49
+ return py23_bytes()
50
+ b = b""
51
+ output = b""
52
+ for name, value in list(self.data.items()):
53
+ if name == "operations":
54
+ for operation in value:
55
+ if isinstance(value, string_types):
56
+ b = py23_bytes(operation, "utf-8")
57
+ else:
58
+ b = py23_bytes(operation)
59
+ output += OctetString(b).dump()
60
+ elif name != "signatures":
61
+ if isinstance(value, string_types):
62
+ b = py23_bytes(value, "utf-8")
63
+ else:
64
+ b = py23_bytes(value)
65
+ output += OctetString(b).dump()
66
+ return output
67
+
68
+ def __json__(self):
69
+ if self.data is None:
70
+ return {}
71
+ d = {} # JSON output is *not* ordered
72
+ for name, value in list(self.data.items()):
73
+ if isinstance(value, Optional) and value.isempty():
74
+ continue
75
+
76
+ if isinstance(value, String):
77
+ d.update({name: str(value)})
78
+ else:
79
+ try:
80
+ d.update({name: JsonObj(value)})
81
+ except Exception:
82
+ d.update({name: value.__str__()})
83
+ return d
84
+
85
+ def __str__(self):
86
+ return json.dumps(self.__json__())
87
+
88
+ def toJson(self):
89
+ return self.__json__()
90
+
91
+ def json(self):
92
+ return self.__json__()
93
+
94
+
95
+ class Unsigned_Transaction(GrapheneObjectASN1):
96
+ """Create an unsigned transaction with ASN1 encoder for using it with ledger
97
+
98
+ :param num ref_block_num:
99
+ :param num ref_block_prefix:
100
+ :param str expiration: expiration date
101
+ :param array operations: array of operations
102
+ """
103
+
104
+ def __init__(self, *args, **kwargs):
105
+ if isArgsThisClass(self, args):
106
+ self.data = args[0].data
107
+ else:
108
+ if len(args) == 1 and len(kwargs) == 0:
109
+ kwargs = args[0]
110
+ prefix = kwargs.pop("prefix", "STM")
111
+ if "extensions" not in kwargs:
112
+ kwargs["extensions"] = Set([])
113
+ elif not kwargs.get("extensions"):
114
+ kwargs["extensions"] = Set([])
115
+ if "signatures" not in kwargs:
116
+ kwargs["signatures"] = Array([])
117
+ else:
118
+ kwargs["signatures"] = Array(
119
+ [Signature(unhexlify(a)) for a in kwargs["signatures"]]
120
+ )
121
+ operations_count = 0
122
+ if "operations" in kwargs:
123
+ operations_count = len(kwargs["operations"])
124
+ # opklass = self.getOperationKlass()
125
+ # if all([not isinstance(a, opklass) for a in kwargs["operations"]]):
126
+ # kwargs['operations'] = Array([opklass(a, prefix=prefix) for a in kwargs["operations"]])
127
+ # else:
128
+ # kwargs['operations'] = (kwargs["operations"])
129
+
130
+ super(Unsigned_Transaction, self).__init__(
131
+ OrderedDict(
132
+ [
133
+ ("ref_block_num", Uint16(kwargs["ref_block_num"])),
134
+ ("ref_block_prefix", Uint32(kwargs["ref_block_prefix"])),
135
+ ("expiration", PointInTime(kwargs["expiration"])),
136
+ ("operations_count", Varint32(operations_count)),
137
+ ("operations", kwargs["operations"]),
138
+ ("extensions", kwargs["extensions"]),
139
+ ("signatures", kwargs["signatures"]),
140
+ ]
141
+ )
142
+ )
143
+
144
+ @property
145
+ def id(self):
146
+ """The transaction id of this transaction"""
147
+ # Store signatures temporarily since they are not part of
148
+ # transaction id
149
+ sigs = self.data["signatures"]
150
+ self.data.pop("signatures", None)
151
+
152
+ # Generage Hash of the seriliazed version
153
+ h = hashlib.sha256(py23_bytes(self)).digest()
154
+
155
+ # recover signatures
156
+ self.data["signatures"] = sigs
157
+
158
+ # Return properly truncated tx hash
159
+ return hexlify(h[:20]).decode("ascii")
160
+
161
+ def getOperationKlass(self):
162
+ return Operation
163
+
164
+ def derSigToHexSig(self, s):
165
+ """Format DER to HEX signature"""
166
+ s, junk = ecdsa.der.remove_sequence(unhexlify(s))
167
+ if junk:
168
+ log.debug("JUNK: %s", hexlify(junk).decode("ascii"))
169
+ if not (junk == b""):
170
+ raise AssertionError()
171
+ x, s = ecdsa.der.remove_integer(s)
172
+ y, s = ecdsa.der.remove_integer(s)
173
+ return "%064x%064x" % (x, y)
174
+
175
+ def getKnownChains(self):
176
+ return known_chains
177
+
178
+ def getChainParams(self, chain):
179
+ # Which network are we on:
180
+ chains = self.getKnownChains()
181
+ if isinstance(chain, str) and chain in chains:
182
+ chain_params = chains[chain]
183
+ elif isinstance(chain, dict):
184
+ chain_params = chain
185
+ else:
186
+ raise Exception("sign() only takes a string or a dict as chain!")
187
+ if "chain_id" not in chain_params:
188
+ raise Exception("sign() needs a 'chain_id' in chain params!")
189
+ return chain_params
190
+
191
+ def deriveDigest(self, chain):
192
+ chain_params = self.getChainParams(chain)
193
+ # Chain ID
194
+ self.chainid = chain_params["chain_id"]
195
+
196
+ # Do not serialize signatures
197
+ sigs = self.data["signatures"]
198
+ self.data["signatures"] = []
199
+
200
+ # Get message to sign
201
+ # bytes(self) will give the wire formated data according to
202
+ # GrapheneObject and the data given in __init__()
203
+ self.message = OctetString(unhexlify(self.chainid)).dump()
204
+ for name, value in list(self.data.items()):
205
+ if name == "operations":
206
+ for operation in value:
207
+ if isinstance(value, string_types):
208
+ b = py23_bytes(operation, "utf-8")
209
+ else:
210
+ b = py23_bytes(operation)
211
+ self.message += OctetString(b).dump()
212
+ elif name != "signatures":
213
+ if isinstance(value, string_types):
214
+ b = py23_bytes(value, "utf-8")
215
+ else:
216
+ b = py23_bytes(value)
217
+ self.message += OctetString(b).dump()
218
+
219
+ self.digest = hashlib.sha256(self.message).digest()
220
+
221
+ # restore signatures
222
+ self.data["signatures"] = sigs
223
+
224
+ def build_path(self, role, account_index, key_index):
225
+ if role == "owner":
226
+ return "48'/13'/0'/%d'/%d'" % (account_index, key_index)
227
+ elif role == "active":
228
+ return "48'/13'/1'/%d'/%d'" % (account_index, key_index)
229
+ elif role == "posting":
230
+ return "48'/13'/4'/%d'/%d'" % (account_index, key_index)
231
+ elif role == "memo":
232
+ return "48'/13'/3'/%d'/%d'" % (account_index, key_index)
233
+
234
+ def build_apdu(self, path="48'/13'/0'/0'/0'", chain=None):
235
+ self.deriveDigest(chain)
236
+ path = unhexlify(parse_path(path, as_bytes=True))
237
+
238
+ message = self.message
239
+ path_size = int(len(path) / 4)
240
+ message_size = len(message)
241
+
242
+ offset = 0
243
+ first = True
244
+ result = []
245
+ while offset != message_size:
246
+ if message_size - offset > 200:
247
+ chunk = message[offset : offset + 200]
248
+ else:
249
+ chunk = message[offset:]
250
+
251
+ if first:
252
+ total_size = int(len(path)) + 1 + len(chunk)
253
+ apdu = (
254
+ unhexlify("d4040000")
255
+ + py23_chr(total_size)
256
+ + py23_chr(path_size)
257
+ + path
258
+ + chunk
259
+ )
260
+ first = False
261
+ else:
262
+ total_size = len(chunk)
263
+ apdu = unhexlify("d4048000") + py23_chr(total_size) + chunk
264
+ result.append(apdu)
265
+ offset += len(chunk)
266
+ return result
267
+
268
+ def build_apdu_pubkey(self, path="48'/13'/0'/0'/0'", request_screen_approval=False):
269
+ path = unhexlify(parse_path(path, as_bytes=True))
270
+ if not request_screen_approval:
271
+ return (
272
+ unhexlify("d4020001")
273
+ + py23_chr(int(len(path)) + 1)
274
+ + py23_chr(int(len(path) / 4))
275
+ + path
276
+ )
277
+ else:
278
+ return (
279
+ unhexlify("d4020101")
280
+ + py23_chr(int(len(path)) + 1)
281
+ + py23_chr(int(len(path) / 4))
282
+ + path
283
+ )
@@ -0,0 +1,2 @@
1
+ """THIS FILE IS GENERATED FROM nectar PYPROJECT.TOML."""
2
+ version = '0.00.02'
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Load modules from other classes
3
+ # # Inspired by https://raw.githubusercontent.com/xeroc/python-graphenelib/master/graphenestorage/__init__.py
4
+ from .base import (
5
+ InRamConfigurationStore,
6
+ InRamEncryptedKeyStore,
7
+ InRamEncryptedTokenStore,
8
+ InRamPlainKeyStore,
9
+ InRamPlainTokenStore,
10
+ SqliteConfigurationStore,
11
+ SqliteEncryptedKeyStore,
12
+ SqliteEncryptedTokenStore,
13
+ SqlitePlainKeyStore,
14
+ SqlitePlainTokenStore,
15
+ )
16
+ from .sqlite import SQLiteCommon, SQLiteFile
17
+
18
+ __all__ = ["interfaces", "masterpassword", "base", "sqlite", "ram"]
19
+
20
+
21
+ def get_default_config_store(*args, **kwargs):
22
+ """This method returns the default **configuration** store
23
+ that uses an SQLite database internally.
24
+ :params str appname: The appname that is used internally to distinguish
25
+ different SQLite files
26
+ """
27
+ kwargs["appname"] = kwargs.get("appname", "nectar")
28
+ return SqliteConfigurationStore(*args, **kwargs)
29
+
30
+
31
+ def get_default_key_store(*args, config, **kwargs):
32
+ """This method returns the default **key** store
33
+ that uses an SQLite database internally.
34
+ :params str appname: The appname that is used internally to distinguish
35
+ different SQLite files
36
+ """
37
+ kwargs["appname"] = kwargs.get("appname", "nectar")
38
+ return SqliteEncryptedKeyStore(config=config, **kwargs)
nectarstorage/base.py ADDED
@@ -0,0 +1,306 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Inspired by https://raw.githubusercontent.com/xeroc/python-graphenelib/master/graphenestorage/base.py
3
+ import logging
4
+
5
+ from .exceptions import KeyAlreadyInStoreException
6
+ from .interfaces import (
7
+ ConfigInterface,
8
+ EncryptedKeyInterface,
9
+ EncryptedTokenInterface,
10
+ KeyInterface,
11
+ TokenInterface,
12
+ )
13
+ from .masterpassword import MasterPassword
14
+ from .ram import InRamStore
15
+ from .sqlite import SQLiteStore
16
+
17
+ log = logging.getLogger(__name__)
18
+
19
+
20
+ # Configuration
21
+ class InRamConfigurationStore(InRamStore, ConfigInterface):
22
+ """A simple example that stores configuration in RAM.
23
+
24
+ Internally, this works by simply inheriting
25
+ :class:`nectarstorage.ram.InRamStore`. The interface is defined in
26
+ :class:`nectarstorage.interfaces.ConfigInterface`.
27
+ """
28
+
29
+ pass
30
+
31
+
32
+ class SqliteConfigurationStore(SQLiteStore, ConfigInterface):
33
+ """This is the configuration storage that stores key/value
34
+ pairs in the `config` table of the SQLite3 database.
35
+
36
+ Internally, this works by simply inheriting
37
+ :class:`nectarstorage.sqlite.SQLiteStore`. The interface is defined
38
+ in :class:`nectarstorage.interfaces.ConfigInterface`.
39
+ """
40
+
41
+ #: The table name for the configuration
42
+ __tablename__ = "config"
43
+ #: The name of the 'key' column
44
+ __key__ = "key"
45
+ #: The name of the 'value' column
46
+ __value__ = "value"
47
+
48
+
49
+ # Keys
50
+ class InRamPlainKeyStore(InRamStore, KeyInterface):
51
+ """A simple in-RAM Store that stores keys unencrypted in RAM
52
+
53
+ Internally, this works by simply inheriting
54
+ :class:`nectarstorage.ram.InRamStore`. The interface is defined in
55
+ :class:`nectarstorage.interfaces.KeyInterface`.
56
+ """
57
+
58
+ def getPublicKeys(self):
59
+ return [k for k, v in self.items()]
60
+
61
+ def getPrivateKeyForPublicKey(self, pub):
62
+ return self.get(str(pub), None)
63
+
64
+ def add(self, wif, pub):
65
+ if str(pub) in self:
66
+ raise KeyAlreadyInStoreException
67
+ self[str(pub)] = str(wif)
68
+
69
+ def delete(self, pub):
70
+ InRamStore.delete(self, str(pub))
71
+
72
+
73
+ class SqlitePlainKeyStore(SQLiteStore, KeyInterface):
74
+ """This is the key storage that stores the public key and the
75
+ **unencrypted** private key in the `keys` table in the SQLite3
76
+ database.
77
+
78
+ Internally, this works by simply inheriting
79
+ :class:`nectarstorage.ram.InRamStore`. The interface is defined in
80
+ :class:`nectarstorage.interfaces.KeyInterface`.
81
+ """
82
+
83
+ #: The table name for the configuration
84
+ __tablename__ = "keys"
85
+ #: The name of the 'key' column
86
+ __key__ = "pub"
87
+ #: The name of the 'value' column
88
+ __value__ = "wif"
89
+
90
+ def getPublicKeys(self):
91
+ return [k for k, v in self.items()]
92
+
93
+ def getPrivateKeyForPublicKey(self, pub):
94
+ return self[pub]
95
+
96
+ def add(self, wif, pub):
97
+ if str(pub) in self:
98
+ raise KeyAlreadyInStoreException
99
+ self[str(pub)] = str(wif)
100
+
101
+ def delete(self, pub):
102
+ SQLiteStore.delete(self, str(pub))
103
+
104
+ def is_encrypted(self):
105
+ """Returns False, as we are not encrypted here"""
106
+ return False
107
+
108
+
109
+ class KeyEncryption(MasterPassword, EncryptedKeyInterface):
110
+ """This is an interface class that provides the methods required for
111
+ EncryptedKeyInterface and links them to the MasterPassword-provided
112
+ functionatlity, accordingly.
113
+ """
114
+
115
+ def __init__(self, *args, **kwargs):
116
+ EncryptedKeyInterface.__init__(self, *args, **kwargs)
117
+ MasterPassword.__init__(self, *args, **kwargs)
118
+
119
+ # Interface to deal with encrypted keys
120
+ def getPublicKeys(self):
121
+ return [k for k, v in self.items()]
122
+
123
+ def getPrivateKeyForPublicKey(self, pub):
124
+ wif = self.get(str(pub), None)
125
+ if wif:
126
+ return self.decrypt(wif) # From Masterpassword
127
+
128
+ def add(self, wif, pub):
129
+ if str(pub) in self:
130
+ raise KeyAlreadyInStoreException
131
+ self[str(pub)] = self.encrypt(str(wif)) # From Masterpassword
132
+
133
+ def is_encrypted(self):
134
+ return True
135
+
136
+
137
+ class InRamEncryptedKeyStore(InRamStore, KeyEncryption):
138
+ """An in-RAM Store that stores keys **encrypted** in RAM.
139
+
140
+ Internally, this works by simply inheriting
141
+ :class:`nectarstorage.ram.InRamStore`. The interface is defined in
142
+ :class:`nectarstorage.interfaces.KeyInterface`.
143
+
144
+ .. note:: This module also inherits
145
+ :class:`nectarstorage.masterpassword.MasterPassword` which offers
146
+ additional methods and deals with encrypting the keys.
147
+ """
148
+
149
+ def __init__(self, *args, **kwargs):
150
+ InRamStore.__init__(self, *args, **kwargs)
151
+ KeyEncryption.__init__(self, *args, **kwargs)
152
+
153
+
154
+ class SqliteEncryptedKeyStore(SQLiteStore, KeyEncryption):
155
+ """This is the key storage that stores the public key and the
156
+ **encrypted** private key in the `keys` table in the SQLite3 database.
157
+
158
+ Internally, this works by simply inheriting
159
+ :class:`nectarstorage.ram.InRamStore`. The interface is defined in
160
+ :class:`nectarstorage.interfaces.KeyInterface`.
161
+
162
+ .. note:: This module also inherits
163
+ :class:`nectarstorage.masterpassword.MasterPassword` which offers
164
+ additional methods and deals with encrypting the keys.
165
+ """
166
+
167
+ __tablename__ = "keys"
168
+ __key__ = "pub"
169
+ __value__ = "wif"
170
+
171
+ def __init__(self, *args, **kwargs):
172
+ SQLiteStore.__init__(self, *args, **kwargs)
173
+ KeyEncryption.__init__(self, *args, **kwargs)
174
+
175
+
176
+ # Token
177
+ class InRamPlainTokenStore(InRamStore, TokenInterface):
178
+ """A simple in-RAM Store that stores token unencrypted in RAM
179
+
180
+ Internally, this works by simply inheriting
181
+ :class:`nectarstorage.ram.InRamStore`. The interface is defined in
182
+ :class:`nectarstorage.interfaces.TokenInterface`.
183
+ """
184
+
185
+ def getPublicNames(self):
186
+ return [k for k, v in self.items()]
187
+
188
+ def getPrivateKeyForPublicKey(self, pub):
189
+ return self.get(str(pub), None)
190
+
191
+ def add(self, token, name):
192
+ if str(name) in self:
193
+ raise KeyAlreadyInStoreException
194
+ self[str(name)] = str(token)
195
+
196
+ def delete(self, name):
197
+ InRamStore.delete(self, str(name))
198
+
199
+
200
+ class SqlitePlainTokenStore(SQLiteStore, TokenInterface):
201
+ """This is the token storage that stores the public key and the
202
+ **unencrypted** private key in the `tokens` table in the SQLite3
203
+ database.
204
+
205
+ Internally, this works by simply inheriting
206
+ :class:`nectarstorage.ram.InRamStore`. The interface is defined in
207
+ :class:`nectarstorage.interfaces.TokenInterface`.
208
+ """
209
+
210
+ #: The table name for the configuration
211
+ __tablename__ = "token"
212
+ #: The name of the 'key' column
213
+ __key__ = "name"
214
+ #: The name of the 'value' column
215
+ __value__ = "token"
216
+
217
+ def getPublicNames(self):
218
+ return [k for k, v in self.items()]
219
+
220
+ def getPrivateKeyForPublicKey(self, name):
221
+ return self[name]
222
+
223
+ def add(self, token, name):
224
+ if str(name) in self:
225
+ raise KeyAlreadyInStoreException
226
+ self[str(name)] = str(token)
227
+
228
+ def updateToken(self, name, token):
229
+ self[str(name)] = str(token) # From Masterpassword
230
+
231
+ def delete(self, name):
232
+ SQLiteStore.delete(self, str(name))
233
+
234
+ def is_encrypted(self):
235
+ """Returns False, as we are not encrypted here"""
236
+ return False
237
+
238
+
239
+ class TokenEncryption(MasterPassword, EncryptedTokenInterface):
240
+ """This is an interface class that provides the methods required for
241
+ EncryptedTokenInterface and links them to the MasterPassword-provided
242
+ functionatlity, accordingly.
243
+ """
244
+
245
+ def __init__(self, *args, **kwargs):
246
+ EncryptedTokenInterface.__init__(self, *args, **kwargs)
247
+ MasterPassword.__init__(self, *args, **kwargs)
248
+
249
+ # Interface to deal with encrypted keys
250
+ def getPublicNames(self):
251
+ return [k for k, v in self.items()]
252
+
253
+ def getPrivateKeyForPublicKey(self, name):
254
+ token = self.get(str(name), None)
255
+ if token:
256
+ return self.decrypt_text(token) # From Masterpassword
257
+
258
+ def add(self, token, name):
259
+ if str(name) in self:
260
+ raise KeyAlreadyInStoreException
261
+ self[str(name)] = self.encrypt_text(str(token)) # From Masterpassword
262
+
263
+ def updateToken(self, name, token):
264
+ self[str(name)] = self.encrypt_text(str(token)) # From Masterpassword
265
+
266
+ def is_encrypted(self):
267
+ return True
268
+
269
+
270
+ class InRamEncryptedTokenStore(InRamStore, TokenEncryption):
271
+ """An in-RAM Store that stores token **encrypted** in RAM.
272
+
273
+ Internally, this works by simply inheriting
274
+ :class:`nectarstorage.ram.InRamStore`. The interface is defined in
275
+ :class:`nectarstorage.interfaces.TokenInterface`.
276
+
277
+ .. note:: This module also inherits
278
+ :class:`nectarstorage.masterpassword.MasterPassword` which offers
279
+ additional methods and deals with encrypting the keys.
280
+ """
281
+
282
+ def __init__(self, *args, **kwargs):
283
+ InRamStore.__init__(self, *args, **kwargs)
284
+ TokenEncryption.__init__(self, *args, **kwargs)
285
+
286
+
287
+ class SqliteEncryptedTokenStore(SQLiteStore, TokenEncryption):
288
+ """This is the key storage that stores the account name and the
289
+ **encrypted** token in the `token` table in the SQLite3 database.
290
+
291
+ Internally, this works by simply inheriting
292
+ :class:`nectarstorage.ram.InRamStore`. The interface is defined in
293
+ :class:`nectarstorage.interfaces.TokenInterface`.
294
+
295
+ .. note:: This module also inherits
296
+ :class:`nectarstorage.masterpassword.MasterPassword` which offers
297
+ additional methods and deals with encrypting the token.
298
+ """
299
+
300
+ __tablename__ = "token"
301
+ __key__ = "name"
302
+ __value__ = "token"
303
+
304
+ def __init__(self, *args, **kwargs):
305
+ SQLiteStore.__init__(self, *args, **kwargs)
306
+ TokenEncryption.__init__(self, *args, **kwargs)
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Inspired by https://raw.githubusercontent.com/xeroc/python-graphenelib/master/graphenestorage/exceptions.py
3
+ class WalletLocked(Exception):
4
+ pass
5
+
6
+
7
+ class WrongMasterPasswordException(Exception):
8
+ """The password provided could not properly unlock the wallet"""
9
+
10
+ pass
11
+
12
+
13
+ class KeyAlreadyInStoreException(Exception):
14
+ """The key of a key/value pair is already in the store"""
15
+
16
+ pass