Example #1
0
    def cancel_order(self, order: Order) -> bool:
        assert (isinstance(order, Order))

        order_hash = self.zrx_exchange.get_order_hash(order.zrx_order)
        self.logger.info(f"Cancelling order #{order_hash}...")

        cancel_msg = self.zrx_exchange.web3.sha3(text=f'cancel:{order_hash}')
        v, r, s = to_vrs(eth_sign(cancel_msg, self.zrx_exchange.web3))
        signature = bytes_to_hexstring(bytes([v])) + \
                    bytes_to_hexstring(r)[2:] + \
                    bytes_to_hexstring(s)[2:] + \
                    "03"  # EthSign

        cancel = {
            "cancellations": [{
                "orderHash": order_hash,
                "signature": signature
            }]
        }

        response = requests.post(f"{self.zrx_api.api_server}/v2/orders/cancel",
                                 json=cancel,
                                 timeout=self.zrx_api.timeout)
        if response.ok:
            data = response.json()[0]  # We suppose only one cancel
            if data.get('success'):
                self.logger.info(f"Cancelled order #{order_hash}")
                return True
            else:
                self.logger.error(
                    f"Failed to cancel: {http_response_summary(response)}")
                return False
        else:
            self.logger.info(f"Failed to cancel order #{order_hash}")
            return False
Example #2
0
    def _http_authenticated(self, method: str, api_path: str, resource: str,
                            body):
        assert (isinstance(method, str))
        assert (isinstance(api_path, str))
        assert (isinstance(resource, str))
        assert (isinstance(body, dict) or (body is None) or (body, list))

        data = json.dumps(body, separators=(',', ':'))
        nonce = int(time.time() * 1000)

        params = {'method': method, 'uri': resource, 'nonce': nonce}

        if body is not None:
            params['body'] = body

        payload = str(nonce)
        signature = self._create_signature(payload)

        v, r, s = to_vrs(signature)

        auth_header = f"NONCE {self.account_id}.{self.api_key}"\
            f".{v}"\
            f".{bytes_to_hexstring(r)}"\
            f".{bytes_to_hexstring(s)}"

        headers = {"Authorization": auth_header, "Nonce": str(nonce)}
        if body is not None:
            headers["Content-Type"] = "application/json"

        return self._result(
            requests.request(method=method,
                             url=f"{self.api_server}{api_path}{resource}",
                             data=data,
                             headers=headers,
                             timeout=self.timeout))
Example #3
0
    def cancel_order(self, order: Order) -> bool:
        assert(isinstance(order, Order))

        nonce = self.next_nonce()
        signed_data = keccak_256(encode_bytes(hexstring_to_bytes(order.order_hash)) +
                                 encode_uint256(nonce)).digest()

        signature = eth_sign(signed_data, self.idex.web3)
        v, r, s = to_vrs(signature)

        data = {
            'orderHash': order.order_hash,
            'nonce': str(nonce),
            'address': self._our_address(),
            'v': v,
            'r': bytes_to_hexstring(r),
            's': bytes_to_hexstring(s)
        }

        self.logger.info(f"Cancelling order #{order.order_id}...")

        result = self._http_post("/cancel", data)
        success = result['success'] == 1

        if success:
            self.logger.info(f"Cancelled order #{order.order_id}")
        else:
            self.logger.info(f"Failed to cancel order #{order.order_id}")

        return success
Example #4
0
    def place_order(self,
                    pay_token: Address,
                    pay_amount: Wad,
                    buy_token: Address,
                    buy_amount: Wad) -> Order:
        """Places a new order.

        Args:
            pay_token: Address of the ERC20 token you want to put on sale.
            pay_amount: Amount of the `pay_token` token you want to put on sale.
            buy_token: Address of the ERC20 token you want to be paid with.
            buy_amount: Amount of the `buy_token` you want to receive.

        Returns:
            New order as an instance of the :py:class:`pyexchange.idex.Order` class.
        """
        assert(isinstance(pay_token, Address))
        assert(isinstance(pay_amount, Wad))
        assert(isinstance(buy_token, Address))
        assert(isinstance(buy_amount, Wad))

        expires = 0
        nonce = self.next_nonce()
        order_hash = keccak_256(encode_address(self.idex.address) +
                                encode_address(buy_token) +
                                encode_uint256(buy_amount.value) +
                                encode_address(pay_token) +
                                encode_uint256(pay_amount.value) +
                                encode_uint256(expires) +
                                encode_uint256(nonce) +
                                encode_address(Address(self._our_address()))).digest()

        signature = eth_sign(order_hash, self.idex.web3)
        v, r, s = to_vrs(signature)

        data = {
            'tokenBuy': buy_token.address,
            'amountBuy': str(buy_amount.value),
            'tokenSell': pay_token.address,
            'amountSell': str(pay_amount.value),
            'address': self._our_address(),
            'nonce': str(nonce),
            'expires': expires,
            'v': v,
            'r': bytes_to_hexstring(r),
            's': bytes_to_hexstring(s)
        }

        self.logger.info(f"Placing order selling {pay_amount} {pay_token} for {buy_amount} {buy_token}...")

        result = self._http_post("/order", data)
        order = self._json_to_order(result)

        self.logger.info(f"Placed order selling {pay_amount} {pay_token} for {buy_amount} {buy_token} as #{order.order_id}")

        return order
Example #5
0
    def create_order(self,
                     pay_token: Address,
                     pay_amount: Wad,
                     buy_token: Address,
                     buy_amount: Wad,
                     expires: int) -> Order:
        """Creates a new off-chain order.

        Although it's not necessary to have any amount of `pay_token` deposited to EtherDelta
        before placing an order, nobody will be able to take this order until some balance of
        'pay_token' is provided.

        If you want to trade raw ETH, pass `Address('0x0000000000000000000000000000000000000000')`
        as either `pay_token` or `buy_token`.

        Args:
            pay_token: Address of the ERC20 token you want to put on sale.
            pay_amount: Amount of the `pay_token` token you want to put on sale.
            buy_token: Address of the ERC20 token you want to be paid with.
            buy_amount:  Amount of the `buy_token` you want to receive.
            expires: The block number after which the order will expire.

        Returns:
            Newly created order as an instance of the :py:class:`pymaker.etherdelta.Order` class.
        """

        assert(isinstance(pay_token, Address))
        assert(isinstance(pay_amount, Wad))
        assert(isinstance(buy_token, Address))
        assert(isinstance(buy_amount, Wad))
        assert(isinstance(expires, int) and (expires > 0))
        assert(pay_amount > Wad(0))
        assert(buy_amount > Wad(0))

        nonce = self.random_nonce()
        order_hash = hashlib.sha256(encode_address(self.address) +
                                    encode_address(buy_token) +
                                    encode_uint256(buy_amount.value) +
                                    encode_address(pay_token) +
                                    encode_uint256(pay_amount.value) +
                                    encode_uint256(expires) +
                                    encode_uint256(nonce)).digest()

        signature = eth_sign(order_hash, self.web3)
        v, r, s = to_vrs(signature)

        return Order(self, Address(self.web3.eth.defaultAccount), pay_token, pay_amount, buy_token, buy_amount,
                     expires, nonce, v, r, s)
Example #6
0
    def sign_order(self, order: Order) -> Order:
        """Signs an order so it can be submitted to the relayer.

        Order will be signed by the `web3.eth.defaultAccount` account.

        Args:
            order: Order you want to sign.

        Returns:
            Signed order. Copy of the order passed as a parameter with the `ec_signature_r`, `ec_signature_s`
            and `ec_signature_v` fields filled with signature values.
        """
        assert(isinstance(order, Order))

        signature = eth_sign(hexstring_to_bytes(self.get_order_hash(order)), self.web3)
        v, r, s = to_vrs(signature)

        signed_order = copy.copy(order)
        signed_order.ec_signature_r = bytes_to_hexstring(r)
        signed_order.ec_signature_s = bytes_to_hexstring(s)
        signed_order.ec_signature_v = v
        return signed_order
Example #7
0
    def sign_order(self, order: Order) -> Order:
        """Signs an order so it can be submitted to the relayer.

        Order will be signed by the `web3.eth.defaultAccount` account.

        Args:
            order: Order you want to sign.

        Returns:
            Signed order. Copy of the order passed as a parameter with the `signature` field filled with signature.
        """
        assert (isinstance(order, Order))

        signature = eth_sign(hexstring_to_bytes(self.get_order_hash(order)),
                             self.web3)
        v, r, s = to_vrs(signature)

        signed_order = copy.copy(order)
        signed_order.signature = bytes_to_hexstring(bytes([v])) + \
                                 bytes_to_hexstring(r)[2:] + \
                                 bytes_to_hexstring(s)[2:] + \
                                 "03"  # EthSign
        return signed_order