Skip to content

Commit f9fb23b

Browse files
committed
Merge branch 'release/0.3.0rc1'
2 parents 83d4919 + f779c47 commit f9fb23b

File tree

108 files changed

+2446
-5350
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+2446
-5350
lines changed

.pre-commit-config.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Read up on pre-commit
2+
# https://ljvmiranda921.github.io/notebook/2018/06/21/precommits-using-black-and-flake8/
3+
4+
repos:
5+
6+
- repo: https://github.com/pre-commit/pre-commit-hooks
7+
rev: v2.0.0
8+
hooks:
9+
- id: trailing-whitespace
10+
- id: check-docstring-first
11+
- id: check-executables-have-shebangs
12+
- id: check-json
13+
- id: check-yaml
14+
- id: end-of-file-fixer
15+
- id: fix-encoding-pragma
16+
- id: no-commit-to-branch
17+
branch: master
18+
- id: flake8
19+
20+
- repo: https://github.com/ambv/black
21+
rev: 18.9b0
22+
hooks:
23+
- id: black
24+
language_version: python3.6

Makefile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,15 @@ check:
3636
python3 setup.py check
3737

3838
dist:
39-
python3 setup.py sdist upload -r pypi
40-
python3 setup.py bdist_wheel upload
39+
python3 setup.py sdist bdist_wheel
40+
python3 setup.py bdist_wheel
41+
twine upload --repository-url https://upload.pypi.org/legacy/ dist/*
42+
#twine upload --repository-url https://test.pypi.org/legacy/ dist/*
43+
#python3 setup.py sdist upload -r pypi
44+
#python3 setup.py bdist_wheel upload
4145

4246
docs:
43-
sphinx-apidoc -d 6 -e -f -o docs . *.py tests
47+
SPHINX_APIDOC_OPTIONS="members,undoc-members,show-inheritance,inherited-members" sphinx-apidoc -d 6 -e -f -o docs . *.py tests
4448
make -C docs clean html
4549

4650
release: clean check dist git

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,8 @@ Discussions around development and use of this library can be found in a
5757

5858
A copy of the license is available in the repository's
5959
[LICENSE](LICENSE.txt) file.
60+
61+
### Bounties
62+
63+
As part of [HackTheDex](https://hackthedex.io), security issues found in this
64+
library are potentially eligible for a bounty.

bitshares/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
# -*- coding: utf-8 -*-
12
from .bitshares import BitShares
23

4+
35
__all__ = [
4-
"bitshares"
5-
"aes",
6+
"bitshares",
67
"account",
78
"amount",
89
"asset",
@@ -17,5 +18,5 @@
1718
"committee",
1819
"vesting",
1920
"proposal",
20-
"message"
21+
"message",
2122
]

bitshares/account.py

Lines changed: 21 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
# -*- coding: utf-8 -*-
2+
from .amount import Amount
13
from .instance import BlockchainInstance
2-
from .exceptions import AccountDoesNotExistsException
3-
from .blockchainobject import BlockchainObject
4-
import logging
4+
from graphenecommon.account import (
5+
Account as GrapheneAccount,
6+
AccountUpdate as GrapheneAccountUpdate,
7+
)
8+
from bitsharesbase import operations
59

6-
log = logging.getLogger()
710

8-
9-
class Account(BlockchainObject):
11+
@BlockchainInstance.inject
12+
class Account(GrapheneAccount):
1013
""" This class allows to easily access Account data
1114
1215
:param str account_name: Name of the account
@@ -37,79 +40,10 @@ class Account(BlockchainObject):
3740
3841
"""
3942

40-
type_id = 2
41-
42-
def __init__(self, *args, **kwargs):
43-
self.full = kwargs.pop("full", False)
44-
super().__init__(*args, **kwargs)
45-
46-
def refresh(self):
47-
""" Refresh/Obtain an account's data from the API server
48-
"""
49-
import re
50-
if re.match("^1\.2\.[0-9]*$", self.identifier):
51-
account = self.blockchain.rpc.get_objects([self.identifier])[0]
52-
else:
53-
account = self.blockchain.rpc.lookup_account_names(
54-
[self.identifier])[0]
55-
if not account:
56-
raise AccountDoesNotExistsException(self.identifier)
57-
self.cache(account["name"])
58-
59-
if self.full:
60-
accounts = self.blockchain.rpc.get_full_accounts(
61-
[account["id"]], False)
62-
if accounts and isinstance(accounts, list):
63-
account = accounts[0][1]
64-
else:
65-
raise AccountDoesNotExistsException(self.identifier)
66-
super(Account, self).__init__(
67-
account["account"],
68-
blockchain_instance=self.blockchain
69-
)
70-
for k, v in account.items():
71-
if k != "account":
72-
self[k] = v
73-
else:
74-
super(Account, self).__init__(
75-
account,
76-
blockchain_instance=self.blockchain
77-
)
78-
79-
@property
80-
def name(self):
81-
return self["name"]
82-
83-
@property
84-
def is_ltm(self):
85-
""" Is the account a lifetime member (LTM)?
86-
"""
87-
return self["id"] == self["lifetime_referrer"]
88-
89-
@property
90-
def balances(self):
91-
""" List balances of an account. This call returns instances of
92-
:class:`bitshares.amount.Amount`.
93-
"""
94-
from .amount import Amount
95-
balances = self.blockchain.rpc.get_account_balances(self["id"], [])
96-
return [
97-
Amount(b, blockchain_instance=self.blockchain)
98-
for b in balances if int(b["amount"]) > 0
99-
]
100-
101-
def balance(self, symbol):
102-
""" Obtain the balance of a specific Asset. This call returns instances of
103-
:class:`bitshares.amount.Amount`.
104-
"""
105-
from .amount import Amount
106-
if isinstance(symbol, dict) and "symbol" in symbol:
107-
symbol = symbol["symbol"]
108-
balances = self.balances
109-
for b in balances:
110-
if b["symbol"] == symbol:
111-
return b
112-
return Amount(0, symbol)
43+
def define_classes(self):
44+
self.type_id = 2
45+
self.amount_class = Amount
46+
self.operations = operations
11347

11448
@property
11549
def call_positions(self):
@@ -123,6 +57,7 @@ def callpositions(self):
12357
"""
12458
self.ensure_full()
12559
from .dex import Dex
60+
12661
dex = Dex(blockchain_instance=self.blockchain)
12762
return dex.list_debt_positions(self)
12863

@@ -131,113 +66,22 @@ def openorders(self):
13166
""" Returns open Orders
13267
"""
13368
from .price import Order
69+
13470
self.ensure_full()
13571
return [
136-
Order(o, blockchain_instance=self.blockchain)
137-
for o in self["limit_orders"]
72+
Order(o, blockchain_instance=self.blockchain) for o in self["limit_orders"]
13873
]
13974

140-
@property
141-
def is_fully_loaded(self):
142-
""" Is this instance fully loaded / e.g. all data available?
143-
"""
144-
return (self.full and "votes" in self)
14575

146-
def ensure_full(self):
147-
if not self.is_fully_loaded:
148-
self.full = True
149-
self.refresh()
150-
151-
def history(
152-
self, first=0,
153-
last=0, limit=-1,
154-
only_ops=[], exclude_ops=[]
155-
):
156-
""" Returns a generator for individual account transactions. The
157-
latest operation will be first. This call can be used in a
158-
``for`` loop.
159-
160-
:param int first: sequence number of the first
161-
transaction to return (*optional*)
162-
:param int last: sequence number of the last
163-
transaction to return (*optional*)
164-
:param int limit: limit number of transactions to
165-
return (*optional*)
166-
:param array only_ops: Limit generator by these
167-
operations (*optional*)
168-
:param array exclude_ops: Exclude these operations from
169-
generator (*optional*).
170-
171-
... note::
172-
only_ops and exclude_ops takes an array of strings:
173-
The full list of operation ID's can be found in
174-
bitsharesbase.operationids.
175-
Example: ['transfer', 'fill_order']
176-
"""
177-
from bitsharesbase.operations import getOperationNameForId
178-
_limit = 100
179-
cnt = 0
180-
181-
if first < 0:
182-
first = 0
183-
184-
while True:
185-
# RPC call
186-
txs = self.blockchain.rpc.get_account_history(
187-
self["id"],
188-
"1.11.{}".format(last),
189-
_limit,
190-
"1.11.{}".format(first - 1),
191-
api="history"
192-
)
193-
for i in txs:
194-
if exclude_ops and getOperationNameForId(
195-
i["op"][0]
196-
) in exclude_ops:
197-
continue
198-
if not only_ops or getOperationNameForId(
199-
i["op"][0]
200-
) in only_ops:
201-
cnt += 1
202-
yield i
203-
if limit >= 0 and cnt >= limit:
204-
return
205-
206-
if not txs:
207-
log.info("No more history returned from API node")
208-
break
209-
if len(txs) < _limit:
210-
log.info("Less than {} have been returned.".format(_limit))
211-
break
212-
first = int(txs[-1]["id"].split(".")[2])
213-
214-
def upgrade(self):
215-
return self.blockchain.upgrade_account(account=self)
216-
217-
def whitelist(self, account):
218-
""" Add an other account to the whitelist of this account
219-
"""
220-
return self.blockchain.account_whitelist(account, lists=["white"], account=self)
221-
222-
def blacklist(self, account):
223-
""" Add an other account to the blacklist of this account
224-
"""
225-
return self.blockchain.account_whitelist(account, lists=["black"], account=self)
226-
227-
def nolist(self, account):
228-
""" Remove an other account from any list of this account
229-
"""
230-
return self.blockchain.account_whitelist(account, lists=[], account=self)
231-
232-
233-
class AccountUpdate(dict, BlockchainInstance):
76+
@BlockchainInstance.inject
77+
class AccountUpdate(GrapheneAccountUpdate):
23478
""" This purpose of this class is to keep track of account updates
23579
as they are pushed through by :class:`bitshares.notify.Notify`.
23680
23781
Instances of this class are dictionaries and take the following
23882
form:
23983
240-
... code-block: js
84+
.. code-block: js
24185
24286
{'id': '2.6.29',
24387
'lifetime_fees_paid': '44261516129',
@@ -250,26 +94,5 @@ class AccountUpdate(dict, BlockchainInstance):
25094
25195
"""
25296

253-
def __init__(self, data, *args, **kwargs):
254-
BlockchainInstance.__init__(self, *args, **kwargs)
255-
if isinstance(data, dict):
256-
super(AccountUpdate, self).__init__(data)
257-
else:
258-
account = Account(data, blockchain_instance=self.blockchain)
259-
update = self.blockchain.rpc.get_objects([
260-
"2.6.%s" % (account["id"].split(".")[2])
261-
])[0]
262-
super(AccountUpdate, self).__init__(update)
263-
264-
@property
265-
def account(self):
266-
""" In oder to obtain the actual
267-
:class:`bitshares.account.Account` from this class, you can
268-
use the ``account`` attribute.
269-
"""
270-
account = Account(self["owner"], blockchain_instance=self.blockchain)
271-
account.refresh()
272-
return account
273-
274-
def __repr__(self):
275-
return "<AccountUpdate: {}>".format(self["owner"])
97+
def define_classes(self):
98+
self.account_class = Account

bitshares/aes.py

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)