maxme / bitcoin-arbitrage

Bitcoin arbitrage - opportunity detector
MIT License
2.43k stars 859 forks source link

Bitstamp.net has implemented new API keys to access private api functions, old username and passwords will not work anymore #22

Open mrnitrate opened 10 years ago

mrnitrate commented 10 years ago

API KEYS IMPLEMENTED The Bitstamp team is pleased to announce that we have implemented API keys on our site.

To access our new API security feature simply go to "Account" and select "Security" from the side menu. Click "API Access" and select from a variety of Permissions for your API.

You can now select between two different filters which you can use separately or combine them for maximum security; you can either lock your access to a specific IP address or lock bitcoin withdrawals to a specific bitcoin adress.

Please be advised that our old API access will no longer be available after 31st October 2013.

We are convinced that our new security feature will prove to be a welcome addition to the security of our users' accounts.

https://www.bitstamp.net/article/api-key-implementation/ https://www.bitstamp.net/api/

dconroy commented 10 years ago

Does anyone have an updated privatemarket/bitstampusd.py ?

I am trying to get it working but keep getting

{"error": "Missing key, signature and nonce parameters"}

code snippet:

def _send_request(self, url, params={}, extra_headers=None):

    nonce = int(time.time())
    msg = str(nonce) + self.bitstamp_username + self.bitstamp_key
    msg2 = str.encode(msg)

    signature = hmac.new(str.encode(self.bitstamp_secret), msg2, digestmod=hashlib.sha256).hexdigest().upper()

    params['key'] = self.bitstamp_key
    params['signature'] = signature
    params['nonce'] = nonce 
    postdata = urllib.parse.urlencode(params).encode('utf-8')

    headers = {
        'Content-type': 'application/json',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' 
    }
    if extra_headers is not None:
        for k, v in extra_headers.items():
            headers[k] = v
    conn = http.client.HTTPSConnection(url)
    conn.request("POST", "/api/balance/", postdata, headers)
    response = conn.getresponse()
    code = response.getcode()
    if code == 200:
        data = response.read().decode('utf-8')
        print (data)
        return json.loads(data)
    return None

Please help!

ghost commented 10 years ago

If its anything like the mtgox api...Make sure that the order of your params matches the order of the params in the signed signature..

vspinu commented 10 years ago

@dconroy Have you solve the issue? I have exactly the same problem with bitstamp api. Thanks.

bearishtrader commented 10 years ago

I have a private repo with my local files pushed to it, but you will need to add parameters to config.py...Work in progress as well, I got the bitstamp getinfo to work but the buy and sell are untested...

Copyright (C) 2013, Maxime Biais maxime@biais.org

from .market import Market, TradeException import time import base64 import hmac import urllib.request import urllib.parse import urllib.error import hashlib import sys import json import config import requests

class PrivateBitstampUSD(Market): balance_url = "https://www.bitstamp.net/api/balance/" buy_url = "https://www.bitstamp.net/api/buy/" sell_url = "https://www.bitstamp.net/api/sell/"

def __init__(self):
    super().__init__()
    self.proxydict = None
    self.client_id = config.bitstamp_client_id
    self.api_key = config.bitstamp_api_key
    self.api_secret = config.bitstamp_api_secret
    self.currency = "USD"
    self.get_info()        

def _create_nonce(self):
    return int(time.time() * 1000000)

def _send_request(self, url, params={}, extra_headers=None):
    headers = {
        'Content-type': 'application/json',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
    }
    if extra_headers is not None:
        for k, v in extra_headers.items():
            headers[k] = v
    nonce = str(self._create_nonce())
    message = nonce + self.client_id + self.api_key
    if sys.version_info.major == 2:
        signature = hmac.new(self.api_secret, msg=message, digestmod=hashlib.sha256).hexdigest().upper()
    else:
        signature = hmac.new(str.encode(self.api_secret), msg=str.encode(message), digestmod=hashlib.sha256).hexdigest().upper()
    params['key'] = self.api_key
    params['signature'] = signature
    params['nonce'] = nonce
    #postdata = urllib.parse.urlencode(params).encode("utf-8")
    #req = urllib.request.Request(url, postdata, headers=headers)
    #print ("req=", postdata)
    #response = urllib.request.urlopen(req)
    response = requests.post(url, data=params, proxies=self.proxydict)
    #code = response.getcode()
    code = response.status_code
    if code == 200:
        #jsonstr = response.read().decode('utf-8')
        #return json.loads(jsonstr)
        if 'error' in response.json():
            return False, response.json()['error']
        else:
            return response.json()
    return None

def _buy(self, amount, price):
    """Create a buy limit order"""
    params = {"amount": amount, "price": price}
    response = self._send_request(self.buy_url, params)
    if "error" in response:
        raise TradeException(response["error"])

def _sell(self, amount, price):
    """Create a sell limit order"""
    params = {"amount": amount, "price": price}
    response = self._send_request(self.sell_url, params)
    if "error" in response:
        raise TradeException(response["error"])

def get_info(self):
    """Get balance"""
    response = self._send_request(self.balance_url)        
    if response:
        print(json.dumps(response))            
        self.btc_balance = float(response["btc_available"])
        self.usd_balance = float(response["usd_available"])
vspinu commented 10 years ago

Thanks.

I actually was writing it in clojure and had the same error as yours. So I thought it is unrelated to the language. it turned that it was the clojure thing. I finally solved it by posting the "form" request.

The python code at https://github.com/kmadac/bitstamp-python-client also worked for me.