application

{'code': '400005', 'msg': 'Invalid KC-API-SIGN'} app.KucoinAPIError: Invalid KC-API-SIGN
mail@pastecode.io avatar
unknown
python
2 years ago
5.1 kB
1
Indexable
Never
# flask
# gunicorn - the web server that heroku uses to serve our applications 

import json, config
from flask import Flask, request, jsonify
from urllib.parse import urljoin
import requests
import hashlib
import hmac
import time
import base64
from urllib.parse import urlencode, urlparse
from typing import Dict, Union, List 

app = Flask(__name__)

class KucoinEndpoints:
    ticker24hr = "/api/v1/ticker"
    new_order = "/api/v1/orders"

class KucoinAPIError(Exception):
        pass 

class Kucoin(object):
    def __init__(self, api_key: str, api_secret: str, api_passphrase: str):
        self.__apikey__     = api_key
        self.__apisecret__  = api_secret
        self.__apipassphrase__  = api_passphrase
        self.__apiversion__  = '2'
        self.__endpoint__   = "https://api-futures.kucoin.com" 

    def _get_passphrase(self, passphrase: str):
        return base64.b64encode(
            hmac.new(self.__apisecret__.encode('utf-8'), passphrase.encode('utf-8'), hashlib.sha256).digest()
        )

#  For the header of KC-API-KEY
    # Use API-Secret to encrypt the prehash string {timestamp+method+endpoint+body}  
    # with sha256 HMAC. The request body is a JSON string and need to
    # be the same with the parameters passed by the API.
    # After that, use base64-encode to encrypt the result in step 1 again.

# For the KC-API-PASSPHRASE of the header:
    # For API key-V1.0, please pass requests in plaintext.
    # For API key-V2.0, please Specify KC-API-KEY-VERSION as 2 --> Encrypt passphrase with HMAC-sha256 via API-Secret --> Encode contents by base64 before you pass the request."
    def _generate_signature(self, timestamp: int, method: str, endpoint: str):
        print(timestamp)
        method = method.upper()
        print(method.upper())
        print(endpoint)
        str_to_sign = str(timestamp) + method + endpoint
        print(str_to_sign)
        return base64.b64encode(
        hmac.new(self.__apisecret__.encode('utf-8'), str_to_sign.encode('utf-8'), hashlib.sha256).digest())

    def _make_request(self, uri: str, method: str, data: Dict = None) -> Dict:
        if data is not None:
            data["timestamp"] = int(time.time() * 1000) 
            data["signature"] = self._generate_signature(data["timestamp"], method, urlparse(uri).path)
            data["passphrase"] = self._get_passphrase(self.__apipassphrase__)
        print(data)
        print(method)
        print(uri)
        if (method := method.lower()) == "post":
            response = requests.request(method=method, url=uri, params=data, headers={"KC-API-TIMESTAMP":str(data["timestamp"]), "KC-API-KEY": self.__apikey__, "KC-API-PASSPHRASE":data["passphrase"], "KC-API-KEY-VERSION": self.__apiversion__,"KC-API-SIGN":data["signature"]})
        elif method == "get":
            response = requests.request(method=method, url=uri, params=data, headers={"KC-API-TIMESTAMP":str(data["timestamp"]), "KC-API-KEY": self.__apikey__, "KC-API-PASSPHRASE":data["passphrase"], "KC-API-KEY-VERSION": self.__apiversion__,"KC-API-SIGN":data["signature"]})

        if not response.ok:
            print(response.json())
            raise KucoinAPIError(response.json()["msg"])

        return response.json()

    #----- builder action functions -----
    def fetch_ticker(self, symbol: Union[str, None] = None) -> Union[Dict, List[Dict]]:
        return self._make_request(self.__endpoint__ + KucoinEndpoints.ticker24hr, "get", {"symbol": symbol} if symbol else None)
        
        # def _make_request(self, uri: str, method: str, endpoint: str, data: Dict = None) -> Dict:
    def new_order(self, **params):
        return self._make_request(self.__endpoint__ + KucoinEndpoints.new_order, "post", params)

#-------------------

kucoin = Kucoin(config.API_KEY, config.API_SECRET, config.API_PASSPHRASE)

@app.route('/webhook', methods=['POST'])
def webhook():
    # print(request.data)
    data = json.loads(request.data)
    # data = json.dumps(request.data)
    print(data)
    if data['passphrase'] != config.WEBHOOK_PASSPHRASE:
        return {
            "code:":"error",
            "message":"invalid passphrase"
        }

    ticker = data['ticker']
    position_size = data['strategy']['position_size']
    side = data['strategy']['order_action']
    size = data['strategy']['order_contracts']
    order_price = data['strategy']['order_price']
    order_id = data['strategy']['order_id']
    strategy_opentrades_size = data['strategy']['strategy_opentrades_size']
    market_position = data['strategy']['market_position']
    market_position_size = data['strategy']['market_position_size']
    prev_market_position = data['strategy']['prev_market_position']

    order_response = kucoin.new_order(symbol=ticker, side=side, type="market", size=size, leverage=1)

    print(order_response)
    if order_response:
        return {
        "code": "success",
        "message": "order executed"
    }
    else:
        print("order failed")

        return{
            "code":"error",
            "message":"order failed"
        }

@app.route('/')
def hello_world():
    return '<p>Hello, World!</p>'