def approve(*args, **kwargs): """ This process is meant to approve proposals that I have created. The reason for this is that proposals created by accountA are not automatically also approved by accountA and need an explicit approval. """ peerplays.rpc.connect() myapprover = kwargs.get("approver", None) if not myapprover: myapprover = config.get("BOOKIE_APPROVER") myproposer = kwargs.get("proposer", None) if not myproposer: myproposer = config.get("BOOKIE_PROPOSER") log.info("Testing for pending proposals " "created by {} that we could approve by {}".format( myproposer, myapprover)) proposals = Proposals("witness-account") approver = Account(myapprover) for proposal in proposals: proposer = Account(proposal.proposer) if (proposer["name"] == myproposer and approver["id"] not in proposal["available_active_approvals"]): log.info( "Proposal {} has been proposed by {}. Approving it!".format( proposal["id"], myproposer)) log.info( peerplays.approveproposal(proposal["id"], account=myapprover))
def history(ctx, account, limit, type, csv, exclude, raw): """ Show history of an account """ from peerplaysbase.operations import getOperationNameForId header = ["#", "time (block)", "operation", "details"] if csv: import csv t = csv.writer(sys.stdout, delimiter=";") t.writerow(header) else: t = PrettyTable(header) t.align = "r" t.align["details"] = "l" for a in account: account = Account(a, peerplays_instance=ctx.peerplays) for b in account.history(limit=limit, only_ops=type, exclude_ops=exclude): row = [ b["id"].split(".")[2], "%s" % (b["block_num"]), "{} ({})".format(getOperationNameForId(b["op"][0]), b["op"][0]), pprintOperation(b) if not raw else json.dumps(b, indent=4), ] if csv: t.writerow(row) else: t.add_row(row) if not csv: click.echo(t)
def fixture_data(): peerplays.clear() BettingMarkets.clear_cache() Rules.clear_cache() BettingMarketGroups.clear_cache() Proposals.clear_cache() Witnesses.clear_cache() Events.clear_cache() EventGroups.clear_cache() Sports.clear_cache() with open(os.path.join(os.path.dirname(__file__), "fixtures.yaml")) as fid: data = yaml.safe_load(fid) [Account(x) for x in data.get("accounts", [])] [Account(x).store(x, "name") for x in data.get("accounts", [])] Witnesses.cache_objects([Witness(x) for x in data.get("witnesses", [])]) Sports.cache_objects([Sport(x) for x in data.get("sports", [])]) EventGroups.cache_objects( [EventGroup(x) for x in data.get("eventgroups", [])]) Events.cache_objects([Event(x) for x in data.get("events", [])]) BettingMarketGroups.cache_objects( [BettingMarketGroup(x) for x in data.get("bettingmarketgroups", [])]) BettingMarkets.cache_objects( [BettingMarket(x) for x in data.get("bettingmarkets", [])]) Rules.cache_objects([Rule(x) for x in data.get("rules", [])]) [Bet(x) for x in data.get("bets", [])] proposals = [] for proposal in data.get("proposals", []): ops = list() for _op in proposal["operations"]: for opName, op in _op.items(): ops.append([operations[opName], op]) # Proposal! proposal_id = proposal["proposal_id"] proposal_data = { "available_active_approvals": [], "available_key_approvals": [], "available_owner_approvals": [], "expiration_time": "2018-05-29T10:23:13", "id": proposal_id, "proposed_transaction": { "expiration": "2018-05-29T10:23:13", "extensions": [], "operations": ops, "ref_block_num": 0, "ref_block_prefix": 0, }, "proposer": "1.2.7", "required_active_approvals": ["1.2.1"], "required_owner_approvals": [], } proposals.append(Proposal(proposal_data)) Proposals.cache_objects(proposals, "1.2.1") Proposals.cache_objects(proposals, "witness-account")
def getResolutions(bettor_id, bmg_id=None): a = Account(bettor_id, peerplays_instance=ppy, full=True) history = [] for line in a.history( limit=1000): # sufficiently large to get all resolutions if line['op'][0] == 64: if bmg_id is not None: if line['op'][1]['betting_market_group_id'] == bmg_id: history.append(line) else: history.append(line) return history
def test_account_upgrade(self): account = Account("witness-account") tx = account.upgrade() ops = tx["operations"] op = ops[0][1] self.assertEqual(len(ops), 1) self.assertEqual(getOperationNameForId(ops[0][0]), "account_upgrade") self.assertTrue(op["upgrade_to_lifetime_member"]) self.assertEqual( op["account_to_upgrade"], "1.2.1", )
def getWitnessAccount(self): # so far default is always active try: return Account("witness-account", peerplays_instance=self.get_node()) except Exception as ex: raise NodeException(ex.__class__.__name__ + ": " + str(ex))
def addkey(ctx, key): """ Add a private key to the wallet """ if not key: while True: key = click.prompt("Private Key (wif) [Enter to quit]", hide_input=True, show_default=False, default="exit") if not key or key == "exit": break try: ctx.peerplays.wallet.addPrivateKey(key) except Exception as e: click.echo(str(e)) continue else: for k in key: try: ctx.peerplays.wallet.addPrivateKey(k) except Exception as e: click.echo(str(e)) installedKeys = ctx.peerplays.wallet.getPublicKeys() if len(installedKeys) == 1: name = ctx.peerplays.wallet.getAccountFromPublicKey(installedKeys[0]) if name: # only if a name to the key was found account = Account(name, peerplays_instance=ctx.peerplays) click.echo("=" * 30) click.echo("Setting new default user: %s" % account["name"]) click.echo() click.echo("You can change these settings with:") click.echo(" uptick set default_account <account>") click.echo("=" * 30) config["default_account"] = account["name"]
def get_pending_operations(self, account="witness-account", require_witness=True, require_active_witness=True, **kwargs): pending_proposals = Proposals(account) witnesses = Witnesses(only_active=require_active_witness) props = list() for proposal in pending_proposals: # Do not inspect proposals that have not been proposed by a witness if require_witness and proposal.proposer not in witnesses: log.info( "Skipping proposal {} as it has been proposed by a non-witness '{}'" .format(proposal["id"], Account(proposal.proposer)["name"])) continue ret = [] if not proposal["id"] in Lookup.approval_map: Lookup.approval_map[proposal["id"]] = {} for oid, operations in enumerate(proposal.proposed_operations): if oid not in Lookup.approval_map[proposal["id"]]: Lookup.approval_map[proposal["id"]][oid] = False ret.append((operations, proposal["id"], oid)) props.append(dict(proposal=proposal, data=ret)) return props
def getSelectedAccount(self): # so far default is always active try: return Account(self.get_node().config["default_account"], peerplays_instance=self.get_node()) except Exception as ex: raise NodeException(ex.__class__.__name__ + ": " + str(ex))
def placeSingleBet(): try: accountStr = request.args.get("account") if accountStr is None: return make_response(jsonify(error="Specify account in query params"), 500) account = Account(accountStr, peerplays_instance = ppy, full=True) body = request.get_json() asset_symbol = body['asset_symbol'] bet_amount = body['bet_amount'] betting_market_id = body['betting_market_id'] odds = body['odds'] back_or_lay = body['back_or_lay'] a = Amount(bet_amount, asset_symbol) ppy.bet_place(betting_market_id, a, odds, back_or_lay, account['id'], fee_asset = asset_symbol) time.sleep(3) # until next block is produced unmatchedBets = bookie.getUnmatchedBets(account['id']) for bet in reversed(unmatchedBets): if bet['betting_market_id'] == betting_market_id and bet['back_or_lay'] == back_or_lay and bet['backer_multiplier'] == odds * 10000: #10000 = precision return jsonify(bet) # only reachable if bet has already been fully matched matchedBets = bookie.getMatchedBets(account['id']) for bet in matchedBets: if bet['betting_market_id'] == betting_market_id and bet['back_or_lay'] == back_or_lay and bet['backer_multiplier'] == odds * 10000: #10000 = precision return jsonify(bet) except Exception as e: return make_response(jsonify(error=e.__doc__), 500)
def getAccounts(self, idList): accounts = [] try: for accountId in idList: accounts.append( Account(accountId, peerplays_instance=self.get_node())) return accounts except Exception as ex: raise NodeException(ex.__class__.__name__ + ": " + str(ex))
def proposals(ctx, account): """ List proposals """ proposals = Proposals(account) t = PrettyTable([ "id", "expiration", "proposer", "required approvals", "available approvals", "review period time", "proposal", ]) t.align = "l" for proposal in proposals: if proposal.proposer: proposer = Account(proposal.proposer, peerplays_instance=ctx.peerplays)["name"] else: proposer = "n/a" t.add_row([ proposal["id"], proposal["expiration_time"], proposer, [ Account(x)["name"] for x in (proposal["required_active_approvals"] + proposal["required_owner_approvals"]) ], json.dumps( [ Account(x)["name"] for x in proposal["available_active_approvals"] ] + proposal["available_key_approvals"] + proposal["available_owner_approvals"], indent=1, ), proposal.get("review_period_time", None), json.dumps(proposal["proposed_transaction"], indent=4), ]) click.echo(str(t))
def balance(ctx, accounts): """ Show Account balances """ t = PrettyTable(["Account", "Amount"]) t.align = "r" for a in accounts: account = Account(a, peerplays_instance=ctx.peerplays) for b in account.balances: t.add_row([str(a), str(b)]) click.echo(str(t))
def test_predefined_data(self): from peerplays.account import Account # Inject test data into cache _cache = ObjectCache(default_expiration=60 * 60 * 1) for i in test_objects: _cache[i["id"]] = i self.assertEqual(_cache['1.19.5']["test"], "passed") BlockchainObject._cache = _cache account = Account("1.2.0") self.assertEqual(account["name"], "committee-account-passed")
def selectAccount(self, accountId): # if there are any pending operations the user need to finish # that first if self.getPendingTransaction() and len( self.getPendingTransaction().list_operations()) > 0: raise BroadcastActiveOperationsExceptions try: account = Account(accountId, peerplays_instance=self.get_node()) self.get_node().config["default_account"] = account['name'] return account['id'] + ' - ' + account['name'] except Exception as ex: raise NodeException(ex.__class__.__name__ + ": " + str(ex))
def __init__( self, accounts=[], objects=[], on_tx=None, on_object=None, on_block=None, on_account=None, peerplays_instance=None, ): # Events super(Notify, self).__init__() self.events = Events() # PeerPlays instance self.peerplays = peerplays_instance or shared_peerplays_instance() # Accounts account_ids = [] for account_name in accounts: account = Account( account_name, peerplays_instance=self.peerplays ) account_ids.append(account["id"]) # Callbacks if on_tx: self.on_tx += on_tx if on_object: self.on_object += on_object if on_block: self.on_block += on_block if on_account: self.on_account += on_account # Open the websocket self.websocket = PeerPlaysWebsocket( urls=self.peerplays.rpc.urls, user=self.peerplays.rpc.user, password=self.peerplays.rpc.password, accounts=account_ids, objects=objects, on_tx=on_tx, on_object=on_object, on_block=on_block, on_account=self.process_account, )
def print_permissions(account): t = PrettyTable(["Permission", "Threshold", "Key/Account"], hrules=allBorders) t.align = "r" for permission in ["owner", "active"]: auths = [] # account auths: for authority in account[permission]["account_auths"]: auths.append("%s (%d)" % (Account(authority[0])["name"], authority[1])) # key auths: for authority in account[permission]["key_auths"]: auths.append("%s (%d)" % (authority[0], authority[1])) t.add_row([ permission, account[permission]["weight_threshold"], "\n".join(auths), ]) print(t)
def listaccounts(ctx): """ List accounts (for the connected network) """ t = PrettyTable(["Name", "Key", "Owner", "Active", "Memo"]) for key in ctx.blockchain.wallet.getPublicKeys(True): for account in ctx.blockchain.wallet.getAccountsFromPublicKey(key): account = Account(account) is_owner = key in [x[0] for x in account["owner"]["key_auths"]] is_active = key in [x[0] for x in account["active"]["key_auths"]] is_memo = key == account["options"]["memo_key"] t.add_row([ account["name"], key, "x" if is_owner else "", "x" if is_active else "", "x" if is_memo else "", ]) click.echo(t)
def importaccount(ctx, account, role): """ Import an account using an account password """ from peerplaysbase.account import PasswordKey password = click.prompt( "Account Passphrase", hide_input=True, ) account = Account(account, peerplays_instance=ctx.peerplays) imported = False if role == "owner": owner_key = PasswordKey(account["name"], password, role="owner") owner_pubkey = format(owner_key.get_public_key(), ctx.peerplays.rpc.chain_params["prefix"]) if owner_pubkey in [x[0] for x in account["owner"]["key_auths"]]: click.echo("Importing owner key!") owner_privkey = owner_key.get_private_key() ctx.peerplays.wallet.addPrivateKey(owner_privkey) imported = True if role == "active": active_key = PasswordKey(account["name"], password, role="active") active_pubkey = format(active_key.get_public_key(), ctx.peerplays.rpc.chain_params["prefix"]) if active_pubkey in [x[0] for x in account["active"]["key_auths"]]: click.echo("Importing active key!") active_privkey = active_key.get_private_key() ctx.peerplays.wallet.addPrivateKey(active_privkey) imported = True if role == "memo": memo_key = PasswordKey(account["name"], password, role=role) memo_pubkey = format(memo_key.get_public_key(), ctx.peerplays.rpc.chain_params["prefix"]) if memo_pubkey == account["memo_key"]: click.echo("Importing memo key!") memo_privkey = memo_key.get_private_key() ctx.peerplays.wallet.addPrivateKey(memo_privkey) imported = True if not imported: click.echo("No matching key(s) found. Password correct?")
def test_finalize(self): account = Account(account_id) op = operations.Transfer( **{ "fee": { "asset_id": "1.3.0", "amount": 1 }, "from": account_id, "to": '1.2.8', "amount": { "asset_id": "1.3.0", "amount": 1 } }) tx = self.ppy.finalizeOp(op, account, "active") self.assertEqual(len(tx["signatures"]), 1)
def retrieve_data(self): self.data = None if self.account_name is None or self.asset is None: logging.error( "retrieve data of source Peerplays Balance failed, because of missing information" ) return None try: self.data = Account(self.account_name).balance(self.asset).amount except AssetDoesNotExistsException as e: logging.error("Asset does not exist: " + str(e)) except AccountDoesNotExistsException as e: logging.error("Account does not exist: " + str(e)) except ValueError as e: logging.error( str(e) + " -- This usually happens when Peerplays is not set up correctly." )
def retrieve_data(self): account = self.get_witness_account() proposals = Proposals(account) # list of open proposals proposals.refresh() proposals = Proposals(account) data = [] for proposal in proposals: if proposal.proposer: proposer = Account(proposal.proposer)["name"] else: proposer = "n/a" data.append( dict( proposal_id=proposal["id"], expiration_time=proposal["expiration_time"], # proposer, # [ # Account(x)["name"] # for x in ( # proposal["required_active_approvals"] # + proposal["required_owner_approvals"] # ) # ], # json.dumps( # [Account(x)["name"] for x in proposal["available_active_approvals"]] # + proposal["available_key_approvals"] # + proposal["available_owner_approvals"], # indent=1, # ), # proposal.get("review_period_time", None), # json.dumps(proposal["proposed_transaction"], indent=4), )) self._set_data(data)
def permissions(ctx, account): """ Show permissions of an account """ print_permissions(Account(account))
def getMatchedBets(bettor_id): try: a = Account(bettor_id, peerplays_instance=ppy, full=True) return jsonify(bookie.getMatchedBets(a['id'])) except Exception as e: return make_response(jsonify(error=e.__doc__), 500)
def info(ctx, objects): """ Obtain all kinds of information """ if not objects: t = PrettyTable(["Key", "Value"]) t.align = "l" info = ctx.peerplays.rpc.get_dynamic_global_properties() for key in info: t.add_row([key, info[key]]) click.echo(t.get_string(sortby="Key")) for obj in objects: # Block if re.match("^[0-9]*$", obj): block = Block(obj, peerplays_instance=ctx.peerplays) if block: t = PrettyTable(["Key", "Value"]) t.align = "l" for key in sorted(block): value = block[key] if key == "transactions": value = json.dumps(value, indent=4) t.add_row([key, value]) click.echo(t) else: click.echo("Block number %s unknown" % obj) # Object Id elif len(obj.split(".")) == 3: data = ctx.peerplays.rpc.get_object(obj) if data: t = PrettyTable(["Key", "Value"]) t.align = "l" for key in sorted(data): value = data[key] if isinstance(value, dict) or isinstance(value, list): value = json.dumps(value, indent=4) t.add_row([key, value]) click.echo(t) else: click.echo("Object %s unknown" % obj) # Asset elif obj.upper() == obj: data = Asset(obj) t = PrettyTable(["Key", "Value"]) t.align = "l" for key in sorted(data): value = data[key] if isinstance(value, dict): value = json.dumps(value, indent=4) t.add_row([key, value]) click.echo(t) # Public Key elif re.match("^PPY.{48,55}$", obj): account = ctx.peerplays.wallet.getAccountFromPublicKey(obj) if account: t = PrettyTable(["Account"]) t.align = "l" t.add_row([account]) click.echo(t) else: click.echo("Public Key not known" % obj) # Account name elif re.match("^[a-zA-Z0-9\-\._]{2,64}$", obj): account = Account(obj, full=True) if account: t = PrettyTable(["Key", "Value"]) t.align = "l" for key in sorted(account): value = account[key] if isinstance(value, dict) or isinstance(value, list): value = json.dumps(value, indent=4) t.add_row([key, value]) click.echo(t) else: click.echo("Account %s unknown" % obj) else: click.echo("Couldn't identify object to read")
def getHistory(bettor_id, limit=10): a = Account(bettor_id, peerplays_instance=ppy, full=True) history = [] for line in a.history(limit=limit): history.append(line) return history
def getAccount(self, name): try: return Account(name, peerplays_instance=self.get_node()) except Exception as ex: raise NodeException(ex.__class__.__name__ + ": " + str(ex))
def getAccountDetails(bettor_id): a = Account(bettor_id, peerplays_instance=ppy, full=True) return a
def approve(self, pid, oid, **kwargs): """ Approve a proposal This call basically flags a single update operation of a proposal as "approved". Only if all operations in the proposal are approved, will this tool approve the whole proposal and otherwise ignore the proposal. The call has to identify the correct operation of a proposal on its own. Internally, a proposal is approved partially using a map that contains the approval of each operation in a proposal. Once all operations of a proposal are approved, the whole proopsal is approved. :param str pid: Proposal id :param int oid: Operation number within the proposal """ if pid[:3] == "0.0": log.info("Cannot approve pending-for-broadcast proposals") return assert self.approving_account, "No approving_account defined!" Lookup.approval_map[pid][oid] = True def pretty_proposal_map(): ret = dict() for k, v in Lookup.approval_map.items(): ret[k] = "{:.1f}".format(sum(v.values()) / len(v) * 100) return ret log.info("Approval Map: {}".format(pretty_proposal_map())) approved_read_for_delete = [] for p in Lookup.approval_map: if all(Lookup.approval_map[p].values()): proposal = Proposal(p) account = Account(self.approving_account) if account["id"] not in proposal["available_active_approvals"]: log.info("Approving proposal {} by {}".format( p, account["name"])) approved_read_for_delete.append(p) try: log.info(self.peerplays.approveproposal( p, account=self.approving_account, append_to=Lookup.direct_buffer )) except Exception as e: log.debug("Exception when approving proposal: {}".format( str(e))) # Not raising as at this point, the only reason for # this to fail is (probably) for the proposal to be # approved already - in the meantime. pass else: log.info( "Proposal {} has already been approved by {}".format( p, account["name"]) ) # In order not to approve the same proposal again and again, we remove # it from the map for p in approved_read_for_delete: del Lookup.approval_map[p]
def test_account(self): Account("witness-account") Account("1.2.3") asset = Asset("1.3.0") symbol = asset["symbol"] account = Account("witness-account", full=True) self.assertEqual(account.name, "witness-account") self.assertEqual(account["name"], account.name) self.assertEqual(account["id"], "1.2.1") self.assertIsInstance(account.balance("1.3.0"), Amount) self.assertIsInstance(account.balance({"symbol": symbol}), Amount) self.assertIsInstance(account.balances, list) for h in account.history(limit=1): pass # BlockchainObjects method account.cached = False self.assertTrue(account.items()) account.cached = False self.assertIn("id", account) account.cached = False self.assertEqual(account["id"], "1.2.1") self.assertEqual(str(account), "<Account 1.2.1>") self.assertIsInstance(Account(account), Account)