def createAlias(self, alias, txFee=pywaves.DEFAULT_ALIAS_FEE, timestamp=0): aliasWithNetwork = b'\x02' + str(pywaves.CHAIN_ID) + struct.pack( ">H", len(alias)) + crypto.str2bytes(alias) if not self.privateKey: msg = 'Private key required' logging.error(msg) pywaves.throw_error(msg) else: if timestamp == 0: timestamp = int(time.time() * 1000) sData = b'\x0a' + \ base58.b58decode(self.publicKey) + \ struct.pack(">H", len(aliasWithNetwork)) + \ crypto.str2bytes(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 pywaves.wrapper('/alias/broadcast/create', data)
def cancelOrder(self, assetPair, order): if not pywaves.OFFLINE: if order.status() == 'Filled': msg = "Order already filled" logging.error(msg) pywaves.throw_error(msg) elif not order.status(): msg = "Order not found" logging.error(msg) pywaves.throw_error(msg) sData = base58.b58decode(self.publicKey) + \ base58.b58decode(order.orderId) signature = crypto.sign(self.privateKey, sData) data = json.dumps({ "sender": self.publicKey, "orderId": order.orderId, "signature": signature }) req = pywaves.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=pywaves.MATCHER) if pywaves.OFFLINE: return req else: id = -1 if req['status'] == 'OrderCanceled': id = req['orderId'] logging.info('Order Cancelled - ID: %s' % id) return id
def leaseCancel(self, leaseId, txFee=pywaves.DEFAULT_LEASE_FEE, timestamp=0): if not self.privateKey: msg = 'Private key required' logging.error(msg) pywaves.throw_error(msg) elif not pywaves.OFFLINE and self.balance() < txFee: msg = 'Insufficient Waves balance' logging.error(msg) pywaves.throw_error(msg) else: if timestamp == 0: timestamp = int(time.time() * 1000) sData = b'\x09' + \ base58.b58decode(self.publicKey) + \ struct.pack(">Q", txFee) + \ struct.pack(">Q", timestamp) + \ base58.b58decode(leaseId) signature = crypto.sign(self.privateKey, sData) data = json.dumps({ "senderPublicKey": self.publicKey, "txId": leaseId, "fee": txFee, "timestamp": timestamp, "signature": signature }) req = pywaves.wrapper('/leasing/broadcast/cancel', data) if pywaves.OFFLINE: return req elif 'leaseId' in req: return req['leaseId']
def _postOrder(self, amountAsset, priceAsset, orderType, amount, price, maxLifetime=30 * 86400, matcherFee=pywaves.DEFAULT_MATCHER_FEE, timestamp=0): if timestamp == 0: timestamp = int(time.time() * 1000) expiration = timestamp + maxLifetime * 1000 asset1 = b'\0' if amountAsset.assetId == '' else b'\1' + base58.b58decode( amountAsset.assetId) asset2 = b'\0' if priceAsset.assetId == '' else b'\1' + base58.b58decode( priceAsset.assetId) sData = base58.b58decode(self.publicKey) + \ base58.b58decode(pywaves.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": pywaves.MATCHER_PUBLICKEY, "assetPair": { "amountAsset": amountAsset.assetId, "priceAsset": priceAsset.assetId, }, "orderType": otype, "price": price, "amount": amount, "timestamp": timestamp, "expiration": expiration, "matcherFee": matcherFee, "signature": signature }) req = pywaves.wrapper('/matcher/orderbook', data, host=pywaves.MATCHER) id = -1 if 'status' in req: if req['status'] == 'OrderRejected': msg = 'Order Rejected - %s' % req['message'] logging.error(msg) pywaves.throw_error(msg) elif req['status'] == 'OrderAccepted': id = req['message']['id'] logging.info('Order Accepted - ID: %s' % id) elif not pywaves.OFFLINE: logging.error(req) pywaves.throw_error(req) else: return req return id
def issue_asset_payload(address, pubkey, name, description, quantity, script=None, decimals=2, reissuable=True, fee=pywaves.DEFAULT_ASSET_FEE, timestamp=0): if not address.privateKey: msg = 'Private key required' logging.error(msg) pywaves.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) pywaves.throw_error(msg) else: # it looks like script can always be 'None' (might be a bug) if script: rawScript = base64.b64decode(script) scriptLength = len(rawScript) if timestamp == 0: timestamp = waves_timestamp() sData = b'\3' + \ b'\2' + \ crypto.str2bytes(str(pywaves.CHAIN_ID)) + \ base58.b58decode(pubkey) + \ 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", fee) + \ struct.pack(">Q", timestamp) + \ (b'\1' + struct.pack(">H", scriptLength) + rawScript if script else b'\0') signature = crypto.sign(address.privateKey, sData) data = json.dumps( { "type": 3, "version": 2, "senderPublicKey": pubkey, "name": name, "description": description, "quantity": quantity, "decimals": decimals, "reissuable": reissuable, "fee": fee, "timestamp": timestamp, "proofs": [signature] }, indent=4) return data
def trades(self, *args): if len(args)==1: limit = args[0] if limit > 0 and limit <= pywaves.MAX_WDF_REQUEST: return self._getMarketData('/api/trades/', '%d' % limit) else: msg = 'Invalid request. Limit must be >0 and <= 100' pywaves.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))
def issueSmartAsset(self, name, description, quantity, scriptSource, decimals=0, reissuable=False, txFee=pywaves.DEFAULT_ASSET_FEE): script = pywaves.wrapper('/utils/script/compile', scriptSource)['script'][7:] if not self.privateKey: msg = 'Private key required' logging.error(msg) pywaves.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) pywaves.throw_error(msg) else: compiledScript = base64.b64decode(script) scriptLength = len(compiledScript) timestamp = int(time.time() * 1000) sData = b'\3' + \ b'\2' + \ crypto.str2bytes(str(pywaves.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 }) print(data) req = pywaves.wrapper('/transactions/broadcast', data) if pywaves.OFFLINE: return req else: return req
def transfer_asset_payload(address, pubkey, recipient, assetid, amount, attachment='', feeAsset='', fee=pywaves.DEFAULT_TX_FEE, timestamp=0): if amount <= 0: msg = 'Amount must be > 0' logging.error(msg) pywaves.throw_error(msg) else: if timestamp == 0: timestamp = waves_timestamp() sData = b'\4' + \ b'\2' + \ base58.b58decode(pubkey) + \ (b'\1' + base58.b58decode(assetid) if assetid else b'\0') + \ (b'\1' + base58.b58decode(feeAsset) if feeAsset else b'\0') + \ struct.pack(">Q", timestamp) + \ struct.pack(">Q", amount) + \ struct.pack(">Q", fee) + \ base58.b58decode(recipient) + \ struct.pack(">H", len(attachment)) + \ crypto.str2bytes(attachment) signature = crypto.sign(address.privateKey, sData) data = json.dumps( { "type": 4, "version": 2, "senderPublicKey": pubkey, "recipient": recipient, "assetId": (assetid if assetid else ""), "feeAssetId": (feeAsset if feeAsset else ""), "amount": amount, "fee": fee, "timestamp": timestamp, "attachment": base58.b58encode(crypto.str2bytes(attachment)), "proofs": [signature] }, indent=4) return data
def issueAsset(self, name, description, quantity, decimals=0, reissuable=False, txFee=pywaves.DEFAULT_ASSET_FEE): if not self.privateKey: msg = 'Private key required' logging.error(msg) pywaves.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) pywaves.throw_error(msg) else: timestamp = int(time.time() * 1000) sData = b'\3' + \ 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) 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 = pywaves.wrapper('/assets/broadcast/issue', data) if pywaves.OFFLINE: return req else: return pywaves.Asset(req['assetId'])
def candles(self, *args): if len(args) == 2: timeframe = args[0] limit = args[1] if timeframe not in pywaves.VALID_TIMEFRAMES: msg = 'Invalid timeframe' pywaves.throw_error(msg) return logging.error(msg) elif limit > 0 and limit <= pywaves.MAX_WDF_REQUEST: return self._getMarketData('/api/candles', '%d/%d' % (timeframe, limit)) else: msg = 'Invalid request. Limit must be >0 and <= 100' pywaves.throw_error(msg) return logging.error(msg) elif len(args) == 3: timeframe = args[0] fromTimestamp = args[1] toTimestamp = args[2] if timeframe not in pywaves.VALID_TIMEFRAMES: msg = 'Invalid timeframe' pywaves.throw_error(msg) return logging.error(msg) else: return self._getMarketData( '/api/candles', '%d/%d/%d' % (timeframe, fromTimestamp, toTimestamp))
def lease(self, recipient, amount, txFee=pywaves.DEFAULT_LEASE_FEE, timestamp=0): if not self.privateKey: msg = 'Private key required' logging.error(msg) pywaves.throw_error(msg) elif amount <= 0: msg = 'Amount must be > 0' logging.error(msg) pywaves.throw_error(msg) elif not pywaves.OFFLINE and self.balance() < amount + txFee: msg = 'Insufficient Waves balance' logging.error(msg) pywaves.throw_error(msg) else: if timestamp == 0: timestamp = int(time.time() * 1000) sData = b'\x08' + \ base58.b58decode(self.publicKey) + \ base58.b58decode(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 = pywaves.wrapper('/leasing/broadcast/lease', data) return req
def sponsor_payload(address, pubkey, assetId, minimalFeeInAssets, fee=pywaves.DEFAULT_SPONSOR_FEE, timestamp=0): if not address.privateKey: msg = 'Private key required' logging.error(msg) pywaves.throw_error(msg) else: if timestamp == 0: timestamp = int(time.time() * 1000) sData = b'\x0e' + \ b'\1' + \ base58.b58decode(pubkey) + \ base58.b58decode(assetId) + \ struct.pack(">Q", minimalFeeInAssets) + \ struct.pack(">Q", fee) + \ struct.pack(">Q", timestamp) signature = crypto.sign(address.privateKey, sData) data = json.dumps( { "type": 14, "version": 1, "senderPublicKey": pubkey, "assetId": assetId, "fee": fee, "timestamp": timestamp, "minSponsoredAssetFee": minimalFeeInAssets, "proofs": [signature] }, indent=4) return data
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) pywaves.throw_error(msg) elif len(transfers) > 100: msg = 'Too many recipients' logging.error(msg) pywaves.throw_error(msg) elif not pywaves.OFFLINE and self.balance() < totalAmount + txFee: msg = 'Insufficient Waves balance' logging.error(msg) pywaves.throw_error(msg) else: if timestamp == 0: timestamp = int(time.time() * 1000) transfersData = b'' for i in range(0, len(transfers)): transfersData += base58.b58decode(transfers[i]['recipient']) + struct.pack(">Q", transfers[i]['amount']) sData = b'\x0b' + \ b'\1' + \ base58.b58decode(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 pywaves.wrapper('/transactions/broadcast', data)
def sendWaves(self, recipient, amount, attachment='', txFee=pywaves.DEFAULT_TX_FEE, timestamp=0): if not self.privateKey: msg = 'Private key required' logging.error(msg) pywaves.throw_error(msg) elif amount <= 0: msg = 'Amount must be > 0' logging.error(msg) pywaves.throw_error(msg) elif not pywaves.OFFLINE and self.balance() < amount + txFee: msg = 'Insufficient Waves balance' logging.error(msg) pywaves.throw_error(msg) else: if timestamp == 0: timestamp = int(time.time() * 1000) sData = b'\4' + \ base58.b58decode(self.publicKey) + \ b'\0\0' + \ struct.pack(">Q", timestamp) + \ struct.pack(">Q", amount) + \ struct.pack(">Q", txFee) + \ base58.b58decode(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 pywaves.wrapper('/assets/broadcast/transfer', data)
def sendAsset(self, recipient, asset, amount, attachment='', feeAsset='', txFee=pywaves.DEFAULT_TX_FEE, timestamp=0): if not self.privateKey: msg = 'Asset not issued' logging.error(msg) pywaves.throw_error(msg) elif not pywaves.OFFLINE and asset and not asset.status(): msg = 'Asset not issued' logging.error(msg) pywaves.throw_error(msg) elif amount <= 0: msg = 'Amount must be > 0' logging.error(msg) pywaves.throw_error(msg) elif not pywaves.OFFLINE and asset and self.balance(asset.assetId) < amount: msg = 'Insufficient asset balance' logging.error(msg) pywaves.throw_error(msg) elif not pywaves.OFFLINE and not asset and self.balance() < amount: msg = 'Insufficient Waves balance' logging.error(msg) pywaves.throw_error(msg) elif not pywaves.OFFLINE and not feeAsset and self.balance() < txFee: msg = 'Insufficient Waves balance' logging.error(msg) pywaves.throw_error(msg) elif not pywaves.OFFLINE and feeAsset and self.balance(feeAsset.assetId) < txFee: msg = 'Insufficient asset balance' logging.error(msg) pywaves.throw_error(msg) else: if feeAsset: feeInfos = pywaves.wrapper('/assets/details/' + feeAsset.assetId) if feeInfos['minSponsoredAssetFee']: txFee = feeInfos['minSponsoredAssetFee'] if timestamp == 0: timestamp = int(time.time() * 1000) sData = b'\4' + \ base58.b58decode(self.publicKey) + \ (b'\1' + base58.b58decode(asset.assetId) if asset else b'\0') + \ (b'\1' + base58.b58decode(feeAsset.assetId) if feeAsset else b'\0') + \ struct.pack(">Q", timestamp) + \ struct.pack(">Q", amount) + \ struct.pack(">Q", txFee) + \ base58.b58decode(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 pywaves.wrapper('/assets/broadcast/transfer', data)