コード例 #1
0
ファイル: views.py プロジェクト: chris0203/pmes
#Third-party
import tornado
from jsonrpcserver.aio import methods
import ujson

# Locals
from utils.tornado_components import web
from utils.bip32keys.r8_ethereum.r8_eth import R8_Ethereum
from utils.qtum_utils.qtum import Qtum
from utils import billing
from utils.models.account import Account
import settings

validator = {
    "QTUM": lambda x: Qtum.public_key_to_hex_address(x),
    "ETH": lambda x: R8_Ethereum.public_key_to_checksum_address(x)
}


class AllContentHandler(web.ManagementSystemHandler):
    """Handles all blockchain content requests

	Endpoint: /api/blockchain/content

	Allowed methods: GET

	"""
    def set_default_headers(self):
        self.set_header("Access-Control-Allow-Origin", "*")
        self.set_header("Access-Control-Allow-Headers", "Content-Type")
        self.set_header('Access-Control-Allow-Methods', 'GET, OPTIONS')
コード例 #2
0
    async def create_account(self, **params):
        """Describes, validates data.
		"""
        model = {
            "unique": ["email", "public_key"],
            "required": ("public_key", "device_id"),
            "default": {
                "count": len(settings.AVAILABLE_COIN_ID),
                "level": 2,
                "news_count": 0,
                "email": None
            },
            "optional": ("phone", )
        }

        message = json.loads(params.get("message", "{}"))

        data = {**message.get("message"), "public_key": message["public_key"]}

        # check if all required
        required = all(
            [True if i in data.keys() else False for i in model["required"]])

        if not required:
            return {"error": 400, "reason": "Missed required fields"}

        # Unique constraint
        get_account = await self.collection.find_one(
            {"public_key": data.get("public_key")})

        # Try get account with current public key
        if get_account:
            return {"error": 400, "reason": "Unique violation error"}

        # Reload data.
        row = {
            i: data[i]
            for i in data if i in model["required"] or i in model["optional"]
        }
        row.update({i: model["default"][i] for i in model["default"]})
        if data.get("email"):
            row["email"] = data.get("email")
        row.update({"id": await self.autoincrement()})
        await self.collection.insert_one(row)
        account = await self.collection.find_one(
            {"public_key": row["public_key"]})

        logging.debug("[+] -- Creating new wallet ")
        # Create wallets
        validator = {
            "QTUM": lambda x: Qtum.public_key_to_hex_address(x),
            "ETH": lambda x: R8_Ethereum.public_key_to_checksum_address(x),
            "PUT": lambda x: Qtum.public_key_to_hex_address(x),
        }

        for coinid in settings.AVAILABLE_COIN_ID:
            database = client[coinid]
            wallet_collection = database[settings.WALLET]
            await wallet_collection.insert_one({
                "account_id":
                account["id"],
                "wallet":
                validator[coinid](account["public_key"])
            })
            wallet = await wallet_collection.find_one({
                "account_id":
                account["id"],
                "wallet":
                validator[coinid](account["public_key"])
            })

        return account
コード例 #3
0
class Account(GenesisClass):
    balance = Balance()
    blockchain = Blockchain()
    permissions = Permissions()
    mailer = Mail()
    client_storage = TornadoClient(settings.storageurl)
    client_withdraw = TornadoClient(settings.withdrawhost)

    validator = {
        "QTUM": lambda x: Qtum.public_key_to_hex_address(x),
        "ETH": lambda x: R8_Ethereum.public_key_to_checksum_address(x),
        "PUT": lambda x: Qtum.public_key_to_hex_address(x),
    }

    withdraw_address = {
        "PUTTEST": lambda x: bip32addresses.Bip32Addresses.address_to_hex(x),
        "QTUMTEST": lambda x: x
    }

    ident_offer = {0: "read_access", 1: "write_access"}

    async def withdraw_fee(self, coinid):
        if not isinstance(coinid, str):
            return {
                "error": 400,
                "reason": "Coinid type error. Must be string."
            }
        fees = {
            "BTCTEST": 0.001 * pow(10, 8),
            "ETH": 0.01 * pow(10, 8),
            "QTUMTEST": 0.5 * pow(10, 8),
            "PUTTEST": 50 * pow(10, 8),
            "LTCTEST": 0.05 * pow(10, 8)
        }
        try:
            fee = fees[coinid]
        except KeyError:
            fee = 0
        return fee

    async def logsource(self, **params):
        result = await self.client_storage.request(method_name="logsource",
                                                   **params)
        return result

    async def createaccount(self, **params):
        result = await self.client_storage.request(method_name="createaccount",
                                                   **params)
        return result

    async def getaccountdata(self, **params):
        result = await self.client_storage.request(
            method_name="getaccountdata", **params)
        return result

    async def createwallet(self, **params):
        result = await self.client_storage.request(method_name="createwallet",
                                                   **params)
        return result

    async def getnews(self, **params):
        result = await self.client_storage.request(method_name="getnews",
                                                   **params)
        return result

    async def setnews(self, **params):
        result = await self.client_storage.request(method_name="setnews",
                                                   **params)
        return result

    async def getaccountbywallet(self, **params):
        result = await self.client_storage.request(
            method_name="getaccountbywallet", **params)
        return result

    async def updatelevel(self, **params):
        result = await self.client_storage.request(method_name="updatelevel",
                                                   **params)
        return result

    async def insertoffer(self, **params):
        result = await self.client_storage.request(method_name="insertoffer",
                                                   **params)
        return result

    async def getoffer(self, **params):
        result = await self.client_storage.request(method_name="getoffer",
                                                   **params)
        return result

    async def removeoffer(self, **params):
        result = await self.client_storage.request(method_name="removeoffer",
                                                   **params)
        return result

    async def updateoffer(self, **params):
        result = await self.client_storage.request(method_name="updateoffer",
                                                   **params)
        return result

    async def mailedconfirm(self, **params):
        result = await self.client_storage.request(method_name="mailedconfirm",
                                                   **params)
        return result

    async def getoffers(self, **params):
        result = await self.client_storage.request(method_name="getoffers",
                                                   **params)
        return result

    async def getuserscontent(self, **params):
        result = await self.client_storage.request(
            method_name="getuserscontent", **params)
        return result

    async def setuserscontent(self, **params):
        result = await self.client_storage.request(
            method_name="setuserscontent", **params)
        return result

    async def updateuserscontent(self, **params):
        result = await self.client_storage.request(
            method_name="updateuserscontent", **params)
        return result

    async def getallcontent(self):
        result = await self.client_storage.request(method_name="getallcontent")
        return result

    async def getsinglecontent(self, cid):
        result = await self.client_storage.request(
            method_name="getsinglecontent", cid=cid)
        return result

    async def changecontentowner(self, **params):
        result = await self.client_storage.request(
            method_name="changecontentowner", **params)
        return result

    async def setaccessstring(self, **params):
        result = await self.client_storage.request(
            method_name="setaccessstring", **params)
        return result

    async def getreviews(self, **params):
        result = await self.client_storage.request(method_name="getreviews",
                                                   **params)
        return result

    async def setreview(self, **params):
        result = await self.client_storage.request(method_name="setreview",
                                                   **params)
        return result

    async def updatereview(self, **params):
        result = await self.client_storage.request(method_name="updatereview",
                                                   **params)
        return result

    async def writedeal(self, **params):
        result = await self.client_storage.request(method_name="writedeal",
                                                   **params)
        return result

    async def getdeals(self, **params):
        result = await self.client_storage.request(method_name="getdeals",
                                                   **params)
        return result

    async def updatedescription(self, **params):
        result = await self.client_storage.request(
            method_name="updatedescription", **params)
        return result

    async def setwriteprice(self, **params):
        result = await self.client_storage.request(method_name="setwriteprice",
                                                   **params)
        return result

    async def setreadprice(self, **params):
        result = await self.client_storage.request(method_name="setreadprice",
                                                   **params)
        return result

    async def changeowner(self, **params):
        result = await self.client_storage.request(method_name="changeowner",
                                                   **params)
        return result

    async def sharecontent(self, **params):
        result = await self.client_storage.request(method_name="sharecontent",
                                                   **params)
        return result

    async def withdraw(self, **params):
        result = await self.client_withdraw.request(method_name="withdraw",
                                                    **params)
        return result
コード例 #4
0
ファイル: balance_methods.py プロジェクト: chris0203/pmes
class Balance(object):
    async def generate_token(self,
                             length=16,
                             chars=string.ascii_letters + string.punctuation +
                             string.digits):
        return "".join(choice(chars) for x in range(0, length))

    coin_ids = settings.AVAILABLE_COIN_ID + ["PUT"]

    create_address = {
        "QTUM": lambda x: Qtum(x, mainnet=False).get_address(),
        "ETH": lambda x: R8_Ethereum(x).get_address(),
        "PUT": lambda x: Qtum(x, mainnet=False).get_address()
    }

    @verify
    async def addaddr(self, *args, **kwargs):
        """ Adding wallet address to database during account registration 

        Accepts:
            - message (signed dictionary):
                - "uid" - int (id of just created account)

        Returns:
            {"result": "ok"}

        Verified: True
        """

        message = json.loads(kwargs.get("message"))

        uid = message.get("uid")

        entropy = await self.generate_token()

        for coinid in self.coin_ids:

            client = MotorClient()
            db = client[coinid]
            balances = db[settings.BALANCE]

            # Create wallet
            address = self.create_address[coinid](entropy)
            # Check if current address does exist
            balance = await balances.find_one({"address": address})
            if balance:
                return {"error": 400, "reason": "Current address does exist."}
            # Create new wallet
            new_balance = {
                "address": address,
                "coinid": coinid,
                "amount": 0,
                "uid": uid,
                "unconfirmed": 0,
                "deposit": 0,
                "txid": None
            }
            await balances.insert_one(new_balance)

        return {"result": "ok"}

    #@verify
    async def incbalance(self, *args, **kwargs):
        """ Increments users balance 

        Accepts:
            - message (signed dictionary):
                - "address" - str
                - "amount" - int
                - "uid" - str
                - "coinid" - str

        Returns:
            - dictionary with following fields:
                - "address" - str
                - "coinid" - str
                - "amount" - int
                - "uid" - int
                - "unconfirmed" - int (0 by default)
                - "deposit" - int (0 by default)
                - "txid" - None
                
        """
        # Get data from message
        message = json.loads(kwargs.get("message", "{}"))
        address = message.get("address")
        amount = int(message.get("amount", 0))
        uid = message.get("uid")
        coinid = message.get("coinid")
        txid = message.get("txid")

        # Connect to database
        db = client[coinid]
        balances = db[settings.BALANCE]

        # Check if amount
        if not amount:
            return {"error": 400, "reason": "Funds is zero"}

        # Get account by uid or address
        if uid:
            balance = await balances.find_one({"uid": int(uid)})
        elif address:
            balance = await balances.find_one({"address": address})
        # Increment balance if account exists
        if not balance:
            return {
                "error": 404,
                "reason": "Increment balance. Balance not found"
            }

        # Update balance
        if not txid:
            await balances.find_one_and_update(
                {"address": balance["address"]},
                {"$inc": {
                    "amount": int(amount)
                }})
            result = await balances.find_one({"address": balance["address"]})

        else:
            db = client["PUT"]
            balances = db[settings.BALANCE]
            await balances.find_one_and_update(
                {"uid": balance["uid"]},
                {"$inc": {
                    "unconfirmed": int(amount)
                }})
            result = await balances.find_one({"uid": balance["uid"]})

            await balances.find_one_and_update({"uid": balance["uid"]},
                                               {"$set": {
                                                   "txid": txid
                                               }})

        account_client = SignedTornadoClient(settings.storageurl)
        account = await account_client.request(method_name="getaccountdata",
                                               **{"id": balance["uid"]})

        # Send mail to user
        if account.get("email"):
            client_email = TornadoClient(settings.emailurl)
            email_data = {
                "to":
                account["email"],
                "subject":
                "Robin8 Support",
                "optional":
                "You`ve got %s tokens. Now your balance is %s" %
                (amount / pow(10, 8), int(result["amount"]) / pow(10, 8))
            }
            await client_email.request(method_name="sendmail", **email_data)

        # Return result
        result = {i: result[i] for i in result if i != "_id"}
        result["amount"] = int(result["amount"])
        return result

    @verify
    async def decbalance(self, *args, **kwargs):
        """ Decrements users balance 
        
        Accepts:
            - message (signed dictionary):
                - "address" - str
                - "amount" - int
                - "uid" - str
                - "coinid" - str

        Returns:
            - dictionary with following fields:
                - "address" - str
                - "coinid" - str
                - "amount" - int
                - "uid" - int
                - "unconfirmed" - int (0 by default)
                - "deposit" - int (0 by default)
                - "txid" - None

        """

        message = json.loads(kwargs.get("message", "{}"))

        uid = message.get("uid")
        address = message.get("address")
        amount = int(message.get("amount", 0))
        coinid = message.get("coinid", "PUT")

        client = MotorClient()
        db = client[coinid]
        balances = db[settings.BALANCE]
        # Check if required fields exist
        if not uid and not address:
            return {
                "error": 400,
                "reason": "Missed required fields or amount is not digit"
            }
        # check if amount is not 0

        if not amount:
            return {"error": 400, "reason": "Decrement balance. Funds is zero"}
        # Get account
        if uid:
            balance = await balances.find_one({"uid": int(uid)})
        elif address:
            balance = await balances.find_one({"address": address})
        # Check if balance is enough
        if balance and (int(balance["amount"]) - amount) < 0:
            return {
                "error": 400,
                "reason": "Address does not exist or amount is not enough"
            }
        # Update account
        await balances.find_one_and_update({"uid": balance["uid"]},
                                           {"$inc": {
                                               "amount": -amount
                                           }})
        result = await balances.find_one({"uid": balance["uid"]})
        # Return balance
        balance = {i: result[i] for i in result if i != "_id"}
        balance["amount"] = int(balance["amount"])
        return balance

    @verify
    async def getbalance(self, *args, **kwargs):
        """ Returns users balance 

        Accepts:
            - message (signed dictionary)
                - "address" - str
                - "amount" - int
                - "uid" - str
                - "coinid" - str
        Returns:
            - list of dictionaries with following fields:
                - "address" - str
                - "coinid" - str
                - "amount" - int
                - "uid" - int
                - "unconfirmed" - int (0 by default)
                - "deposit" - int (0 by default)

        Verified: True

        """
        # Get data from messaqe
        message = json.loads(kwargs.get("message", "{}"))

        address = message.get("address")
        uid = message.get("uid")

        # Check if required parameters exist
        if not address and not uid:
            return {"error": 400, "reason": "Missed required fields"}

        wallets = []

        # Iter available coin id`s
        for coinid in self.coin_ids:
            logging.debug("\n Coin id")
            logging.debug(coinid)
            # Connect to appropriate database
            db = client[coinid]
            balances = db[settings.BALANCE]
            # Get balance
            if address:
                balance = await balances.find_one({"address": address})
            elif uid:
                balance = await balances.find_one({"uid": uid})
            try:
                wallets.append({
                    "address": balance["address"],
                    "amount": balance["amount"],
                    "deposit": balance["deposit"],
                    "unconfirmed": balance["unconfirmed"],
                    "coinid": coinid
                })
            except:
                continue
        if not wallets:
            return {"error": 404, "reason": "Current address does not exist"}
        return wallets

    @verify
    async def depositbalance(self, *args, **kwargs):
        """ Freeze partial balance. 
        Amount equals to offer`s price.

        Accepts:
            - message (sogned dictionary):
                - "address" - str
                - "uid" - str
                - "coinid" - str

        Returns:
                - "address" - str
                - "coinid" - str
                - "amount" - int
                - "uid" - int
                - "unconfirmed" - int (0 by default)
                - "deposit" - int (0 by default)


        Verified: True

        """
        # Get data from request
        message = json.loads(kwargs.get("message", "{}"))

        uid = int(message.get("uid", 0))
        amount = int(message.get("amount", 0))
        coinid = message.get("coinid")

        coinid = "PUT"

        # Connect to database
        db = client[coinid]
        balances = db[settings.BALANCE]

        # Check if current balance exists
        balance = await balances.find_one({"uid": uid})
        if not balance:
            return {"error": 404, "reason": "Current user was not found"}

        # Decrement amount
        updated_amount = await balances.find_one_and_update(
            {"uid": balance["uid"]}, {"$inc": {
                "amount": -amount
            }})
        # Increment deposit
        updated_deposit = await balances.find_one_and_update(
            {"uid": balance["uid"]}, {"$inc": {
                "deposit": amount
            }})
        updated = await balances.find_one({"uid": balance["uid"]})

        return {i: updated[i] for i in updated if i != "_id" and i != "txid"}

    @verify
    async def undepositbalance(self, *args, **kwargs):
        """ Returns deposit amount to the base balance
        
        Accepts:
             - message (signed dict):
                - "uid" - str
                - "amount" - int
                - "coinid" - str

        Returns:
                - "address" - str
                - "coinid" - str
                - "amount" - int
                - "uid" - int
                - "unconfirmed" - int (0 by default)
                - "deposit" - int (0 by default)

        Verified: True
        
        """
        # Get data from request
        message = json.loads(kwargs.get("message", "{}"))
        uid = int(message.get("uid", 0))
        amount = int(message.get("amount", 0))
        coinid = message.get("coinid")

        coinid = "PUT"

        # Connect to database
        db = client[coinid]
        balances = db[settings.BALANCE]

        # Try to get current balance
        balance = await balances.find_one({"uid": uid})
        if not balance:
            return {"error": 404, "reason": "Current user was not found"}

        difference = int(balance["deposit"]) - int(amount)
        if difference < 0:
            return {
                "error": 400,
                "reason": "Undeposit balance. Can not set value below zero."
            }
        # Decrement from deposit
        await balances.find_one_and_update({"uid": balance["uid"]},
                                           {"$inc": {
                                               "deposit": -amount
                                           }})
        # Increment dase balance
        await balances.find_one_and_update({"uid": balance["uid"]},
                                           {"$inc": {
                                               "amount": amount
                                           }})
        # Get just updated balance
        updated = await balances.find_one({"uid": balance["uid"]})

        return {i: updated[i] for i in updated if i != "_id" and i != "txid"}

    #@verify
    async def confirmbalance(self, *args, **kwargs):
        """ Confirm balance after trading

        Accepts:
            - message (signed dictionary):
                - "txid" - str
                - "coinid" - str
                - "amount" - int

        Returns:
                - "address" - str
                - "coinid" - str
                - "amount" - int
                - "uid" - int
                - "unconfirmed" - int (0 by default)
                - "deposit" - int (0 by default)

        Verified: True

        """
        # Get data from request
        #if message.get()
        message = json.loads(kwargs.get("message", "{}"))
        txid = message.get("txid")
        coinid = message.get("coinid")
        buyer_address = message.get("buyer_address")
        cid = message.get("cid")

        # Check if required fields exists
        if not all([txid, coinid, cid, buyer_address]):
            return {
                "error": 400,
                "reason": "Confirm balance. Missed required fields"
            }

        client_bridge = SignedTornadoClient(settings.bridges[coinid])
        offer = await client_bridge.request(method_name="get_offer",
                                            cid=cid,
                                            buyer_address=buyer_address)
        # Connect to database
        coinid = "PUT"

        database = client[coinid]
        balance_collection = database[settings.BALANCE]

        amount = int(offer["price"])
        # Try to update balance if exists
        updated = await balance_collection.find_one_and_update(
            {"txid": txid}, {"$inc": {
                "amount": int(amount)
            }})
        if not updated:
            return {
                "error": 404,
                "reason": "Confirm balance. Not found current transaction id"
            }

        # Decrement unconfirmed
        await balance_collection.find_one_and_update(
            {"txid": txid}, {"$inc": {
                "unconfirmed": -amount
            }})

        # Update users level if it is equal two
        client_storage = SignedTornadoClient(settings.storageurl)
        account = await client_storage.request(method_name="getaccountdata",
                                               **{"id": updated["uid"]})
        if "error" in account.keys():
            return {
                "error": 500,
                "reason":
                "While incrementing balance current user was not found"
            }

        if int(account["level"]) == 2:
            await client_storage.request(method_name="updatelevel",
                                         **{
                                             "id": account["id"],
                                             "level": 3
                                         })

        return {i: updated[i] for i in updated if i != "_id" and i != "txid"}