Esempio n. 1
0
    def cancelOrder(self, assetPair, order):
        if not yuwaves.OFFLINE:
            if order.status() == 'Filled':
                msg = "Order already filled"
                logging.error(msg)
                yuwaves.throw_error(msg)

            elif not order.status():
                msg = "Order not found"
                logging.error(msg)
                yuwaves.throw_error(msg)
        sData = base58.b58decode(bytes(self.publicKey)) + \
                base58.b58decode(bytes(order.orderId))
        signature = crypto.sign(self.privateKey, sData)
        data = json.dumps({
            "sender": self.publicKey,
            "orderId": order.orderId,
            "signature": signature
        })
        req = yuwaves.wrapper(
            '/matcher/orderbook/%s/%s/cancel' %
            ('WAVES' if assetPair.asset1.assetId == '' else
             assetPair.asset1.assetId, 'WAVES'
             if assetPair.asset2.assetId == '' else assetPair.asset2.assetId),
            data,
            host=yuwaves.MATCHER)
        if yuwaves.OFFLINE:
            return req
        else:
            id = -1
            if req['status'] == 'OrderCanceled':
                id = req['orderId']
                logging.info('Order Cancelled - ID: %s' % id)
            return id
Esempio n. 2
0
 def createAlias(self, alias, txFee=yuwaves.DEFAULT_ALIAS_FEE, timestamp=0):
     aliasWithNetwork = b'\x02' + crypto.str2bytes(bytes(
         yuwaves.CHAIN_ID)) + struct.pack(
             ">H", len(alias)) + crypto.str2bytes(alias)
     if not self.privateKey:
         msg = 'Private key required'
         logging.error(msg)
         yuwaves.throw_error(msg)
     else:
         if timestamp == 0:
             timestamp = int(time.time() * 1000)
         sData = b'\x0a' + \
                 base58.b58decode(bytes(self.publicKey)) + \
                 struct.pack(">H", len(aliasWithNetwork)) + \
                 crypto.str2bytes(bytes(aliasWithNetwork)) + \
                 struct.pack(">Q", txFee) + \
                 struct.pack(">Q", timestamp)
         signature = crypto.sign(self.privateKey, sData)
         data = json.dumps({
             "alias": alias,
             "senderPublicKey": self.publicKey,
             "fee": txFee,
             "timestamp": timestamp,
             "signature": signature
         })
         return yuwaves.wrapper('/alias/broadcast/create', data)
Esempio n. 3
0
 def leaseCancel(self,
                 leaseId,
                 txFee=yuwaves.DEFAULT_LEASE_FEE,
                 timestamp=0):
     if not self.privateKey:
         msg = 'Private key required'
         logging.error(msg)
         yuwaves.throw_error(msg)
     elif not yuwaves.OFFLINE and self.balance() < txFee:
         msg = 'Insufficient Waves balance'
         logging.error(msg)
         yuwaves.throw_error(msg)
     else:
         if timestamp == 0:
             timestamp = int(time.time() * 1000)
         sData = b'\x09' + \
                 base58.b58decode(bytes(self.publicKey)) + \
                 struct.pack(">Q", txFee) + \
                 struct.pack(">Q", timestamp) + \
                 base58.b58decode(bytes(leaseId))
         signature = crypto.sign(self.privateKey, sData)
         data = json.dumps({
             "senderPublicKey": self.publicKey,
             "txId": leaseId,
             "fee": txFee,
             "timestamp": timestamp,
             "signature": signature
         })
         req = yuwaves.wrapper('/leasing/broadcast/cancel', data)
         if yuwaves.OFFLINE:
             return req
         elif 'leaseId' in req:
             return req['leaseId']
Esempio n. 4
0
 def issueSmartAsset(self,
                     name,
                     description,
                     quantity,
                     scriptSource,
                     decimals=0,
                     reissuable=False,
                     txFee=yuwaves.DEFAULT_ASSET_FEE):
     script = yuwaves.wrapper('/utils/script/compile',
                              scriptSource)['script'][7:]
     if not self.privateKey:
         msg = 'Private key required'
         logging.error(msg)
         yuwaves.throw_error(msg)
     elif len(name) < 4 or len(name) > 16:
         msg = 'Asset name must be between 4 and 16 characters long'
         logging.error(msg)
         yuwaves.throw_error(msg)
     else:
         compiledScript = base64.b64decode(script)
         scriptLength = len(compiledScript)
         timestamp = int(time.time() * 1000)
         sData = b'\3' + \
                 b'\2' + \
                 crypto.str2bytes(str(yuwaves.CHAIN_ID)) + \
                 base58.b58decode(self.publicKey) + \
                 struct.pack(">H", len(name)) + \
                 crypto.str2bytes(name) + \
                 struct.pack(">H", len(description)) + \
                 crypto.str2bytes(description) + \
                 struct.pack(">Q", quantity) + \
                 struct.pack(">B", decimals) + \
                 (b'\1' if reissuable else b'\0') + \
                 struct.pack(">Q", txFee) + \
                 struct.pack(">Q", timestamp) + \
                 b'\1' + \
                 struct.pack(">H", scriptLength) + \
                 compiledScript
         signature = crypto.sign(self.privateKey, sData)
         data = json.dumps({
             "type": 3,
             "senderPublicKey": self.publicKey,
             "name": name,
             "version": 2,
             "quantity": quantity,
             "timestamp": timestamp,
             "description": description,
             "decimals": decimals,
             "reissuable": reissuable,
             "fee": txFee,
             "proofs": [signature],
             "script": 'base64:' + script
         })
         req = yuwaves.wrapper('/transactions/broadcast', data)
         if yuwaves.OFFLINE:
             return req
         else:
             return req
Esempio n. 5
0
 def trades(self, *args):
     if len(args) == 1:
         limit = args[0]
         if limit > 0 and limit <= yuwaves.MAX_WDF_REQUEST:
             return self._getMarketData('/api/trades/', '%d' % limit)
         else:
             msg = 'Invalid request. Limit must be >0 and <= 100'
             yuwaves.throw_error(msg)
             return logging.error(msg)
     elif len(args) == 2:
         fromTimestamp = args[0]
         toTimestamp = args[1]
         return self._getMarketData('/api/trades',
                                    '%d/%d' % (fromTimestamp, toTimestamp))
Esempio n. 6
0
 def issueAsset(self,
                name,
                description,
                quantity,
                decimals=0,
                reissuable=False,
                txFee=yuwaves.DEFAULT_ASSET_FEE):
     if not self.privateKey:
         msg = 'Private key required'
         logging.error(msg)
         yuwaves.throw_error(msg)
     elif len(name) < 4 or len(name) > 16:
         msg = 'Asset name must be between 4 and 16 characters long'
         logging.error(msg)
         yuwaves.throw_error(msg)
     else:
         timestamp = int(time.time() * 1000)
         sData = b'\3' + \
                 base58.b58decode(bytes(self.publicKey)) + \
                 struct.pack(">H", len(name)) + \
                 crypto.str2bytes(name) + \
                 struct.pack(">H", len(description)) + \
                 crypto.str2bytes(description) + \
                 struct.pack(">Q", quantity) + \
                 struct.pack(">B", decimals) + \
                 (b'\1' if reissuable else b'\0') + \
                 struct.pack(">Q", txFee) + \
                 struct.pack(">Q", timestamp)
         signature = crypto.sign(self.privateKey, sData)
         data = json.dumps({
             "senderPublicKey": self.publicKey,
             "name": name,
             "quantity": quantity,
             "timestamp": timestamp,
             "description": description,
             "decimals": decimals,
             "reissuable": reissuable,
             "fee": txFee,
             "signature": signature
         })
         req = yuwaves.wrapper('/assets/broadcast/issue', data)
         if yuwaves.OFFLINE:
             return req
         else:
             return yuwaves.Asset(req['assetId'])
Esempio n. 7
0
 def candles(self, *args):
     if len(args) == 2:
         timeframe = args[0]
         limit = args[1]
         if timeframe not in yuwaves.VALID_TIMEFRAMES:
             msg = 'Invalid timeframe'
             yuwaves.throw_error(msg)
             return logging.error(msg)
         elif limit > 0 and limit <= yuwaves.MAX_WDF_REQUEST:
             return self._getMarketData('/api/candles',
                                        '%d/%d' % (timeframe, limit))
         else:
             msg = 'Invalid request. Limit must be >0 and <= 100'
             yuwaves.throw_error(msg)
             return logging.error(msg)
     elif len(args) == 3:
         timeframe = args[0]
         fromTimestamp = args[1]
         toTimestamp = args[2]
         if timeframe not in yuwaves.VALID_TIMEFRAMES:
             msg = 'Invalid timeframe'
             yuwaves.throw_error(msg)
             return logging.error(msg)
         else:
             return self._getMarketData(
                 '/api/candles',
                 '%d/%d/%d' % (timeframe, fromTimestamp, toTimestamp))
Esempio n. 8
0
 def getOrderHistory(self, assetPair, timestamp=0):
     if timestamp == 0:
         timestamp = int(time.time() * 1000)
     sData = base58.b58decode(bytes(self.publicKey)) + \
             struct.pack(">Q", timestamp)
     signature = crypto.sign(self.privateKey, sData)
     data = {
         "Accept": "application/json",
         "Timestamp": bytes(timestamp),
         "Signature": signature
     }
     req = yuwaves.wrapper(
         '/matcher/orderbook/%s/%s/publicKey/%s' %
         ('WAVES' if assetPair.asset1.assetId == '' else
          assetPair.asset1.assetId, 'WAVES' if assetPair.asset2.assetId
          == '' else assetPair.asset2.assetId, self.publicKey),
         headers=data,
         host=yuwaves.MATCHER)
     if 'message' in req:
         msg = req['message']
         logging.error(msg)
         yuwaves.throw_error(msg)
     return req
Esempio n. 9
0
    def sendWaves(self,
                  recipient,
                  amount,
                  attachment='',
                  txFee=yuwaves.DEFAULT_TX_FEE,
                  timestamp=0):
        if not self.privateKey:
            msg = 'Private key required'
            logging.error(msg)
            yuwaves.throw_error(msg)

        elif amount <= 0:
            msg = 'Amount must be > 0'
            logging.error(msg)
            yuwaves.throw_error(msg)
        elif not yuwaves.OFFLINE and self.balance() < amount + txFee:
            msg = 'Insufficient Waves balance'
            logging.error(msg)
            yuwaves.throw_error(msg)

        else:
            if timestamp == 0:
                timestamp = int(time.time() * 1000)
            sData = b'\4' + \
                    base58.b58decode(bytes(self.publicKey)) + \
                    b'\0\0' + \
                    struct.pack(">Q", timestamp) + \
                    struct.pack(">Q", amount) + \
                    struct.pack(">Q", txFee) + \
                    base58.b58decode(bytes(recipient.address)) + \
                    struct.pack(">H", len(attachment)) + \
                    crypto.str2bytes(attachment)
            signature = crypto.sign(self.privateKey, sData)
            data = json.dumps({
                "senderPublicKey":
                self.publicKey,
                "recipient":
                recipient.address,
                "amount":
                amount,
                "fee":
                txFee,
                "timestamp":
                timestamp,
                "attachment":
                base58.b58encode(crypto.str2bytes(attachment)),
                "signature":
                signature
            })

            return yuwaves.wrapper('/assets/broadcast/transfer', data)
Esempio n. 10
0
 def lease(self,
           recipient,
           amount,
           txFee=yuwaves.DEFAULT_LEASE_FEE,
           timestamp=0):
     if not self.privateKey:
         msg = 'Private key required'
         logging.error(msg)
         yuwaves.throw_error(msg)
     elif amount <= 0:
         msg = 'Amount must be > 0'
         logging.error(msg)
         yuwaves.throw_error(msg)
     elif not yuwaves.OFFLINE and self.balance() < amount + txFee:
         msg = 'Insufficient Waves balance'
         logging.error(msg)
         yuwaves.throw_error(msg)
     else:
         if timestamp == 0:
             timestamp = int(time.time() * 1000)
         sData = b'\x08' + \
                 base58.b58decode(bytes(self.publicKey)) + \
                 base58.b58decode(bytes(recipient.address)) + \
                 struct.pack(">Q", amount) + \
                 struct.pack(">Q", txFee) + \
                 struct.pack(">Q", timestamp)
         signature = crypto.sign(self.privateKey, sData)
         data = json.dumps({
             "senderPublicKey": self.publicKey,
             "recipient": recipient.address,
             "amount": amount,
             "fee": txFee,
             "timestamp": timestamp,
             "signature": signature
         })
         req = yuwaves.wrapper('/leasing/broadcast/lease', data)
         return req
Esempio n. 11
0
    def _postOrder(self,
                   amountAsset,
                   priceAsset,
                   orderType,
                   amount,
                   price,
                   maxLifetime=30 * 86400,
                   matcherFee=yuwaves.DEFAULT_MATCHER_FEE,
                   timestamp=0):

        from decimal import Decimal
        if not isinstance(amount, Decimal) or not isinstance(price, Decimal):
            raise Exception('Decimal type expected')
        amount = int((amount * Decimal(
            (0, (1, ), amountAsset.decimals))).to_integral_exact())
        price = int((price * Decimal(
            (0, (1, ), priceAsset.decimals))).to_integral_exact())

        if timestamp == 0:
            timestamp = int(time.time() * 1000)
        expiration = timestamp + maxLifetime * 1000
        asset1 = b'\0' if amountAsset.assetId == '' else b'\1' + base58.b58decode(
            bytes(amountAsset.assetId))
        asset2 = b'\0' if priceAsset.assetId == '' else b'\1' + base58.b58decode(
            bytes(priceAsset.assetId))
        sData = base58.b58decode(bytes(self.publicKey)) + \
                base58.b58decode(bytes(yuwaves.MATCHER_PUBLICKEY)) + \
                asset1 + \
                asset2 + \
                orderType + \
                struct.pack(">Q", price) + \
                struct.pack(">Q", amount) + \
                struct.pack(">Q", timestamp) + \
                struct.pack(">Q", expiration) + \
                struct.pack(">Q", matcherFee)
        signature = crypto.sign(self.privateKey, sData)
        otype = "buy" if orderType == b'\0' else "sell"
        data = json.dumps({
            "senderPublicKey": self.publicKey,
            "matcherPublicKey": yuwaves.MATCHER_PUBLICKEY,
            "assetPair": {
                "amountAsset": amountAsset.assetId,
                "priceAsset": priceAsset.assetId,
            },
            "orderType": otype,
            "price": price,
            "amount": amount,
            "timestamp": timestamp,
            "expiration": expiration,
            "matcherFee": matcherFee,
            "signature": signature
        })
        req = yuwaves.wrapper('/matcher/orderbook', data, host=yuwaves.MATCHER)
        """
        {u'status': u'OrderAccepted', u'message': {u'assetPair': {u'priceAsset': u'Ft8X1v1LTa1ABafufpaCWyVj8KkaxUWE6xBhW6sNFJck', u'amountAsset': None}, u'orderType': u'buy', u'price': 268, u'signature': u'4LzSfA4CDLbznAsykB8fHXtvLP6ZvaUYkSowrn6KXgouatSskHRQ1chiPdq6Hyo7yXi9cdfYdTZo6NFVk8APBXuz', u'matcherFee': 300000, u'senderPublicKey': u'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', u'amount': 387444879, u'version': 1, u'expiration': 1553609813760, u'timestamp': 1551017813760, u'proofs': [u'4LzSfA4CDLbznAsykB8fHXtvLP6ZvaUYkSowrn6KXgouatSskHRQ1chiPdq6Hyo7yXi9cdfYdTZo6NFVk8APBXuz'], u'id': u'CGchfxnGKsySb36SPziRXo7AoijPUPvYReuXN9KczRwT', u'matcherPublicKey': u'7kPFrHDiGw1rCm7LPszuECwWYL3dMf6iMifLRDJQZMzy', u'sender': u'3XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'}}
        """
        id = -1
        if 'status' in req:
            if req['status'] == 'OrderRejected':
                msg = 'Order Rejected - %s' % req['message']
                logging.error(msg)
                yuwaves.throw_error(msg)
            elif req['status'] == 'OrderAccepted':
                id = str(req['message']['id'])
                logging.info('Order Accepted - ID: %s' % id)
        elif not yuwaves.OFFLINE:
            logging.error(req)
            yuwaves.throw_error(req)
        else:
            return req
        return id
Esempio n. 12
0
    def sendAsset(self,
                  recipient,
                  asset,
                  amount,
                  attachment='',
                  feeAsset='',
                  txFee=yuwaves.DEFAULT_TX_FEE,
                  timestamp=0):
        if not self.privateKey:
            msg = 'Asset not issued'
            logging.error(msg)
            yuwaves.throw_error(msg)
        elif not yuwaves.OFFLINE and asset and not asset.status():
            msg = 'Asset not issued'
            logging.error(msg)
            yuwaves.throw_error(msg)
        elif amount <= 0:
            msg = 'Amount must be > 0'
            logging.error(msg)
            yuwaves.throw_error(msg)
        elif not yuwaves.OFFLINE and asset and self.balance(
                asset.assetId) < amount:
            msg = 'Insufficient asset balance'
            logging.error(msg)
            yuwaves.throw_error(msg)
        elif not yuwaves.OFFLINE and not asset and self.balance() < amount:
            msg = 'Insufficient Waves balance'
            logging.error(msg)
            yuwaves.throw_error(msg)
        elif not yuwaves.OFFLINE and not feeAsset and self.balance() < txFee:
            msg = 'Insufficient Waves balance'
            logging.error(msg)
            yuwaves.throw_error(msg)
        elif not yuwaves.OFFLINE and feeAsset and self.balance(
                feeAsset.assetId) < txFee:
            msg = 'Insufficient asset balance'
            logging.error(msg)
            yuwaves.throw_error(msg)
        else:
            if feeAsset:
                feeInfos = yuwaves.wrapper('/assets/details/' +
                                           feeAsset.assetId)
                if feeInfos['minSponsoredAssetFee']:
                    txFee = feeInfos['minSponsoredAssetFee']
            if timestamp == 0:
                timestamp = int(time.time() * 1000)
            sData = b'\4' + \
                    base58.b58decode(bytes(self.publicKey)) + \
                    (b'\1' + base58.b58decode(bytes(asset.assetId)) if asset else b'\0') + \
                    (b'\1' + base58.b58decode(bytes(feeAsset.assetId)) if feeAsset else b'\0') + \
                    struct.pack(">Q", timestamp) + \
                    struct.pack(">Q", amount) + \
                    struct.pack(">Q", txFee) + \
                    base58.b58decode(bytes(recipient.address)) + \
                    struct.pack(">H", len(attachment)) + \
                    crypto.str2bytes(attachment)
            signature = crypto.sign(self.privateKey, sData)
            data = json.dumps({
                "assetId": (asset.assetId if asset else ""),
                "feeAssetId": (feeAsset.assetId if feeAsset else ""),
                "senderPublicKey":
                self.publicKey,
                "recipient":
                recipient.address,
                "amount":
                amount,
                "fee":
                txFee,
                "timestamp":
                timestamp,
                "attachment":
                base58.b58encode(crypto.str2bytes(attachment)),
                "signature":
                signature
            })

            return yuwaves.wrapper('/assets/broadcast/transfer', data)
Esempio n. 13
0
    def massTransferWaves(self, transfers, attachment='', timestamp=0):
        txFee = 100000 + (math.ceil((len(transfers) + 1) / 2 - 0.5)) * 100000
        totalAmount = 0

        for i in range(0, len(transfers)):
            totalAmount += transfers[i]['amount']

        if not self.privateKey:
            msg = 'Private key required'
            logging.error(msg)
            yuwaves.throw_error(msg)
        elif len(transfers) > 100:
            msg = 'Too many recipients'
            logging.error(msg)
            yuwaves.throw_error(msg)
        elif not yuwaves.OFFLINE and self.balance() < totalAmount + txFee:
            msg = 'Insufficient Waves balance'
            logging.error(msg)
            yuwaves.throw_error(msg)
        else:
            if timestamp == 0:
                timestamp = int(time.time() * 1000)
            transfersData = b''
            for i in range(0, len(transfers)):
                transfersData += base58.b58decode(
                    bytes(transfers[i]['recipient']) +
                    struct.pack(">Q", transfers[i]['amount']))
            sData = b'\x0b' + \
                    b'\1' + \
                    base58.b58decode(bytes(self.publicKey)) + \
                    b'\0' + \
                    struct.pack(">H", len(transfers)) + \
                    transfersData + \
                    struct.pack(">Q", timestamp) + \
                    struct.pack(">Q", txFee) + \
                    struct.pack(">H", len(attachment)) + \
                    crypto.str2bytes(attachment)

            signature = crypto.sign(self.privateKey, sData)

            data = json.dumps({
                "type":
                11,
                "version":
                1,
                "assetId":
                "",
                "senderPublicKey":
                self.publicKey,
                "fee":
                txFee,
                "timestamp":
                timestamp,
                "transfers":
                transfers,
                "attachment":
                base58.b58encode(crypto.str2bytes(attachment)),
                "signature":
                signature,
                "proofs": [signature]
            })

            return yuwaves.wrapper('/transactions/broadcast', data)