From 408650adf061721b14aba0135139b4b7754b1d34 Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Wed, 25 Oct 2017 19:51:48 +0000 Subject: [PATCH 01/12] modified --- .gitignore | 94 +++++++++++++++++++++ bl3p/__init__.py | 2 + bl3p/api/__init__.py | 2 + bl3p/api/api.py | 191 +++++++++++++++++++++++++++++++++++++++++++ setup.py | 23 ++++++ test/example-py.txt | 100 ++++++++++++++++++++++ test/example.cfg | 3 + test/example.py | 41 ++++++++++ 8 files changed, 456 insertions(+) create mode 100644 .gitignore create mode 100644 bl3p/__init__.py create mode 100644 bl3p/api/__init__.py create mode 100755 bl3p/api/api.py create mode 100644 setup.py create mode 100644 test/example-py.txt create mode 100644 test/example.cfg create mode 100755 test/example.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b99b59e --- /dev/null +++ b/.gitignore @@ -0,0 +1,94 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# IPython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# dotenv +.env + +# virtualenv +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject + +# Project +*~ +*.swp + diff --git a/bl3p/__init__.py b/bl3p/__init__.py new file mode 100644 index 0000000..973a698 --- /dev/null +++ b/bl3p/__init__.py @@ -0,0 +1,2 @@ +from .api import * + diff --git a/bl3p/api/__init__.py b/bl3p/api/__init__.py new file mode 100644 index 0000000..973a698 --- /dev/null +++ b/bl3p/api/__init__.py @@ -0,0 +1,2 @@ +from .api import * + diff --git a/bl3p/api/api.py b/bl3p/api/api.py new file mode 100755 index 0000000..95d6a79 --- /dev/null +++ b/bl3p/api/api.py @@ -0,0 +1,191 @@ +#! /usr/bin/python + +# this code was written by folkert@vanheusden.com +# it has been released under AGPL v3.0 + +# it requires 'pycurl' +# in debian this can be found in the 'python-pycurl' package + +import base64 +import ConfigParser +import hashlib +import hmac +import json +import pycurl +import sys +import urllib + +try: + from io import BytesIO +except ImportError: + from StringIO import StringIO as BytesIO + +from datetime import datetime +from time import mktime + +class Bl3pApi: + url = None + pubKey = None + secKey = None + verbose = False + + def __init__(self, u, pk, sk): + self.url = u + self.pubKey = pk + self.secKey = sk + + def setVerbose(self, v): + self.verbose = v + + def apiCall(self, path, params): + dt = datetime.utcnow() + us = mktime(dt.timetuple()) * 1000 * 1000 + dt.microsecond + nonce = '%d' % us + + # generate the POST data string + post_data = urllib.urlencode(params) + + body = '%s%c%s' % (path, 0x00, post_data) + + privkey_bin = base64.b64decode(self.secKey) + + signature_bin = hmac.new(privkey_bin, body, hashlib.sha512).digest() + + signature = base64.b64encode(signature_bin) + + fullpath = '%s%s' % (self.url, path) + + headers = [ 'Rest-Key: %s' % self.pubKey, 'Rest-Sign: %s' % signature ] + + buffer = BytesIO() + + c = pycurl.Curl() + c.setopt(c.USERAGENT, 'Mozilla/4.0 (compatible; BL3P Python client written by folkert@vanheusden.com; 0.1)'); + c.setopt(c.WRITEFUNCTION, buffer.write) + c.setopt(c.URL, fullpath); + c.setopt(c.POST, 1); + c.setopt(c.POSTFIELDS, post_data); + c.setopt(c.HTTPHEADER, headers); + c.setopt(c.SSLVERSION, 1); + c.setopt(c.SSL_VERIFYPEER, True); + c.setopt(c.SSL_VERIFYHOST, 2); + c.setopt(c.CONNECTTIMEOUT, 5); + c.setopt(c.TIMEOUT, 10); + + if self.verbose: + c.setopt(c.VERBOSE, 1) + else: + c.setopt(c.VERBOSE, 0) + + c.perform() + + response_code = c.getinfo(c.RESPONSE_CODE) + if response_code != 200: + raise Exception('unexpected response code: %d' % response_code) + + c.close() + + return json.loads(buffer.getvalue()) + + # multiply the btc value (e.g 1.3BTC) with this and round-up/down + def getBtcMultiplier(self): + return 100000000 + + def getEurMutiplier(self): + return 100000 + + # Add order to your account. + # @method addOrder + # @param market 'EUR' + # @param order_type 'bid' or 'ask' + # bid: used if you want to buy bitcoins + # ask: if you want to sell bitcoins + # @param order_amount Amount to order *1e8 (so 1 bitcoin is 100000000) + # @param order_price Price of order *1e5 (1 euro is 100000) + # @return Result of the add order call + def addOrder(self, market, order_type, order_amount, order_price): + + params = { + 'type' : order_type, + 'amount_int' : order_amount, + 'price_int' : order_price, + 'fee_currency' : 'BTC' + } + + return self.apiCall('%sEUR/money/order/add' % market, params) + + # Cancel a specific order. + # @method cancelOrder + # @param market 'EUR' + # @param order_id Id of the order + # @return Direct resulf of the '/money/order/cancel' call + def cancelOrder(self, market, order_id): + params = { 'order_id' : order_id } + + return self.apiCall("%sEUR/money/order/cancel" % market, params) + + # Fetch information about an specific order + # @method orderInfo + # @param market 'EUR' + # @param order_id Id of the order + # @return Direct resulf of the '/money/order/result' call + def orderInfo(self, market, order_id): + params = { 'order_id' : order_id } + + return self.apiCall("%sEUR/money/order/result" % market, params) + + # Fetch complete orderbook + # @method fullDepth + # @param market 'EUR' + # @return Direct resulf of the '/money/depth/full' call + def fullDepth(self, market): + return self.apiCall("%sEUR/money/depth/full" % market, { }) + + # Get new deposit address. + # @method getNewDepositAddress + # @param market 'EUR' + # @return new deposit address + def getNewDepositAddress(self, market): + return self.apiCall("%sEUR/money/new_deposit_address" % market, { }) + + # Get the most recent generated deposit address + # @method getLastDepositAddress + # @param market 'EUR' + # @return most recent generated deposit address + def getLastDepositAddress(self, market): + return self.apiCall("%sEUR/money/deposit_address" % market, { }) + + # Get the last 1000 trades that where executed before an specific trade_id + # @method fetchTrades + # @param market 'EUR' + # @param trade_id id of the trade + # @return array of last 1000 executed trades. + def fetchLast1000Trades(self, market, trade_id): + params = { 'trade_id' : trade_id } + + return self.apiCall("%sEUR/money/trades/fetch" % market, params) + + # Get the transaction history + # @method walletHistory + # @param currency currency which currency + # @param n how many to retrieve + # @return array json structure with the transaction history + def walletHistory(self, currency, n): + params = { 'currency' : currency, 'recs_per_page' : n } + + return self.apiCall('GENMKT/money/wallet/history', params) + + # Get all open orders. + # @method getAllActiveOrders + # @param market 'EUR' + # @return array of open orders + def getAllActiveOrders(self, market): + return self.apiCall("%sEUR/money/orders" % market, { }); + + # Get the balances + # @method getBalances + # @return array json structure with the wallet balances + def getBalances(self): + params = { } + return self.apiCall('GENMKT/money/info', params) + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..00fdb67 --- /dev/null +++ b/setup.py @@ -0,0 +1,23 @@ +from setuptools import setup + + +setup( + name='bl3p', + version='20171025.0', + description='BL3P.eu exchange API', + keywords='bl3p exchange api', + url='https://github.com/joosthoeks/bl3p-api', + author='Joost Hoeks', + author_email='joosthoeks@gmail.com', + license='GNU', + packages=[ + 'bl3p', + 'bl3p.api', + ], + install_requires=[ +# 'numpy', +# 'pandas', + ], + zip_safe=False +) + diff --git a/test/example-py.txt b/test/example-py.txt new file mode 100644 index 0000000..1fd2089 --- /dev/null +++ b/test/example-py.txt @@ -0,0 +1,100 @@ +Examples +======== + +invalid public/secret key: +------------------------- +{ + "data": { + "code": "KEY_MISSING", + "message": "Rest-Key missing" + }, + "result": "error" +} + + +invalid market: +-------------- +{ + "data": { + "code": "UNKNOWN_MARKETPLACE", + "message": "Unknown marketplace" + }, + "result": "error" +} + + +price too low: +------------- +{ + "data": { + "code": "PRICE_LESS_THAN_MINIMUM", + "message": "Price '1' less than marketplace minimum '1000'" + }, + "result": "error" +} + + +insufficient funds: +------------------ +{ + "data": { + "code": "INSUFFICIENT_FUNDS", + "message": "Insufficient available funds, available = 0 order value = 10000000" + }, + "result": "error" +} + + +market unavailable: +------------------ +{ + "data": { + "code": "ERR_TEMPORARILY_UNAVAILABLE", + "message": "Error creating address" + }, + "result": "error" +} + + +walletHistory(): +------------- +{ + "data": { + "max_page": 1, + "page": 1, + "records": 1, + "transactions": [ + { + "amount": { + "currency": "BTC", + "display": "0.01000000 BTC", + "display_short": "0.01 BTC", + "value": "0.01000000", + "value_int": "1000000" + }, + "balance": { + "currency": "BTC", + "display": "0.01000000 BTC", + "display_short": "0.01 BTC", + "value": "0.01000000", + "value_int": "1000000" + }, + "date": 1450353480, + "debit_credit": "credit", + "transaction_id": 575126, + "type": "deposit" + } + ] + }, + "result": "success" +} + + +getNewDepositAddress(): +-------------------- +{ + "data": { + "address": "**********************************" + }, + "result": "success" +} diff --git a/test/example.cfg b/test/example.cfg new file mode 100644 index 0000000..3e98153 --- /dev/null +++ b/test/example.cfg @@ -0,0 +1,3 @@ +[bl3p] +public_key= +secret_key= diff --git a/test/example.py b/test/example.py new file mode 100755 index 0000000..f0e6685 --- /dev/null +++ b/test/example.py @@ -0,0 +1,41 @@ +#! /usr/bin/python + + +import bl3p + +import base64 +import ConfigParser +import hashlib +import hmac +import json +import pycurl +import sys +import urllib + +try: + from io import BytesIO +except ImportError: + from StringIO import StringIO as BytesIO + +from datetime import datetime +from time import mktime + + +def d(j): + print json.dumps(j, sort_keys=True, indent=4, separators=(',', ': ')) + +# example: +config = ConfigParser.RawConfigParser() + +if len(sys.argv) == 2: + config.read(sys.argv[1]) +else: + config.read('example.cfg') + +public_key = config.get('bl3p', 'public_key') # ........-....-....-....-............ +secret_key = config.get('bl3p', 'secret_key') # (long string with a-z/A-Z/0-9 and =) + +b = Bl3pApi('https://api.bl3p.eu/1/', public_key, secret_key) + +d(b.walletHistory('BTC', 10)) + From 617799731e60598d8db3f53f2cc31c62ecc65d7d Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Thu, 26 Oct 2017 19:50:16 +0000 Subject: [PATCH 02/12] modified --- bl3p/api/api.py | 332 +++++++++++++++++++++++------------------------ doc_python.md | 21 +++ test/example.cfg | 3 - test/example.py | 34 +---- 4 files changed, 190 insertions(+), 200 deletions(-) create mode 100644 doc_python.md delete mode 100644 test/example.cfg diff --git a/bl3p/api/api.py b/bl3p/api/api.py index 95d6a79..8ac458f 100755 --- a/bl3p/api/api.py +++ b/bl3p/api/api.py @@ -1,19 +1,18 @@ -#! /usr/bin/python +#!/usr/bin/env python # this code was written by folkert@vanheusden.com # it has been released under AGPL v3.0 -# it requires 'pycurl' -# in debian this can be found in the 'python-pycurl' package +# modified by Joost Hoeks (github.com/joosthoeks) + import base64 -import ConfigParser import hashlib import hmac import json import pycurl import sys -import urllib +import urllib.parse try: from io import BytesIO @@ -24,168 +23,163 @@ from time import mktime class Bl3pApi: - url = None - pubKey = None - secKey = None - verbose = False - - def __init__(self, u, pk, sk): - self.url = u - self.pubKey = pk - self.secKey = sk - - def setVerbose(self, v): - self.verbose = v - - def apiCall(self, path, params): - dt = datetime.utcnow() - us = mktime(dt.timetuple()) * 1000 * 1000 + dt.microsecond - nonce = '%d' % us - - # generate the POST data string - post_data = urllib.urlencode(params) - - body = '%s%c%s' % (path, 0x00, post_data) - - privkey_bin = base64.b64decode(self.secKey) - - signature_bin = hmac.new(privkey_bin, body, hashlib.sha512).digest() - - signature = base64.b64encode(signature_bin) - - fullpath = '%s%s' % (self.url, path) - - headers = [ 'Rest-Key: %s' % self.pubKey, 'Rest-Sign: %s' % signature ] - - buffer = BytesIO() - - c = pycurl.Curl() - c.setopt(c.USERAGENT, 'Mozilla/4.0 (compatible; BL3P Python client written by folkert@vanheusden.com; 0.1)'); - c.setopt(c.WRITEFUNCTION, buffer.write) - c.setopt(c.URL, fullpath); - c.setopt(c.POST, 1); - c.setopt(c.POSTFIELDS, post_data); - c.setopt(c.HTTPHEADER, headers); - c.setopt(c.SSLVERSION, 1); - c.setopt(c.SSL_VERIFYPEER, True); - c.setopt(c.SSL_VERIFYHOST, 2); - c.setopt(c.CONNECTTIMEOUT, 5); - c.setopt(c.TIMEOUT, 10); - - if self.verbose: - c.setopt(c.VERBOSE, 1) - else: - c.setopt(c.VERBOSE, 0) - - c.perform() - - response_code = c.getinfo(c.RESPONSE_CODE) - if response_code != 200: - raise Exception('unexpected response code: %d' % response_code) - - c.close() - - return json.loads(buffer.getvalue()) - - # multiply the btc value (e.g 1.3BTC) with this and round-up/down - def getBtcMultiplier(self): - return 100000000 - - def getEurMutiplier(self): - return 100000 - - # Add order to your account. - # @method addOrder - # @param market 'EUR' - # @param order_type 'bid' or 'ask' - # bid: used if you want to buy bitcoins - # ask: if you want to sell bitcoins - # @param order_amount Amount to order *1e8 (so 1 bitcoin is 100000000) - # @param order_price Price of order *1e5 (1 euro is 100000) - # @return Result of the add order call - def addOrder(self, market, order_type, order_amount, order_price): - - params = { - 'type' : order_type, - 'amount_int' : order_amount, - 'price_int' : order_price, - 'fee_currency' : 'BTC' - } - - return self.apiCall('%sEUR/money/order/add' % market, params) - - # Cancel a specific order. - # @method cancelOrder - # @param market 'EUR' - # @param order_id Id of the order - # @return Direct resulf of the '/money/order/cancel' call - def cancelOrder(self, market, order_id): - params = { 'order_id' : order_id } - - return self.apiCall("%sEUR/money/order/cancel" % market, params) - - # Fetch information about an specific order - # @method orderInfo - # @param market 'EUR' - # @param order_id Id of the order - # @return Direct resulf of the '/money/order/result' call - def orderInfo(self, market, order_id): - params = { 'order_id' : order_id } - - return self.apiCall("%sEUR/money/order/result" % market, params) - - # Fetch complete orderbook - # @method fullDepth - # @param market 'EUR' - # @return Direct resulf of the '/money/depth/full' call - def fullDepth(self, market): - return self.apiCall("%sEUR/money/depth/full" % market, { }) - - # Get new deposit address. - # @method getNewDepositAddress - # @param market 'EUR' - # @return new deposit address - def getNewDepositAddress(self, market): - return self.apiCall("%sEUR/money/new_deposit_address" % market, { }) - - # Get the most recent generated deposit address - # @method getLastDepositAddress - # @param market 'EUR' - # @return most recent generated deposit address - def getLastDepositAddress(self, market): - return self.apiCall("%sEUR/money/deposit_address" % market, { }) - - # Get the last 1000 trades that where executed before an specific trade_id - # @method fetchTrades - # @param market 'EUR' - # @param trade_id id of the trade - # @return array of last 1000 executed trades. - def fetchLast1000Trades(self, market, trade_id): - params = { 'trade_id' : trade_id } - - return self.apiCall("%sEUR/money/trades/fetch" % market, params) - - # Get the transaction history - # @method walletHistory - # @param currency currency which currency - # @param n how many to retrieve - # @return array json structure with the transaction history - def walletHistory(self, currency, n): - params = { 'currency' : currency, 'recs_per_page' : n } - - return self.apiCall('GENMKT/money/wallet/history', params) - - # Get all open orders. - # @method getAllActiveOrders - # @param market 'EUR' - # @return array of open orders - def getAllActiveOrders(self, market): - return self.apiCall("%sEUR/money/orders" % market, { }); - - # Get the balances - # @method getBalances - # @return array json structure with the wallet balances - def getBalances(self): - params = { } - return self.apiCall('GENMKT/money/info', params) + url = None + pubKey = None + secKey = None + verbose = False + + def __init__(self, u, pk, sk): + self.url = u + self.pubKey = pk + self.secKey = sk + + def setVerbose(self, v): + self.verbose = v + + def apiCall(self, path, params): + dt = datetime.utcnow() + us = mktime(dt.timetuple()) * 1000 * 1000 + dt.microsecond + nonce = '%d' % us + + # generate the POST data string + post_data = urllib.parse.urlencode(params) + + body = '%s%c%s' % (path, 0x00, post_data) + + privkey_bin = base64.b64decode(self.secKey) + + # TODO + signature_bin = hmac.new(privkey_bin, body, hashlib.sha512).digest() + + signature = base64.b64encode(signature_bin) + + fullpath = '%s%s' % (self.url, path) + + headers = [ 'Rest-Key: %s' % self.pubKey, 'Rest-Sign: %s' % signature ] + + buffer = BytesIO() + + c = pycurl.Curl() + c.setopt(c.USERAGENT, 'Mozilla/4.0 (compatible; BL3P Python client modified by github.com/joosthoeks; 0.1)'); + c.setopt(c.WRITEFUNCTION, buffer.write) + c.setopt(c.URL, fullpath); + c.setopt(c.POST, 1); + c.setopt(c.POSTFIELDS, post_data); + c.setopt(c.HTTPHEADER, headers); + c.setopt(c.SSLVERSION, 1); + c.setopt(c.SSL_VERIFYPEER, True); + c.setopt(c.SSL_VERIFYHOST, 2); + c.setopt(c.CONNECTTIMEOUT, 5); + c.setopt(c.TIMEOUT, 10); + + if self.verbose: + c.setopt(c.VERBOSE, 1) + else: + c.setopt(c.VERBOSE, 0) + + c.perform() + + response_code = c.getinfo(c.RESPONSE_CODE) + if response_code != 200: + raise Exception('unexpected response code: %d' % response_code) + + c.close() + + return json.loads(buffer.getvalue()) + + # multiply the btc value (e.g 1.3BTC) with this and round-up/down + def getBtcMultiplier(self): + return 100000000 + + def getEurMutiplier(self): + return 100000 + + # Add order to your account. + # @method addOrder + # @param market 'EUR' + # @param order_type 'bid' or 'ask' + # bid: used if you want to buy bitcoins + # ask: if you want to sell bitcoins + # @param order_amount Amount to order *1e8 (so 1 bitcoin is 100000000) + # @param order_price Price of order *1e5 (1 euro is 100000) + # @return Result of the add order call + def addOrder(self, market, order_type, order_amount, order_price): + params = { + 'type' : order_type, + 'amount_int' : order_amount, + 'price_int' : order_price, + 'fee_currency' : 'BTC' + } + return self.apiCall('%sEUR/money/order/add' % market, params) + + # Cancel a specific order. + # @method cancelOrder + # @param market 'EUR' + # @param order_id Id of the order + # @return Direct resulf of the '/money/order/cancel' call + def cancelOrder(self, market, order_id): + params = { 'order_id' : order_id } + return self.apiCall("%sEUR/money/order/cancel" % market, params) + + # Fetch information about an specific order + # @method orderInfo + # @param market 'EUR' + # @param order_id Id of the order + # @return Direct resulf of the '/money/order/result' call + def orderInfo(self, market, order_id): + params = { 'order_id' : order_id } + return self.apiCall("%sEUR/money/order/result" % market, params) + + # Fetch complete orderbook + # @method fullDepth + # @param market 'EUR' + # @return Direct resulf of the '/money/depth/full' call + def fullDepth(self, market): + return self.apiCall("%sEUR/money/depth/full" % market, { }) + + # Get new deposit address. + # @method getNewDepositAddress + # @param market 'EUR' + # @return new deposit address + def getNewDepositAddress(self, market): + return self.apiCall("%sEUR/money/new_deposit_address" % market, { }) + + # Get the most recent generated deposit address + # @method getLastDepositAddress + # @param market 'EUR' + # @return most recent generated deposit address + def getLastDepositAddress(self, market): + return self.apiCall("%sEUR/money/deposit_address" % market, { }) + + # Get the last 1000 trades that where executed before an specific trade_id + # @method fetchTrades + # @param market 'EUR' + # @param trade_id id of the trade + # @return array of last 1000 executed trades. + def fetchLast1000Trades(self, market, trade_id): + params = { 'trade_id' : trade_id } + return self.apiCall("%sEUR/money/trades/fetch" % market, params) + + # Get the transaction history + # @method walletHistory + # @param currency currency which currency + # @param n how many to retrieve + # @return array json structure with the transaction history + def walletHistory(self, currency, n): + params = { 'currency' : currency, 'recs_per_page' : n } + return self.apiCall('GENMKT/money/wallet/history', params) + + # Get all open orders. + # @method getAllActiveOrders + # @param market 'EUR' + # @return array of open orders + def getAllActiveOrders(self, market): + return self.apiCall("%sEUR/money/orders" % market, { }); + + # Get the balances + # @method getBalances + # @return array json structure with the wallet balances + def getBalances(self): + params = { } + return self.apiCall('GENMKT/money/info', params) diff --git a/doc_python.md b/doc_python.md new file mode 100644 index 0000000..924c98d --- /dev/null +++ b/doc_python.md @@ -0,0 +1,21 @@ +## Install +``` +$ git clone https://github.com/joosthoeks/bl3p-api.git +$ cd bl3p-api +$ [sudo] pip3 install -e . +``` + +## Update +``` +$ cd bl3p-api +$ git pull +``` + +## Test +``` +$ cd test/ +``` +``` +$ python3 example.py +``` + diff --git a/test/example.cfg b/test/example.cfg deleted file mode 100644 index 3e98153..0000000 --- a/test/example.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[bl3p] -public_key= -secret_key= diff --git a/test/example.py b/test/example.py index f0e6685..93d0ae8 100755 --- a/test/example.py +++ b/test/example.py @@ -1,41 +1,19 @@ -#! /usr/bin/python +#!/usr/bin/env python import bl3p -import base64 -import ConfigParser -import hashlib -import hmac import json -import pycurl -import sys -import urllib - -try: - from io import BytesIO -except ImportError: - from StringIO import StringIO as BytesIO - -from datetime import datetime -from time import mktime def d(j): - print json.dumps(j, sort_keys=True, indent=4, separators=(',', ': ')) + print (json.dumps(j, sort_keys=True, indent=4, separators=(',', ': '))) # example: -config = ConfigParser.RawConfigParser() - -if len(sys.argv) == 2: - config.read(sys.argv[1]) -else: - config.read('example.cfg') - -public_key = config.get('bl3p', 'public_key') # ........-....-....-....-............ -secret_key = config.get('bl3p', 'secret_key') # (long string with a-z/A-Z/0-9 and =) - -b = Bl3pApi('https://api.bl3p.eu/1/', public_key, secret_key) +public_key = '' +secret_key = '' +b = bl3p.Bl3pApi('https://api.bl3p.eu/1/', public_key, secret_key) +b.setVerbose(True) d(b.walletHistory('BTC', 10)) From a0218456dbcfe53d1521543f107554aa0e57b9b9 Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Thu, 26 Oct 2017 19:51:29 +0000 Subject: [PATCH 03/12] modified --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 00fdb67..55967a4 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name='bl3p', - version='20171025.0', + version='20171026.0', description='BL3P.eu exchange API', keywords='bl3p exchange api', url='https://github.com/joosthoeks/bl3p-api', From 0fe25c6d4be7a225bcbafd16d8fa64a244f7e05d Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Sat, 28 Oct 2017 15:28:58 +0000 Subject: [PATCH 04/12] modified --- bl3p/api/api.py | 13 +++++++------ test/example.py | 17 +++++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/bl3p/api/api.py b/bl3p/api/api.py index 8ac458f..1d1da5e 100755 --- a/bl3p/api/api.py +++ b/bl3p/api/api.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # this code was written by folkert@vanheusden.com # it has been released under AGPL v3.0 @@ -14,13 +12,15 @@ import sys import urllib.parse +from datetime import datetime +from time import mktime + + try: from io import BytesIO except ImportError: from StringIO import StringIO as BytesIO -from datetime import datetime -from time import mktime class Bl3pApi: url = None @@ -43,12 +43,13 @@ def apiCall(self, path, params): # generate the POST data string post_data = urllib.parse.urlencode(params) +# post_data = params body = '%s%c%s' % (path, 0x00, post_data) +# body = base64.b64decode('%s%c%s' % (path, 0x00, post_data)) privkey_bin = base64.b64decode(self.secKey) - # TODO signature_bin = hmac.new(privkey_bin, body, hashlib.sha512).digest() signature = base64.b64encode(signature_bin) @@ -85,7 +86,7 @@ def apiCall(self, path, params): c.close() - return json.loads(buffer.getvalue()) + return json.loads(buffer.getvalue().decode('utf-8')) # multiply the btc value (e.g 1.3BTC) with this and round-up/down def getBtcMultiplier(self): diff --git a/test/example.py b/test/example.py index 93d0ae8..d2189c1 100755 --- a/test/example.py +++ b/test/example.py @@ -9,11 +9,16 @@ def d(j): print (json.dumps(j, sort_keys=True, indent=4, separators=(',', ': '))) -# example: -public_key = '' -secret_key = '' +def main(): + # example: + public_key = '' + secret_key = '' -b = bl3p.Bl3pApi('https://api.bl3p.eu/1/', public_key, secret_key) -b.setVerbose(True) -d(b.walletHistory('BTC', 10)) + b = bl3p.Bl3pApi('https://api.bl3p.eu/1/', public_key, secret_key) + b.setVerbose(True) + d(b.walletHistory('BTC', 10)) + + +if __name__ == '__main__': + main() From b8dda0668ad267f700c835df16cfcef8d885b8b9 Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Sat, 28 Oct 2017 20:14:03 +0000 Subject: [PATCH 05/12] modified for python 3 and added install doc for setup.py --- bl3p/api/api.py | 22 ++++++---------------- doc_python.md | 1 + setup.py | 6 +++--- test/example.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 57 insertions(+), 21 deletions(-) diff --git a/bl3p/api/api.py b/bl3p/api/api.py index 1d1da5e..b678237 100755 --- a/bl3p/api/api.py +++ b/bl3p/api/api.py @@ -1,7 +1,7 @@ # this code was written by folkert@vanheusden.com # it has been released under AGPL v3.0 -# modified by Joost Hoeks (github.com/joosthoeks) +# modified for Python 3 by Joost Hoeks (github.com/joosthoeks) import base64 @@ -9,12 +9,8 @@ import hmac import json import pycurl -import sys import urllib.parse -from datetime import datetime -from time import mktime - try: from io import BytesIO @@ -37,22 +33,16 @@ def setVerbose(self, v): self.verbose = v def apiCall(self, path, params): - dt = datetime.utcnow() - us = mktime(dt.timetuple()) * 1000 * 1000 + dt.microsecond - nonce = '%d' % us - - # generate the POST data string post_data = urllib.parse.urlencode(params) -# post_data = params body = '%s%c%s' % (path, 0x00, post_data) -# body = base64.b64decode('%s%c%s' % (path, 0x00, post_data)) + encoded_body = body.encode() privkey_bin = base64.b64decode(self.secKey) - signature_bin = hmac.new(privkey_bin, body, hashlib.sha512).digest() + signature_bin = hmac.new(privkey_bin, encoded_body, hashlib.sha512) - signature = base64.b64encode(signature_bin) + signature = base64.b64encode(signature_bin.digest()).decode() fullpath = '%s%s' % (self.url, path) @@ -61,7 +51,7 @@ def apiCall(self, path, params): buffer = BytesIO() c = pycurl.Curl() - c.setopt(c.USERAGENT, 'Mozilla/4.0 (compatible; BL3P Python client modified by github.com/joosthoeks; 0.1)'); + c.setopt(c.USERAGENT, 'Mozilla/4.0 (compatible; BL3P Python 3 client modified by github.com/joosthoeks; 0.1)'); c.setopt(c.WRITEFUNCTION, buffer.write) c.setopt(c.URL, fullpath); c.setopt(c.POST, 1); @@ -86,7 +76,7 @@ def apiCall(self, path, params): c.close() - return json.loads(buffer.getvalue().decode('utf-8')) + return json.loads(buffer.getvalue().decode()) # multiply the btc value (e.g 1.3BTC) with this and round-up/down def getBtcMultiplier(self): diff --git a/doc_python.md b/doc_python.md index 924c98d..ecc0736 100644 --- a/doc_python.md +++ b/doc_python.md @@ -15,6 +15,7 @@ $ git pull ``` $ cd test/ ``` +modify public_key and secret_key in example.py then run: ``` $ python3 example.py ``` diff --git a/setup.py b/setup.py index 55967a4..aff3356 100644 --- a/setup.py +++ b/setup.py @@ -3,9 +3,9 @@ setup( name='bl3p', - version='20171026.0', - description='BL3P.eu exchange API', - keywords='bl3p exchange api', + version='20171028.0', + description='BL3P.eu Python 3 exchange API', + keywords='bl3p python3 exchange api', url='https://github.com/joosthoeks/bl3p-api', author='Joost Hoeks', author_email='joosthoeks@gmail.com', diff --git a/test/example.py b/test/example.py index d2189c1..b4c3d3e 100755 --- a/test/example.py +++ b/test/example.py @@ -15,8 +15,53 @@ def main(): secret_key = '' b = bl3p.Bl3pApi('https://api.bl3p.eu/1/', public_key, secret_key) - b.setVerbose(True) - d(b.walletHistory('BTC', 10)) +# b.setVerbose(True) + ''' + market = 'BTC' + order_type = 'bid' # 'bid' (=buy BTC) or 'ask' (=sell BTC) + order_amount = 100000000 # 1 BTC = 100000000 + order_price = 100000 # 1 EUR = 100000 + d(b.addOrder(market, order_type, order_amount, order_price)) + ''' + ''' + market = 'BTC' + order_id = 0 + d(b.cancelOrder(market, order_id)) + ''' + ''' + market = 'BTC' + order_id = 0 + d(b.orderInfo(market, order_id)) + ''' + ''' + market = 'BTC' + d(b.fullDepth(market)) + ''' + ''' + market = 'BTC' + d(b.getNewDepositAddress(market)) + ''' + ''' + market = 'BTC' + d(b.getLastDepositAddress(market)) + ''' + ''' + market = 'BTC' + trade_id = 0 + d(b.fetchLast1000Trades(market, trade_id)) + ''' + ''' + currency = 'BTC' + n = 10 + d(b.walletHistory(currency, n)) + ''' + ''' + market = 'BTC' + d(b.getAllActiveOrders(market)) + ''' +# ''' + d(b.getBalances()) +# ''' if __name__ == '__main__': From 6adb0241481c1fcb51607ed6af5a460f300858dc Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Mon, 6 Nov 2017 07:32:54 +0000 Subject: [PATCH 06/12] moved python 3 example and doc added example and doc links --- README.md | 2 ++ doc_python.md => docs/python3/doc_python.md | 2 +- {test => examples/python3}/example-py.txt | 0 {test => examples/python3}/example.py | 0 setup.py | 2 +- 5 files changed, 4 insertions(+), 2 deletions(-) rename doc_python.md => docs/python3/doc_python.md (91%) rename {test => examples/python3}/example-py.txt (100%) rename {test => examples/python3}/example.py (100%) diff --git a/README.md b/README.md index 67b3d02..cab91dc 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,5 @@ You can find each client reference implementation in: * [NodeJs](examples/nodejs/) * [Java](examples/java/) * [Go](examples/go/) +* [Python 2](examples/python/) +* [Python 3](examples/python3/) [doc](docs/python3/) diff --git a/doc_python.md b/docs/python3/doc_python.md similarity index 91% rename from doc_python.md rename to docs/python3/doc_python.md index ecc0736..2302fff 100644 --- a/doc_python.md +++ b/docs/python3/doc_python.md @@ -13,7 +13,7 @@ $ git pull ## Test ``` -$ cd test/ +$ cd examples/python3/ ``` modify public_key and secret_key in example.py then run: ``` diff --git a/test/example-py.txt b/examples/python3/example-py.txt similarity index 100% rename from test/example-py.txt rename to examples/python3/example-py.txt diff --git a/test/example.py b/examples/python3/example.py similarity index 100% rename from test/example.py rename to examples/python3/example.py diff --git a/setup.py b/setup.py index aff3356..7a1f333 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name='bl3p', - version='20171028.0', + version='20171106.0', description='BL3P.eu Python 3 exchange API', keywords='bl3p python3 exchange api', url='https://github.com/joosthoeks/bl3p-api', From 3b5ee51ab73cd8372e80b29d0bd7011de1a8d099 Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Mon, 6 Nov 2017 20:12:34 +0000 Subject: [PATCH 07/12] added btc and eur multiplier to example and typo fix --- bl3p/api/api.py | 2 +- examples/python3/example.py | 7 +++++-- setup.py | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/bl3p/api/api.py b/bl3p/api/api.py index b678237..d590665 100755 --- a/bl3p/api/api.py +++ b/bl3p/api/api.py @@ -82,7 +82,7 @@ def apiCall(self, path, params): def getBtcMultiplier(self): return 100000000 - def getEurMutiplier(self): + def getEurMultiplier(self): return 100000 # Add order to your account. diff --git a/examples/python3/example.py b/examples/python3/example.py index b4c3d3e..c60aa17 100755 --- a/examples/python3/example.py +++ b/examples/python3/example.py @@ -17,10 +17,13 @@ def main(): b = bl3p.Bl3pApi('https://api.bl3p.eu/1/', public_key, secret_key) # b.setVerbose(True) ''' + koers_in_eur = 5000 + kapitaal_in_eur = 10000 + btc = round(kapitaal_in_eur / koers_in_eur, 8) # round to 8 decimals market = 'BTC' order_type = 'bid' # 'bid' (=buy BTC) or 'ask' (=sell BTC) - order_amount = 100000000 # 1 BTC = 100000000 - order_price = 100000 # 1 EUR = 100000 + order_amount = int(btc * b.getBtcMultiplier()) # 1 BTC = 100000000 + order_price = int(koers_in_eur * b.getEurMultiplier()) # 1 EUR = 100000 d(b.addOrder(market, order_type, order_amount, order_price)) ''' ''' diff --git a/setup.py b/setup.py index 7a1f333..1b0f55f 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name='bl3p', - version='20171106.0', + version='20171106.1', description='BL3P.eu Python 3 exchange API', keywords='bl3p python3 exchange api', url='https://github.com/joosthoeks/bl3p-api', From 28b5787bb1f34f360495232935ab0e467720d68b Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Fri, 12 Jan 2018 18:41:27 +0000 Subject: [PATCH 08/12] deleted unused files --- README.md | 31 +- bl3p/api/api.py | 5 +- docs/authenticated_api/http.md | 986 --------------------------- docs/base.md | 125 ---- docs/public_api/http.md | 202 ------ docs/public_api/websocket.md | 124 ---- docs/python3/doc_python.md | 22 - examples/go/bl3p/bl3p.go | 278 -------- examples/go/callModels/callModels.go | 107 --- examples/go/example/example.go | 39 -- examples/java/ComingSoon.md | 0 examples/nodejs/example.md | 933 ------------------------- examples/php/example.php | 280 -------- examples/python/example-py.txt | 100 --- examples/python/example.cfg | 3 - examples/python/example.py | 208 ------ setup.py | 2 +- 17 files changed, 23 insertions(+), 3422 deletions(-) delete mode 100644 docs/authenticated_api/http.md delete mode 100644 docs/base.md delete mode 100644 docs/public_api/http.md delete mode 100644 docs/public_api/websocket.md delete mode 100644 docs/python3/doc_python.md delete mode 100644 examples/go/bl3p/bl3p.go delete mode 100644 examples/go/callModels/callModels.go delete mode 100644 examples/go/example/example.go delete mode 100644 examples/java/ComingSoon.md delete mode 100644 examples/nodejs/example.md delete mode 100644 examples/php/example.php delete mode 100644 examples/python/example-py.txt delete mode 100644 examples/python/example.cfg delete mode 100755 examples/python/example.py diff --git a/README.md b/README.md index cab91dc..2ecb937 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,25 @@ -BL3P exchange official documentation +Unofficial Python 3 Bl3p client exchange api === -Please access [docs](docs/) for the latest official documentation. +## Install +``` +$ git clone https://github.com/joosthoeks/bl3p-api.git +$ cd bl3p-api +$ [sudo] pip3 install -e . +``` -API reference implementations -=== +## Update +``` +$ cd bl3p-api +$ git pull +``` -You can find each client reference implementation in: +## Test +``` +$ cd examples/python3/ +``` +modify public_key and secret_key in example.py then run: +``` +$ python3 example.py +``` -* [PHP](examples/php/) -* [NodeJs](examples/nodejs/) -* [Java](examples/java/) -* [Go](examples/go/) -* [Python 2](examples/python/) -* [Python 3](examples/python3/) [doc](docs/python3/) diff --git a/bl3p/api/api.py b/bl3p/api/api.py index d590665..505bb77 100755 --- a/bl3p/api/api.py +++ b/bl3p/api/api.py @@ -1,5 +1,4 @@ -# this code was written by folkert@vanheusden.com -# it has been released under AGPL v3.0 +# Unofficial Python 3 Bl3p client exchange api # modified for Python 3 by Joost Hoeks (github.com/joosthoeks) @@ -51,7 +50,7 @@ def apiCall(self, path, params): buffer = BytesIO() c = pycurl.Curl() - c.setopt(c.USERAGENT, 'Mozilla/4.0 (compatible; BL3P Python 3 client modified by github.com/joosthoeks; 0.1)'); + c.setopt(c.USERAGENT, 'Mozilla/4.0 (compatible; Unofficial Python 3 Bl3p client exchange api; 0.1)'); c.setopt(c.WRITEFUNCTION, buffer.write) c.setopt(c.URL, fullpath); c.setopt(c.POST, 1); diff --git a/docs/authenticated_api/http.md b/docs/authenticated_api/http.md deleted file mode 100644 index 7974552..0000000 --- a/docs/authenticated_api/http.md +++ /dev/null @@ -1,986 +0,0 @@ -# Authenticated API | HTTP Calls - -## Table of contents - -1. Introduction -2. Basic functions - 1. Create an order - 2. Cancel an order - 3. Get a specific order - 4. Get the whole orderbook - -3. Account info & functions - 1. Get the transaction history - 2. Create a new deposit address - 3. Get the last deposit address - 4. Create a withdrawal - 5. Get account info & balance - 6. Get active orders - 7. Get order history - 8. Fetch all trades on BL3P - -4. Appendix - Error code - ---- - -## 1 - Introduction - -This document describes the usage of the private HTTP API of BL3P. -In the file on directory above you can find the base.md file. -The base.md document describes all basic details that you need to know to use the BL3P API. -If you would like to know how to make a connection to the BL3P API, please check the examples that are available one directory above. - -## 2 - Basic functions - -**Definition of the path variable order:** -```text -////[/] -``` -___ -**Description of the path variables:** - -Version of API (is currently: 1) -```text - = 1 -``` -___ -Market that the call will be applied to. - -Note: GENMKT is used for market independent calls -```text - = BTCEUR, LTCEUR, GENMKT -``` -___ -Namespace of call. Usualy: "money" -```text - = $namespace -``` -___ -Name of call (for example: “order”) -```text - = $callname -``` -___ -Name of subcall, (for example: “add”) -```text - = $subcallname -``` -___ - -The response is a succes or an error. In case of result: succes, the requested data will be returned. -In case of an error, an error code will be retuned. The possible error codes are listed in the appendix. - -## 2.1 - Create an order - -### Call - -```text -/money/order/add -``` - -### Request -`type` string -``` -'bid', 'ask' -``` -___ -`amount_int` int -``` -Amount BTC, amount LTC (*1e8) -``` -The field described above is optional -___ -`price_int` int -``` -Limit price in EUR (*1e5) -``` -The field described above is optional -___ -`amount_funds_int` int -``` -Maximal EUR amount to spend (*1e5) -``` -The field described above is optional -___ -`fee_currency` string -``` -Currency the fee is accounted in. Can be: 'EUR' or 'BTC' -``` ->___ - -### Response -`order_id` int -``` -The id of the order. -``` - -## 2.2 - Cancel an order - -### Call - -```text -/money/order/cancel -``` - -### Request -`order_id` int -``` -The id of the order that you wish to cancel. -``` - -### Response -``` -For this call there is no specific result returned other then -the result of the call which contains: 'success' or 'failed' and a optional error array. -``` - - -## 2.3 - Get a specific order -### Call -```text -/money/order/result -``` - -### Request -`order_id` int -``` -The id of the order that you wish to retrieve. -``` - -### Response -`order_id` int -``` -Id of the order. -``` -___ -`label` string -``` -API-key label -``` -___ -`currency` string -``` -Currency of the order. (Is now by default 'EUR') -``` -___ -`item` string -``` -The item that will be traded for `currency`. (Can be: 'BTC') -``` -___ -`type` string -``` -Type of order. (Can be: 'bid', 'ask') -``` -___ -`amount` amountObj -``` -Total order amount of BTC or LTC. -``` -The field described above is optional -___ -`price` amountObj -``` -Order limit price. -``` -The field described above is optional -___ -`status` string -``` -Status of the order. (Can be: ’pending’, ‘open’, ‘closed’, ‘cancelled’, ’placed’) -``` -___ -`date` timestamp -``` -The time the order got added. -``` -___ -`total_amount` amountObj -``` -Total amount of the trades that got executed. (Can be: BTC or LTC). -``` -___ -`total_spent` amountObj -``` -Total amount in EUR of the trades that got executed. -``` -___ -`total_fee` amountObj -``` -Total fee incurred in BTC or LTC. -``` -___ -`avg_cost` amountObj -``` -Average cost of executed trades. -``` -The field described above is optional -___ -`trades` array -``` -Array of trades executed for the regarding order. -``` -**Each array item of 'trade' will contain:** -`amount` amountObj -``` -BTC or LTC amount. -``` -___ -`currency` string -``` -Currency of the regarding trade. -``` -___ -`date` timestamp -``` -The time of the trade execution. -``` -___ -`item` string -``` -'BTC' -``` -___ -`price` amountObj -``` -Price of the executed trade in EUR. -``` -___ -`trade_id` int -``` -Id of trade. -``` - ->___ - -## 2.4 - Get the whole orderbook - -### Call - -```text -/money/depth/full -``` - -### Request - -``` -There are no specific parameters required for this call. -``` - -### Response -`asks` array -``` -Array of asks that are in the orderbook. -``` -**Each array item of 'asks' will contain:** - -`amount_int` int -``` -Amount BTC, amount LTC (*1e8) -``` -___ -`price_int` int -``` -Limit price in EUR (*1e5) -``` -___ -`count` int -``` -Count of orders at this price. -``` - ->___ - -`bids` array -``` -Array of bids that are in the orderbook. -``` -**Each array item of 'bids' will contain:** - -`amount_int` int -``` -Amount BTC, amount LTC (*1e8) -``` -___ -`price_int` int -``` -Limit price in EUR (*1e5) -``` -___ -`count` int -``` -Count of orders at this price. -``` - ->___ - -## 3 - Account info & functions - -## 3.1 - Get your transaction history - -### Call - -```text -GENMKT/money/wallet/history -``` - -### Request - -`currency` string -``` -Currency of the wallet. (Can be: 'BTC', 'EUR') -``` -___ -`page` int -``` -Page number. (1 = most recent transactions) -``` -The field described above is optional, default is 1 -___ -`date_from` timestamp -``` -Filter the result by a Unix-timestamp. Transactions before this date will not be returned. -``` -The field described above is optional, default is no filter -___ -`date_to` timestamp -``` -Filter the result by a Unix-timestamp. Transactions after this date will not be returned. -``` -The field described above is optional, default is no filter -___ -`type` string -``` -Filter the result by type. (Can be: ‘trade’, ‘fee’, ‘deposit’, ‘withdraw’) -``` -The field described above is optional, default is no filter -___ -`recs_per_page` int -``` -Number of records per page. -``` -The field described above is optional, default is 50 ->___ - -### Response - -`page` int -``` -Current page number. -``` -___ -`records` int -``` -Count of records in the result set. -``` -___ -`max_page` int -``` -Number of last page. -``` -___ -`transactions` array -``` -Array of transactions. -``` -**Each array item of 'transactions' will contain:** -`transaction_id` int -``` -Id of the transaction. -``` -`amount` amountObj -``` -BTC or LTC amount. -``` -___ -`date` timestamp -``` -Time when the regarding transaction took place. -``` -___ -`debit_credit` string -``` -Type of booking. (Can be: 'debit' or 'credit') -``` -___ -`price` amountObj -``` -Price of the executed trade. -``` -The field described above is for type 'trade' only and will be omitted if recs_per_page > 1000 -___ -`order_id` int -``` -Id of the order. -``` -The field described above is for type 'trade' only and will be omitted if recs_per_page > 1000 -___ -`type` string -``` -Type of transaction (Can be: 'trade’, ‘fee’, ‘deposit’, ‘withdraw’) -``` -___ -`balance` amountObj -``` -Balance of the user his account (for the regarding currency) after the transaction. -``` -___ -`trade_id` int -``` -Id of the trade. -``` -The field described above is for type 'trade' only and will be omitted if recs_per_page > 1000 -___ -`contra_amount` amountObj -``` -Contra amount of the trade. -``` -The field described above is for type 'trade' only and will be omitted if recs_per_page > 1000 -___ -`fee` amountObj -``` -Fee incurred by the regarding trade -``` -The field described above is for type 'trade' only and will be omitted if recs_per_page > 1000 - - ->___ - -## 3.2 - Create a new deposit address - -### Call - -```text -GENMKT/money/new_deposit_address -``` - -### Request - -`currency` string -``` -Currency (Can be: 'BTC') -``` - -### Response - -`address` string -``` -Deposit address for the requested currency -``` - -## 3.3 - Get the last deposit address - -### Call - -```text -GENMKT/money/deposit_address -``` - -### Request - -`currency` string -``` -currency (Can be: 'BTC') -``` - -### Response - -`address` string -``` -Deposit address for the requested currency -``` - -## 3.4 - Create a withdrawal - -### Call - -```text -GENMKT/money/withdraw -``` - -### Request - -`currency` string -``` -Currency (Can be: 'BTC','EUR') -``` -___ -`account_id` string -``` -IBAN account-id (that is available within the regarding BL3P account) -``` -`account_name` string -``` -IBAN account-name (should match your account verification) -``` - -**or** - -`address` string -``` -The address to withdraw to -``` -`extra_fee` int (use 1 for extra fee) -``` -This will send the withdrawal as priority, extra fee will be charged (see bl3p.eu) -``` -The field described above is optional, default is no extra fee -___ - -`amount_int` int -``` -Satoshis or 0,00001 EUR -``` - -### Response - -`id` int -``` -Id of the withdrawal -``` - -## 3.5 - Get account info & balance -### Call - -```text -GENMKT/money/info -``` - -### Request - -``` -There are no specific parameters required for this call. -``` - -### Response - -`user_id` int -``` -Id of the user. -``` -___ -`trade_fee` float -``` -Percentage fee for the user -``` -___ -`wallets` array -``` -Array of wallets. -``` -**Each array item of 'wallets' will contain:** - -`balance` amountObj -``` -Balance in this wallet -``` -___ -`available` amountObj -``` -Available in this wallet. -``` - ->___ - -## 3.6 Get active orders -### Call -```text -/money/orders -``` - -### Request - -``` -There are no specific parameters required for this call. -``` - -### Response - -`orders` array -``` -Array of active orders. -``` -**Each array item of 'orders' will contain:** - -`order_id` int -``` -Id of the order. -``` -___ -`label` string -``` -API-key label -``` -___ -`currency` string -``` -Currency of the order. (Is now by default 'EUR') -``` -___ -`item` string -``` -The item that will be traded for `currency`. (Can be: 'BTC') -``` -___ -`type` string -``` -Type of order. (Can be: 'bid', 'ask') -``` -___ -`status` string -``` -Status of the order. (Can be: 'pending’, ‘open’, ‘closed’, ‘cancelled’, ’placed’) -``` -___ -`date` timestamp -``` -The time the order got added. -``` -___ -`amount` amountObj -``` -Total order amount of BTC or LTC. -``` -The field described above is optional -___ -`amount_funds_executed` amountObj -``` -Amount in funds that is executed. -``` -___ -`amount_executed` amountObj -``` -Amount that is executed. -``` -___ -`price` amountObj -``` -Order limit price. -``` -The field described above is optional -___ -`amount_funds` amountObj -``` -Maximal EUR amount to spend (*1e5) -``` -The field described above is optional - ->___ - -## 3.7 Get order history -### Call -```text -/money/orders/history -``` - -### Request - -`page` int -``` -Page number. (1 = most recent transactions) -``` -The field described above is optional, default is 1 -___ -`date_from` timestamp -``` -Filter the result by a Unix-timestamp. Transactions before this date will not be returned. -``` -The field described above is optional, default is no filter -___ -`date_to` timestamp -``` -Filter the result by a Unix-timestamp. Transactions after this date will not be returned. -``` -The field described above is optional, default is no filter -___ -`recs_per_page` int -``` -Number of records per page. -``` -The field described above is optional, default is 100 - ->___ - -### Response - -`page` int -``` -Current page number. -``` -___ - -`records` int -``` -Count of records in the result set. -``` -___ -`max_page` int -``` -Number of last page. -``` -`orders` array -``` -Array of active orders. -``` -**Each array item of 'orders' will contain:** - -`order_id` int -``` -Id of the order. -``` -___ - -`label` string -``` -API-key label -``` -___ -`currency` string -``` -Currency of the order. (Is now by default 'EUR') -``` -___ -`item` string -``` -The item that will be traded for `currency`. (Can be: 'BTC') -``` -___ -`type` string -``` -Type of order. (Can be: 'bid', 'ask') -``` -___ -`status` string -``` -Status of the order. (Can be: 'pending’, ‘open’, ‘closed’, ‘cancelled’, ’placed’) -``` -___ -`date` timestamp -``` -The time the order got added. -``` -___ -`date_closed` timestamp -``` -The time the order got closed. -``` -___ -`amount` amountObj -``` -Total order amount of BTC or LTC. -``` -The field described above is optional -___ -`amount_funds_executed` amountObj -``` -Amount in funds that is executed. -``` -___ -`amount_executed` amountObj -``` -Amount that is executed. -``` -___ -`price` amountObj -``` -Order limit price. -``` -The field described above is optional -___ -`amount_funds` amountObj -``` -Maximal EUR amount to spend (*1e5) -``` -The field described above is optional - ->___ - -## 3.8 - Fetch all trades on BL3P - -### Call - -```text -/money/trades/fetch -``` - -### Request - -`trade_id` int -``` -Id of the trade after which you want to fetch the (next) 1000 trades -``` -The field described above is optional, if this field isn't specified, this call will return the last 1000 trades. - ->___ - -### Response - -`trades` array -``` -Array of trades. -``` -**Each array item of 'trades' will contain:** -`trade_id` int -``` -Id of the trade. -``` -___ -`date` timestamp (in milliseconds) -``` -The time of the trade execution. -``` -___ -`amount_int` int -``` -Amount traded. (*1e8) -``` -___ -`price_int` int -``` -Price of the traded item in EUR. (*1e5) -``` - ->___ - -## 4 - Appendix - Error codes - -The API can respond to invalid calls with the following error messages: - -`AMOUNT_FUNDS_LESS_THAN_MINIMUM` -``` -Order amount (amount_funds) smaller than the minimum. -``` -___ - -`AMOUNT_LESS_THAN_MINIMUM` -``` -Order amount is smaller than the minimum -``` -___ - -`INSUFFICIENT_FUNDS` -``` -Not enough money on account for this order. -``` -___ - -`INVALID_AMOUNT` -``` -Invalid field 'amount_int'. -``` -___ - -`INVALID_AMOUNT_FUNDS` -``` -Invalid field 'amount_funds_int'. -``` -___ - -`INVALID_FEE_CURRENCY` -``` -Invalid field 'fee_currency'. -``` -___ - -`INVALID_LIMIT_ORDER` -``` -Limitorders can't have both an 'amount' and an 'amount_funds'. -``` -___ - -`INVALID_PRICE` -``` -Invalid field 'price_int'. -``` -___ - -`INVALID_TYPE` -``` -Invalid field type (‘bid’ or ‘ask’). -``` -___ - -`KEY_MISSING` -``` -The Rest-Key header misses. -``` -___ - -`LIMIT_REACHED` -``` -User has done to much calls. -``` -___ - -`MARKETPLACE_INACCESSIBLE` -``` -Market (temporarily) closed. -``` -___ - -`MARKETPLACE_NOT_ACCEPTING_ORDERS` -``` -Market does (temporarily) not accepts orders. -``` -___ - -`MISSING_AMOUNT` -``` -The field 'amount' or 'amout_funds' is missing with this order. -``` -___ - -`MISSING_FIELD` -``` -A required field at this call is missing. -``` -___ - -`NOT_AUTHENTICATED` -``` -Signature-key-combination is invalid. -``` -___ - -`SIGN_MISSING` -``` -The Rest-Sign header misses. -``` -___ - -`UNKNOWN_ACCOUNT` -``` -User has no account for given currency (SystemServer) -``` -___ - -`UNKNOWN_CURRENCY` -``` -The requested currency doesn't exist. -``` -___ - -`UNKNOWN_ERROR` -``` -An unknown server error occured. -``` -___ - -`UNKNOWN_MARKETPLACE` -``` -The requested market doesn't exist. -``` -___ - -`UNKNOWN_ORDER` -``` -The order to cancel or fetch doesn't exist -``` -___ - - -`UNKNOWN_PATH` -``` -Requested path and/or call doesn't exist. -``` -___ diff --git a/docs/base.md b/docs/base.md deleted file mode 100644 index b0b0acd..0000000 --- a/docs/base.md +++ /dev/null @@ -1,125 +0,0 @@ -# Base - -## Table of contents - -1. Introduction -2. General information - - 1. Public API & Authenticated API - 2. Base urls - 3. Authentication and authorization - 4. Capacity - 5. AmountObj type - ---- - -## 1 - General information - -### 2.1 - Public API & Authenticated API - -There are two different API types. -A Public API and an Authenticated API. -The Public API will supply basic public information like all trades and the orderbook. -The Authenticated API differs from the Public API since you can control your BL3P account and retrieve non-public information about your BL3P account. - -### 2.2 - Base urls - -The base urls for the two different APIs are as following: - -###Authenticated API - -**HTTP** -``` -https://api.bl3p.eu -``` -___ -###Public API - -**Websocket** -``` -wss://api.bl3p.eu/ -``` -**HTTP** -``` -https://api.bl3p.eu -``` -___ - -### 2.3 Authentication and authorization - -On the [security page](https://www.bl3p.eu/security) within BL3P you can add one or more API keys. -Use this API key to control your BL3P account. -For the Public API this API key is not required. - -The Authenticated API requires two variables to be passed within the HEADER. - -`Rest-Key` - -This is contains the raw API key. -___ -`Rest-Sign` - -You also need to sign the Rest-Key. This variable needs to contain the following: -``` -base64 encode of ( - HMAC_SHA512 of ( - $path_of_request + null terminator + $post_data_string - ) with the key set to the base64 decode of the private apikey) -) -``` -Note: That the HMAC_SHA512 needs to output raw binary data, using hexits (hexadecimal digits) will return an error. - -### 2.4 - Capacity - -You cannot call the API unlimited times in a certain timeframe. -The current amount of calls per 10 minutes is set to 600. - -### 2.5 - AmountObj type - -You will notice that sometimes we don't define an field type as '_string_', '_array_' or '_int_', but as '_amountObj_'. -This is an type of field which will always maintain the following format: - -`value_int` string - -The amount in 1e5 (for fiat) or 1e8 (for virtual currency). - -**Example:** -``` -100000 -``` -___ -`display_short` string - -The common notation of this amount. - -**Example:** -``` -1.00 EUR -``` -___ -`display` string - -The amount in 1e5 (for fiat) or 1e8 (for virtual currency), with decimal notation and the regarding currency. - -**Example:** -``` -1.00000 EUR -``` -___ -`currency` string - -The currency of the amountObj. - -**Example:** -``` -'EUR' -``` -___ -`value` string - -The amount in 1e5 (for fiat) or 1e8 (for virtual currency), with decimal notation. - -**Example:** -``` -1.00000 -``` diff --git a/docs/public_api/http.md b/docs/public_api/http.md deleted file mode 100644 index c38dd58..0000000 --- a/docs/public_api/http.md +++ /dev/null @@ -1,202 +0,0 @@ -# Public API | HTTP Calls - -## Table of contents - -1. Introduction -2. Basic functions - - 1. Ticker - 2. Orderbook - 3. Last 1000 trades - -## 1 - Introduction - -This document describes the usage of the public HTTP API of BL3P. -In the file on directory above you can find the base.md file. -The base.md document describes all basic details that you need to know to use the BL3P API. -If you would like to know how to make a connection to the BL3P API, please check the examples that are available one directory above. - -## 2. Basic functions - -**Definition of the path variable:** -``` -/// -``` -___ -**Description of the path variable:** - -___ -Market that the call will be applied to. - -``` - = ‘BTCEUR’ -``` - -Version of API (is currently: 1) -```text - = 1 -``` - -___ -Name of call (for example: “trades”) -```text - = $callname -``` -___ - -## 2.1 - Ticker - -### Call - -```text -ticker -``` - -### Request - -``` -There are no specific parameters required for this call. -``` - -### Response - -`currency` string -``` -The currency the returned values apply to. -``` -___ -`last` float -``` -Price of the last trade. -``` -___ -`bid` float -``` -Price of the current bid. -``` -___ -`ask` float -``` -Price of the current ask. -``` -___ -`volume` array -``` -Array of trades executed for the regarding order. -``` -**The 'volume' array will contain:** ->`24h` float -``` -Volume of the last 24 hours. -``` -___ -`30d` float -``` -Volume of the last 30 days. -``` - ->___ - -## 2.2 - Orderbook - -### Call - -```text -orderbook -``` - -### Request - -``` -There are no specific parameters required for this call. -``` - -### Response ->`asks` array -``` -Array of asks that are in the orderbook. -``` -**Each array item of 'asks' will contain:** - ->`amount_int` int -``` -Amount BTC (*1e8) -``` -___ -`price_int` int -``` -Limit price in EUR (*1e5) -``` -___ -`count` int -``` -Count of orders at this price. -``` - ->___ - ->`bids` array -``` -Array of bids that are in the orderbook. -``` -**Each array item of 'bids' will contain:** - ->`amount_int` int -``` -Amount BTC (*1e8) -``` -___ -`price_int` int -``` -Limit price in EUR (*1e5) -``` -___ -`count` int -``` -Count of orders at this price. -``` - ->___ - -## 2.3 - Last 1000 trades - -### Call - -```text -trades -``` - -### Request - -``` -There are no specific parameters required for this call. -``` - -### Response - ->`trades` array -``` -Array of trades. -``` -**Each array item of 'trades' will contain:** ->`trade_id` int -``` -Id of the trade. -``` -___ -`date` timestamp (in milliseconds) -``` -The time of the trade execution. -``` -___ -`amount_int` int -``` -Amount traded. (*1e8) -``` -___ -`price_int` int -``` -Price of the traded item in EUR. (*1e5) -``` - ->___ diff --git a/docs/public_api/websocket.md b/docs/public_api/websocket.md deleted file mode 100644 index 27fcfeb..0000000 --- a/docs/public_api/websocket.md +++ /dev/null @@ -1,124 +0,0 @@ -# Public API | Websocket Calls - -## Table of contents - -1. Introduction -2. Basic functions - 1. Trades - 2. Orderbook - -## 1 - Introduction - -This document describes the usage of the public websocket API of BL3P. -In the file on directory above you can find the base.md file. -The base.md document describes all basic details that you need to know to use the BL3P API. -If you would like to know how to make a connection to the BL3P API, please check the examples that are available one directory above. - -## 2. Basic functions - -**Definition of the path variables:** -``` -/// -``` -___ -**Description of the path variables:** - -Version of API (is currently: 1) -``` - = 1 -``` -___ -Market that the call will be applied to. - -``` - = ‘BTCEUR’, 'LTCEUR' -``` -___ -Channel to subscribe to. -``` - = $channel_name -``` -___ - -## 2.1 - Trades - -###Channel ->`trades` string -``` -The 'trades' ticker streams trade messages to subscribers. ->``` - -###Message - ->`amount_int` int -``` -Traded BTC Amount or traded LTC amount (*1e8) -``` -___ -`price_int` int -``` -Trade price in EUR (*1e5) -``` -___ -`date` timestamp -``` -The time of the trade execution. -``` ->___ - - -## 2.2 - Orderbook - -###Channel ->`orderbook` string -``` -The 'orderbook' ticker streams the orderbook to subscribers, every time a change occurs. ->``` - -###Message - ->`asks` array -``` -Array of asks that are in the orderbook. -``` -**Each array item of 'asks' will contain:** - ->>`amount_int` int -``` -BTC amount or LTC amount (*1e8) -``` -___ -`price_int` int -``` -Limit price in EUR (*1e5) -``` -___ -`count` int -``` -Count of orders at this price. -``` ->> ->___ - ->`bids` array -``` -Array of bids that are in the orderbook. -``` -**Each array item of 'bids' will contain:** - ->>`amount_int` int -``` -BTC amount or LTC amount (*1e8) -``` -___ -`price_int` int -``` -Limit price in EUR (*1e5) -``` -___ -`count` int -``` -Count of orders at this price. -``` ->> ->___ \ No newline at end of file diff --git a/docs/python3/doc_python.md b/docs/python3/doc_python.md deleted file mode 100644 index 2302fff..0000000 --- a/docs/python3/doc_python.md +++ /dev/null @@ -1,22 +0,0 @@ -## Install -``` -$ git clone https://github.com/joosthoeks/bl3p-api.git -$ cd bl3p-api -$ [sudo] pip3 install -e . -``` - -## Update -``` -$ cd bl3p-api -$ git pull -``` - -## Test -``` -$ cd examples/python3/ -``` -modify public_key and secret_key in example.py then run: -``` -$ python3 example.py -``` - diff --git a/examples/go/bl3p/bl3p.go b/examples/go/bl3p/bl3p.go deleted file mode 100644 index e3cb20a..0000000 --- a/examples/go/bl3p/bl3p.go +++ /dev/null @@ -1,278 +0,0 @@ -package bl3p - -import ( - "bytes" - "crypto/hmac" - "crypto/sha512" - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "strconv" - - "github.com/BitonicNL/bl3p-api/examples/go/callModels" -) - -//Bl3p struct -type Bl3p struct { - url string - pubkey string - privkey string - version string -} - -//Error struct -type Error struct { - Result string `json:"result"` - Data struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"data"` -} - -//NewBl3p | Returns new Bl3p struct -func NewBl3p(apiURL string, apiPubkey string, apiPrivkey string, apiVersion string) *Bl3p { - a := Bl3p{apiURL, apiPubkey, apiPrivkey, apiVersion} - return &a -} - -//Error | Extends default Error struct -func (e Error) Error() string { - return fmt.Sprintf("Message: %v: Code: %v", e.Data.Message, e.Data.Code) -} - -//requester | Creates the request to Bl3p API -func (b Bl3p) requester(call string, params map[string]string) (callModels.Bl3pResult, error) { - - //create empty bl3presult - result := callModels.Bl3pResult{} - - //build url - u, err := url.ParseRequestURI(b.url) - - //error handling - if err != nil { - return result, err - } - - u.Path = "/" + b.version + "/" + call - apiCallURL := fmt.Sprintf("%v", u) - - //prepare params - data := url.Values{} - - //convert params into querystring - if len(params) > 0 { - for k, p := range params { - data.Set(k, p) - } - } - - //create request - client := &http.Client{} - r, err := http.NewRequest("GET", apiCallURL, bytes.NewBufferString(data.Encode())) - - //error handling - if err != nil { - return result, err - } - - //request body - body := []byte(call + string(0) + data.Encode()) - - //decode privkey - base64Decode := make([]byte, base64.StdEncoding.DecodedLen(len(b.privkey))) - l, err := base64.StdEncoding.Decode(base64Decode, []byte(b.privkey)) - - //error handling - if err != nil { - return result, err - } - - decodedPrivkey := []byte(base64Decode[:l]) - - //sign - h := hmac.New(sha512.New, decodedPrivkey) - h.Write(body) - sign := h.Sum(nil) - - //encode signature - encodedSign := string(base64.StdEncoding.EncodeToString([]byte(sign))) - - //add headers for authentication - r.Header.Add("Rest-Key", b.pubkey) - r.Header.Add("Rest-Sign", encodedSign) - - //do request - res, err := client.Do(r) - - //error handling - if res.StatusCode != 200 { - return result, fmt.Errorf("Request didn't return a HTTP Status 200 but HTTP Status: %v.", res.StatusCode) - } - - //error handling - if err != nil { - return result, err - } - - //read request body - contents, err := ioutil.ReadAll(res.Body) - - //parse json - err = json.Unmarshal(contents, &result) - - //error handling - if err != nil { - return result, err - } - - //handle Bl3pResult error - if result.Result == "error" { - blerr := Error{} - json.Unmarshal(contents, &blerr) - err = blerr - } - - return result, err -} - -//AddOrder | Add new order to the orderbook -func (b Bl3p) AddOrder(orderType string, orderAmount int, orderPrice int) (interface{}, error) { - - price := strconv.FormatInt(int64(orderPrice), 10) - amount := strconv.FormatInt(int64(orderAmount), 10) - - params := map[string]string{"type": orderType, "amount_int": amount, "price_int": price, "fee_currency": "BTC"} - - addOrder, err := b.requester("BTCEUR/money/order/add", params) - - result := callModels.AddOrder{} - - if err == nil { - err = json.Unmarshal(addOrder.Data, &result) - } - - return result, err -} - -//WalletHistory | Retrieve your account transaction history -func (b Bl3p) WalletHistory(currency string) (callModels.Transactions, error) { - - params := map[string]string{"currency": currency, "recs_per_page": "25"} - - transactions, err := b.requester("GENMKT/money/wallet/history", params) - - result := callModels.Transactions{} - - if err == nil { - err = json.Unmarshal(transactions.Data, &result) - } - - return result, err -} - -//CancelOrder | Cancel an open order -func (b Bl3p) CancelOrder(orderID int) (callModels.Bl3pResult, error) { - - params := map[string]string{"order_id": strconv.FormatInt(int64(orderID), 10)} - - result, err := b.requester("BTCEUR/money/order/cancel", params) - - return result, err -} - -//OrderInfo | Retrieve information about an order -func (b Bl3p) OrderInfo(orderID int) (callModels.Order, error) { - - params := map[string]string{"order_id": strconv.FormatInt(int64(orderID), 10)} - - order, err := b.requester("BTCEUR/money/order/result", params) - - result := callModels.Order{} - - if err == nil { - err = json.Unmarshal(order.Data, &result) - } - - return result, err -} - -//FetchLast1000Trades | Retrieve the last 1000 trades or the last 1000 trades after the specified tradeID -func (b Bl3p) FetchLast1000Trades(tradeID int) (callModels.Trades, error) { - var trades callModels.Bl3pResult - var err error - - if tradeID != 0 { - params := map[string]string{"trade_id": strconv.FormatInt(int64(tradeID), 10)} - trades, err = b.requester("BTCEUR/money/trades/fetch", params) - } else { - trades, err = b.requester("BTCEUR/money/trades/fetch", nil) - } - - result := callModels.Trades{} - - if err == nil { - err = json.Unmarshal(trades.Data, &result) - } - - return result, err -} - -//FullDepth | Retrieve the orderbook -func (b Bl3p) FullDepth() (callModels.Fulldepth, error) { - - fullDepth, err := b.requester("BTCEUR/money/depth/full", nil) - - result := callModels.Fulldepth{} - - if err == nil { - err = json.Unmarshal(fullDepth.Data, &result) - } - - return result, err -} - -//GetAllActiveOrders | Retrieve all your open orders -func (b Bl3p) GetAllActiveOrders() (callModels.Orders, error) { - - allActiveOrders, err := b.requester("BTCEUR/money/orders", nil) - - result := callModels.Orders{} - - if err == nil { - err = json.Unmarshal(allActiveOrders.Data, &result) - } - - return result, err -} - -//GetNewDepositAddress | Create a new bitcoin deposit address -func (b Bl3p) GetNewDepositAddress() (callModels.DepositAddress, error) { - - depositAddress, err := b.requester("BTCEUR/money/new_deposit_address", nil) - - result := callModels.DepositAddress{} - - if err == nil { - err = json.Unmarshal(depositAddress.Data, &result) - } - - return result, err -} - -//GetLastDepositAddress | Retrieve the last created bitcoin deposit address -func (b Bl3p) GetLastDepositAddress() (callModels.DepositAddress, error) { - - depositAddress, err := b.requester("BTCEUR/money/deposit_address", nil) - - result := callModels.DepositAddress{} - - if err == nil { - err = json.Unmarshal(depositAddress.Data, &result) - } - - return result, err -} diff --git a/examples/go/callModels/callModels.go b/examples/go/callModels/callModels.go deleted file mode 100644 index 3883161..0000000 --- a/examples/go/callModels/callModels.go +++ /dev/null @@ -1,107 +0,0 @@ -package callModels - -import "encoding/json" - -//Bl3pResult | Main result struct -type Bl3pResult struct { - Result string `json:"result"` - Data json.RawMessage `json:"data"` -} - -//Fulldepth | FullDepth call struct -type Fulldepth struct { - Bids []OrderbookItem - Asks []OrderbookItem -} - -//OrderbookItem | Orderbook item struct -type OrderbookItem struct { - Count int `json:"count"` - PriceInt int64 `json:"price_int"` - AmountInt int64 `json:"amount_int"` -} - -//Orders | Order array struct -type Orders struct { - Order []Order `json:"orders"` -} - -//Trades | Trades array struct -type Trades struct { - Trade []Trade `json:"trades"` -} - -//Order | Order struct -type Order struct { - OrderID int64 `json:"order_id"` - Label string `json:"label"` - Currency string `json:"currency"` - Item string `json:"item"` - Type string `json:"type"` - Status string `json:"status"` - Date int64 `json:"date"` - Amount AmountObj `json:"amount"` - AmountExecuted AmountObj `json:"amount_executed"` - AmountFunds AmountObj `json:"amount_funds"` - AmountFundsExecuted AmountObj `json:"amount_funds_executed"` - Price AmountObj `json:"price"` - TotalAmount AmountObj `json:"total_amount"` - TotalSpent AmountObj `json:"total_spent"` - TotalFee AmountObj `json:"total_fee"` - AvgCost AmountObj `json:"avg_cost"` - Trades []Trade `json:"trades"` -} - -//Trade | Trade struct -type Trade struct { - TradeID int64 `json:"trade_id"` - Date int64 `json:"date"` - Currency string `json:"currency"` - Amount AmountObj `json:"amount"` - Price AmountObj `json:"price"` - AmountInt int64 `json:"amount_int"` - Item string `json:"item"` - PriceInt int64 `json:"price_int"` -} - -//AmountObj | AmountObj struct -type AmountObj struct { - ValueInt string `json:"value_int"` - DisplayShort string `json:"display_short"` - Display string `json:"display"` - Currency string `json:"currency"` - Value string `json:"value"` -} - -//DepositAddress | DepositAddress call struct -type DepositAddress struct { - Address string `json:"address"` -} - -//Transactions | WalletHistory call struct -type Transactions struct { - Page int64 `json:"page"` - Records int64 `json:"records"` - MaxPpage int64 `json:"max_page"` - Transactions []Transaction `json:"transactions"` -} - -//Transaction | Transaction struct -type Transaction struct { - TransactionID int64 `json:"transaction_id"` - Amount AmountObj `json:"amount"` - Date int64 `json:"date"` - DebitCredit string `json:"debit_credit"` - Price AmountObj `json:"price"` - OrderID int64 `json:"order_id"` - Type string `json:"type"` - Balance AmountObj `json:"balance"` - TradeID int64 `json:"trade_id"` - ContraAmount AmountObj `json:"contra_amount"` - Fee AmountObj `json:"fee"` -} - -//AddOrder | AddOrder call struct -type AddOrder struct { - OrderID int64 `json:"order_id"` -} diff --git a/examples/go/example/example.go b/examples/go/example/example.go deleted file mode 100644 index bafdb6c..0000000 --- a/examples/go/example/example.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "fmt" - "time" - - bl3p "github.com/BitonicNL/bl3p-api/examples/go/bl3p" -) - -func main() { - - var bl3p = bl3p.NewBl3p( - "https://api.bl3p.eu", - "YOUR_PUBLIC_API_KEY", - "YOUR_PRIVATE_API_KEY", - "1", - ) - - depositAddress, err := bl3p.GetNewDepositAddress() - if err != nil { - panic(err) - } else { - fmt.Println(depositAddress) - } - - last1000trades, err := bl3p.FetchLast1000Trades(0) - if err != nil { - fmt.Println(err) - } else { - var dayvol float64 - for _, t := range last1000trades.Trade { - if int32(t.Date/1000) >= int32(time.Now().Unix()-86400) { - amountPrice := float64(t.AmountInt) / 1e8 - dayvol = dayvol + amountPrice - } - } - fmt.Printf("The volume of the last 24 hours is: %v \n", dayvol) - } -} diff --git a/examples/java/ComingSoon.md b/examples/java/ComingSoon.md deleted file mode 100644 index e69de29..0000000 diff --git a/examples/nodejs/example.md b/examples/nodejs/example.md deleted file mode 100644 index 4755035..0000000 --- a/examples/nodejs/example.md +++ /dev/null @@ -1,933 +0,0 @@ -# BL3P NodeJS module - -## Table of contents - -1. Introduction - - 1. Installation - 2. Example code - -2. Basic functions - - 1. Create an order - 2. Cancel an order - 3. Get a specific order - 4. Get the whole orderbook - 5. Live trade stream - 6. Live orderbook stream - -3. Account info & functions - - 1. Get the transaction history - 2. Create a new deposit address - 3. Get the last deposit address - 4. Create a withdrawal - 5. Get account info & balance - 6. Get active orders - 7. Get the last 1000 trades after an specific trade - -4. Appendix - Error code - ---- - -## 1 - Introduction - -This document describes the usage of BL3P NodeJS module. -If you don't have an API-key you can signup and create one at https://bl3p.eu. - -## 1.1 - Installation - -The BL3P nodejs library is available within Node Package Manager. - -https://www.npmjs.com/package/bl3p - -To install, navigate into your nodejs project directory and run the defined command below in your command-line: -``` -npm install bl3p -``` - -## 1.2 - Example code - -```javascript -var bl3p = require('bl3p'); -var public_key = 'YOUR_PUBLIC_KEY'; -var private_key = 'YOUR_PRIVATE_KEY'; - -var bl3p_auth = new bl3p.Bl3pAuth(public_key, private_key); - -bl3p_auth.account_info(function(error, data){ - if(data){ - console.log(data); - }else{ - console.log(error); - } -}); - -bl3p.trades(function(error, data){ - if(data){ - console.log(data); - }else{ - console.log(error); - } -}); - -bl3p.orderbook(function(error, data){ - if(data){ - console.log(data); - }else{ - console.log(error); - } -}); -``` - -## 2 - Basic functions - -All the methods return a data and an error array in JSON format. -All methods also require a callback method. The callback method is always the last required parameter. -In case of an error, an error code will be retuned. The possible error codes are listed in the appendix. - -## 2.1 - Create an order - -### Method - ->```text ->add_order(amount, type, price, fee_currency, amount_funds, callback) ->``` - -### Parameters ->`type` string ->``` ->'bid', 'ask' ->``` ->___ ->`amount` int ->``` ->Amount BTC, amount LTC (*1e8) ->``` ->The field described above is optional ->___ ->`price` int ->``` ->Limit price in EUR (*1e5) ->``` ->The field described above is optional ->___ ->`amount_funds` int ->``` ->Maximal EUR amount to spend (*1e5) ->``` ->The field described above is optional ->___ ->`fee_currency` string ->``` ->Currency the fee is accounted in. Can be: 'EUR' or 'BTC' ->``` ->___ - -### Response ->`order_id` int ->``` ->The id of the order. ->``` - -## 2.2 - Cancel an order - -### Method - ->```text ->cancel_order(order_id, callback) ->``` - -### Parameters ->`order_id` int ->``` ->The id of the order that you wish to cancel. ->``` - -### Response ->``` ->For this call there is no specific result returned other then ->the result of the call which contains: 'success' or 'failed' and a optional error array. ->``` - - -## 2.3 - Get a specific order -### Method ->```text ->order_info(order_id, callback) ->``` - -### Parameters ->`order_id` int ->``` ->The id of the order that you wish to retrieve. ->``` - -### Response ->`order_id` int ->``` ->Id of the order. ->``` ->___ ->`label` string ->``` ->API-key label ->``` ->___ ->`currency` string ->``` ->Currency of the order. (Is now by default 'EUR') ->``` ->___ ->`item` string ->``` ->The item that will be traded for `currency`. (Can be: 'BTC' or 'LTC') ->``` ->___ ->`type` string ->``` ->Type of order. (Can be: 'bid', 'ask') ->``` ->___ ->`amount` amountObj ->``` ->Total order amount of BTC or LTC. ->``` ->The field described above is optional ->___ ->`price` amountObj ->``` ->Order limit price. ->``` ->The field described above is optional ->___ ->`status` string ->``` ->Status of the order. (Can be: 'pending’, ‘open’, ‘closed’, ‘cancelled’) ->``` ->___ ->`date` timestamp ->``` ->The time the order got added. ->``` ->___ ->`total_amount` amountObj ->``` ->Total amount of the trades that got executed. (Can be: BTC or LTC). ->``` ->___ ->`total_spent` amountObj ->``` ->Total amount in EUR of the trades that got executed. ->``` ->___ ->`total_fee` amountObj ->``` ->Total fee incurred in BTC or LTC. ->``` ->___ ->`avg_cost` amountObj ->``` ->Average cost of executed trades. ->``` ->The field described above is optional ->___ ->`trades` array ->``` ->Array of trades executed for the regarding order. ->``` ->**Each array item of 'trade' will contain:** ->>`amount` amountObj ->>``` ->>BTC or LTC amount. ->>``` ->>___ ->>`currency` string ->>``` ->>Currency of the regarding trade. ->>``` ->>___ ->>`date` timestamp ->>``` ->>The time of the trade execution. ->>``` ->>___ ->>`item` string ->>``` ->>'BTC' or 'LTC' ->>``` ->>___ ->>`price` amountObj ->>``` ->>Price of the executed trade in EUR. ->>``` ->>___ ->>`trade_id` int ->>``` ->>Id of trade. ->>``` ->> ->___ - -## 2.4 - Get the whole orderbook - -### Method - ->```text ->full_depth(callback) ->``` - -### Parameters - ->``` ->There are no specific parameters required for this call. ->``` - -### Response ->`asks` array ->``` ->Array of asks that are in the orderbook. ->``` ->**Each array item of 'asks' will contain:** ->> ->>`amount_int` int ->>``` ->>Amount BTC, amount LTC (*1e8) ->>``` ->>___ ->>`price_int` int ->>``` ->>Limit price in EUR (*1e5) ->>``` ->>___ ->>`count` int ->>``` ->>Count of orders at this price. ->>``` ->> ->___ ->> ->`bids` array ->``` ->Array of bids that are in the orderbook. ->``` ->**Each array item of 'bids' will contain:** ->> ->>`amount_int` int ->>``` ->>Amount BTC, amount LTC (*1e8) ->>``` ->>___ ->>`price_int` int ->>``` ->>Limit price in EUR (*1e5) ->>``` ->>___ ->>`count` int ->>``` ->>Count of orders at this price. ->>``` ->> ->___ - -## 2.5 - Live trade stream - -### Method - ->```text ->trades(callback) ->``` - -### Response - ->`amount_int` int ->``` ->Traded BTC Amount or traded LTC amount (*1e8) ->``` ->___ ->`price_int` int ->``` ->Trade price in EUR (*1e5) ->``` ->___ ->`date` timestamp ->``` ->The time of the trade execution. ->``` -___ - -## 2.6 - Live orderbook stream - -### Method - ->```text ->orderbook(callback) ->``` - -### Response ->`asks` array ->``` ->Array of asks that are in the orderbook. ->``` ->**Each array item of 'asks' will contain:** -> ->>`amount_int` int ->>``` ->>Amount BTC, amount LTC (*1e8) ->>``` ->>___ ->>`price_int` int ->>``` ->>Limit price in EUR (*1e5) ->>``` ->>___ ->>`count` int ->>``` ->>Count of orders at this price. ->>``` ->> ->___ -> ->`bids` array ->``` ->Array of bids that are in the orderbook. ->``` ->**Each array item of 'bids' will contain:** ->> ->>`amount_int` int ->>``` ->>Amount BTC, amount LTC (*1e8) ->>``` ->>___ ->>`price_int` int ->>``` ->>Limit price in EUR (*1e5) ->>``` ->>___ ->>`count` int ->>``` ->>Count of orders at this price. ->>``` ->> ->___ - -## 3 - Account info & functions - -## 3.1 - Get your transaction history - -### Method - ->```text ->wallet_history(currency, page, date_from, date_to, type, recs_per_page, callback) ->``` - -### Parameters - ->`currency` string ->``` ->Currency of the wallet. (Can be: 'BTC', 'EUR' or 'LTC') ->``` ->___ ->`page` int ->``` ->Page number. (1 = most recent transactions) ->``` ->The field described above is optional ->___ ->`date_from` timestamp ->``` ->Filter the result by an Unix-timestamp. Transactions before this date will not be returned. ->``` ->The field described above is optional ->___ ->`date_to` timestamp ->``` ->Filter the result by an Unix-timestamp. Transactions after this date will not be returned. ->``` ->The field described above is optional ->___ ->`type` string ->``` ->Filter the result by type. (Can be: ‘trade’, ‘fee’, ‘deposit’, ‘withdraw’) ->``` ->The field described above is optional ->___ ->`recs_per_page` int ->``` ->Number of records per page. ->``` ->The field described above is optional ->___ - -### Response - ->`page` int ->``` ->Current page number. ->``` ->___ ->`records` int ->``` ->Count of records in the result set. ->``` ->___ ->`max_page` int ->``` ->Number of last page. ->``` ->___ ->`transactions` array ->``` ->Array of transactions. ->``` ->**Each array item of 'transactions' will contain:** ->>`transaction_id` int ->>``` ->>Id of the transaction. ->>``` ->>`amount` amountObj ->>``` ->>BTC or LTC amount. ->>``` ->>___ ->>`date` timestamp ->>``` ->>Time when the regarding transaction took place. ->>``` ->>___ ->>`debit_credit` string ->>``` ->>Type of booking. (Can be: 'debit' or 'credit') ->>``` ->>___ ->>`price` amountObj ->>``` ->>Price of the executed trade. ->>``` ->>The field described above is optional ->>___ ->>`order_id` int ->>``` ->>Id of the order. ->>``` ->>The field described above is optional ->>___ ->>`type` string ->>``` ->>Type of transaction (Can be: 'trade’, ‘fee’, ‘deposit’, ‘withdraw’) ->>``` ->>___ ->>`balance` amountObj ->>``` ->>Balance of the user his account (for the regarding currency) after the transaction. ->>``` ->>___ ->>`trade_id` int ->>``` ->>Id of the trade. ->>``` ->>The field described above is optional ->>___ ->>`contra_amount` amountObj ->>``` ->>Contra amount of the trade. ->>``` ->>The field described above is optional ->>___ ->>`fee` amountObj ->>``` ->>Fee incurred by the regarding trade ->>``` ->> ->___ - -## 3.2 - Create a new deposit address - -### Method - ->```text ->new_deposit_address(callback) ->``` - -### Parameters - ->``` ->There are no specific parameters required for this call. ->``` - -### Response - ->`address` string ->``` ->Deposit address for the market leading currency ->``` - -## 3.3 - Get the last deposit address - -### Method - ->```text ->last_deposit_address ->``` - -### Parameters - ->``` ->There are no specific parameters required for this call. ->``` - -### Response - ->`address` string ->``` ->Deposit address for the market leading currency ->``` - -## 3.4 - Create a withdrawal - -### Method - ->```text ->withdraw(type, amount, account, callback) ->``` - -### Parameters ->`account` string ->``` ->IBAN account-id (that is available within the regarding BL3P account) or a Bitcoin address ->``` ->**Note: The kind of account value you need to specify depends on the 'type' parameter described below.** ->___ ->`type` string ->``` ->Can be 'EUR' or 'BTC' ->``` ->___ ->`amount` int ->``` ->Satoshis or 0,00001 EUR ->``` - -### Response - ->`id` int ->``` ->Id of the withdrawal ->``` - -## 3.5 - Get account info & balance -### Method - ->```text ->account_info(callback) ->``` - -### Parameters - ->``` ->There are no specific parameters required for this call. ->``` - -### Response - ->`user_id` int ->``` ->Id of the user. ->``` ->___ ->`trade_fee` float ->``` ->Percentage fee for the user ->``` ->___ ->`wallets` array ->``` ->Array of wallets. ->``` ->**Each array item of 'wallets' will contain:** ->> ->>`balance` amountObj ->>``` ->>Balance in this wallet ->>``` ->>___ ->>`available` amountObj ->>``` ->>Available in this wallet. ->>``` ->> ->___ - -## 3.6 Get active orders -### Method ->```text ->active_orders(callback) ->``` - -### Parameters - ->``` ->There are no specific parameters required for this call. ->``` - -### Response - ->`orders` array ->``` ->Array of active orders. ->``` ->**Each array item of 'orders' will contain:** -> ->>`order_id` int ->>``` ->>Id of the order. ->>``` ->>___ ->>`label` string ->>``` ->>API-key label ->>``` ->>___ ->>`currency` string ->>``` ->>Currency of the order. (Is now by default 'EUR') ->>``` ->>___ ->>`item` string ->>``` ->>The item that will be traded for `currency`. (Can be: 'BTC' or 'LTC') ->>``` ->>___ ->>`type` string ->>``` ->>Type of order. (Can be: 'bid', 'ask') ->>``` ->>___ ->>`status` string ->>``` ->>Status of the order. (Can be: 'pending’, ‘open’, ‘closed’, ‘cancelled’) ->>``` ->>___ ->>`date` timestamp ->>``` ->>The time the order got added. ->>``` ->>___ ->>`amount` amountObj ->>``` ->>Total order amount of BTC or LTC. ->>``` ->>The field described above is optional ->>___ ->>`amount_funds_executed` amountObj ->>``` ->>Amount in funds that is executed. ->>``` ->>___ ->>`amount_executed` amountObj ->>``` ->>Amount that is executed. ->>``` ->>___ ->>`price` amountObj ->>``` ->>Order limit price. ->>``` ->>The field described above is optional ->>___ ->>`amount_funds` amountObj ->>``` ->>Maximal EUR amount to spend (*1e5) ->>``` ->>The field described above is optional ->> ->___ - -## 3.7 - Get the last 1000 trades after an specific trade - -### Method - ->```text ->last_1000_trades(trade_id, callback) ->``` - -### Parameters - ->`trade_id` int ->``` ->Id of the trade ->``` ->The field described above is optional, if this field isn't specified, this call will return the last 1000 trades. -> - -### Response - ->`trades` array ->``` ->Array of trades. ->``` ->**Each array item of 'trades' will contain:** ->>`trade_id` int ->>``` ->>Id of the trade. ->>``` ->>___ ->>`date` timestamp ->>``` ->>The time of the trade execution. ->>``` ->>___ ->>`amount_int` int ->>``` ->>Amount traded. (*1e8) ->>``` ->>___ ->>`price_int` int ->>``` ->>Price of the traded item in EUR. (*1e5) ->>``` ->> ->___ - -## 4 - Appendix - Error codes - -The API can respond to invalid calls with the following error messages: - -`AMOUNT_FUNDS_LESS_THAN_MINIMUM` -``` -Order amount (amount_funds) smaller than the minimum. -``` -___ - -`AMOUNT_LESS_THAN_MINIMUM` -``` -Order amount is smaller than the minimum -``` -___ - -`INSUFFICIENT_FUNDS` -``` -Not enough money on account for this order. -``` -___ - -`INVALID_AMOUNT` -``` -Invalid field 'amount_int'. -``` -___ - -`INVALID_AMOUNT_FUNDS` -``` -Invalid field 'amount_funds_int'. -``` -___ - -`INVALID_FEE_CURRENCY` -``` -Invalid field 'fee_currency'. -``` -___ - -`INVALID_LIMIT_ORDER` -``` -Limitorders can't have both an 'amount' and an 'amount_funds'. -``` -___ - -`INVALID_PRICE` -``` -Invalid field 'price_int'. -``` -___ - -`INVALID_TYPE` -``` -Invalid field type (‘bid’ or ‘ask’). -``` -___ - -`KEY_MISSING` -``` -The Rest-Key header misses. -``` -___ - -`LIMIT_REACHED` -``` -User has done to much calls. -``` -___ - -`MARKETPLACE_INACCESSIBLE` -``` -Market (temporarily) closed. -``` -___ - -`MARKETPLACE_NOT_ACCEPTING_ORDERS` -``` -Market does (temporarily) not accepts orders. -``` -___ - -`MISSING_AMOUNT` -``` -The field 'amount' or 'amout_funds' is missing with this order. -``` -___ - -`MISSING_FIELD` -``` -A required field at this call is missing. -``` -___ - -`NOT_AUTHENTICATED` -``` -Signature-key-combination is invalid. -``` -___ - -`SIGN_MISSING` -``` -The Rest-Sign header misses. -``` -___ - -`UNKNOWN_ACCOUNT` -``` -User has no account for given currency (SystemServer) -``` -___ - -`UNKNOWN_CURRENCY` -``` -The requested currency doesn't exist. -``` -___ - -`UNKNOWN_ERROR` -``` -An unknown server error occured. -``` -___ - -`UNKNOWN_MARKETPLACE` -``` -The requested market doesn't exist. -``` -___ - -`UNKNOWN_ORDER` -``` -The order to cancel or fetch doesn't exist -``` -___ - - -`UNKNOWN_PATH` -``` -Requested path and/or call doesn't exist. -``` -___ diff --git a/examples/php/example.php b/examples/php/example.php deleted file mode 100644 index 1d524b0..0000000 --- a/examples/php/example.php +++ /dev/null @@ -1,280 +0,0 @@ - - */ -class Bl3pApi { - - private $pubkey; - private $privkey; - private $url; - - /** - * Set the url to call, the public key and the private key - * @method __construct - * @param string $url Url to call (https://api.bl3p.eu) - * @param string $pubkey Your Public API key - * @param string $privkey Your Private API key - */ - function __construct($url, $pubkey, $privkey) { - $this->url = $url; - $this->pubkey = $pubkey; - $this->privkey = $privkey; - } - - /** - * To make a call to BL3P API - * @method apiCall - * @param string $path path to call - * @param array $params parameters to add to the call - * @return array result of call - */ - public function apiCall($path, $params=array()) { - - // generate a nonce as microtime, with as-string handling to avoid problems with 32bits systems - $mt = explode(' ', microtime()); - $params['nonce'] = $mt[1].substr($mt[0], 2, 6); - - // generate the POST data string - $post_data = http_build_query($params, '', '&'); - $body = $path . chr(0). $post_data; - - //build signature for Rest-Sign - $sign = base64_encode(hash_hmac('sha512', $body, base64_decode($this->privkey), true)); - - //combine the url and the desired path - $fullpath = $this->url . $path; - - //set headers - $headers = array( - 'Rest-Key: '.$this->pubkey, - 'Rest-Sign: '. $sign, - ); - - //build curl call - $ch = curl_init(); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; BL3P PHP client; '.php_uname('s').'; PHP/'.phpversion().')'); - curl_setopt($ch, CURLOPT_URL, $fullpath); - curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - curl_setopt($ch, CURLOPT_SSLVERSION, 1); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); - curl_setopt($ch, CURLOPT_TIMEOUT, 10); - - //execute curl request - $res = curl_exec($ch); - - //throw exception with additional information when curl request returns false - if ($res === false) { - throw new Exception("API request failed: Could not get reply from API: ".curl_error($ch)); - } - - //close curl connection - curl_close ($ch); - - //convert json into an array - $result = json_decode($res, true); - - //check json convert result and throw an exception if invalid - if (!$result) { - throw new Exception("API request failed: Invalid JSON-data received: ".substr($res,0,100)); - } - - if(!array_key_exists('result', $result)) { - //note that data now is the first element in the array. - $result['data'] = $result; - $result['result'] = 'success'; - - //remove all the keys in $result except 'result' and 'data' - return array_intersect_key($result, array_flip(['result', 'data'])); - } - - //check returned result of call, if not success then throw an exception with additional information - if ($result['result'] !== 'success') { - if (!isset($result['data']['code']) || !isset($result['data']['message'])) - throw new Exception(sprintf('Received unsuccessful state, and additionally a malformed response: %s', var_export($result['data'], true))); - - throw new Exception(sprintf("API request unsuccessful: [%s] %s", $result['data']['code'], $result['data']['message'])); - } - - return $result; - } -} - -/** - * =================================================== - * Code to make calls with help of the Bl3pApi class - * =================================================== - **/ - -$url = "https://api.bl3p.eu/1/"; -$pubkey = "YOUR_PUBLIC_API_KEY"; -$privkey = "YOUR_PRIVATE_API_KEY"; - -//Init Bl3pAPi class -$api = new Bl3pApi($url, $pubkey, $privkey); - -try { - - //Add an buy order for 0.01 @400 euro - - $result = addOrder('bid', 1000000, 40000000); - - echo '
'.var_export($result, true) . '
'; -} catch (Exception $ex) { - echo '
'.var_export($ex, true) . '
'; -} - -/** - * Add order to your account. - * @method addOrder - * @param string $order_type 'bid' or 'ask' - * @param int $order_amount Amount to order *1e8 - * @param int $order_price Price of order *1e5 - * @return array Result of the add order call - */ - -function addOrder($order_type, $order_amount, $order_price) { - - global $api; - - $params = array( - 'type' => $order_type, - 'amount_int' => $order_amount, - 'price_int' => $order_price, - 'fee_currency' => 'BTC' - ); - - $result = $api->apiCall("BTCEUR/money/order/add", $params); - - return $result; -} - -/** - * Cancel a specific order. - * @method cancelOrder - * @param int $order_id Id of the order - * @return array Direct resulf of the '/money/order/cancel' call - */ - -function cancelOrder($order_id) { - - global $api; - - $params = array( - 'order_id' => $order_id - ); - - return $api->apiCall("BTCEUR/money/order/cancel", $params); -} - -/** - * Fetch information about an specific order - * @method orderInfo - * @param int $order_id Id of the order - * @return array Direct resulf of the '/money/order/result' call - */ - -function orderInfo($order_id) { - - global $api; - - $params = array( - 'order_id' => $order_id - ); - - return $api->apiCall("BTCEUR/money/order/result", $params); -} - -/** - * Fetch complete orderbook - * @method fullDepth - * @return array Direct resulf of the '/money/depth/full' call - */ - -function fullDepth() { - - global $api; - - return $api->apiCall("BTCEUR/money/depth/full"); -} - -/** - * Get new deposit address. - * @method getNewDepositAddress - * @return array new deposit address - */ - -function getNewDepositAddress() { - - global $api; - - return $api->apiCall("BTCEUR/money/new_deposit_address"); -} - -/** - * Get the most recent generated deposit address - * @method getLastDepositAddress - * @return array most recent generated deposit address - */ - -function getLastDepositAddress() { - - global $api; - - return $api->apiCall("BTCEUR/money/deposit_address"); -} - -/** - * Get the last 1000 trades that where executed before an specific trade_id - * @method fetchTrades - * @param int $trade_id id of the trade - * @return array array of last 1000 executed trades. - */ - -function fetchLast1000Trades($trade_id) { - - global $api; - - $params = array( - 'trade_id' => $trade_id - ); - - return $api->apiCall("BTCEUR/money/trades/fetch", $params); -} - -/** - * Get the transaction history - * @method walletHistory - * @param string $currency type of currency - * @return array array of transactions - */ - -function walletHistory($currency) { - - global $api; - - $params = array( - 'currency' => $currency, - 'recs_per_page' => 25 - ); - - return $api->apiCall("GENMKT/money/wallet/history", $params); -} - - -/** - * Get all open orders. - * @method getAllActiveOrders - * @return array array of open orders - */ - -function getAllActiveOrders(){ - - global $api; - - return $api->apiCall("BTCEUR/money/orders"); -} diff --git a/examples/python/example-py.txt b/examples/python/example-py.txt deleted file mode 100644 index 1fd2089..0000000 --- a/examples/python/example-py.txt +++ /dev/null @@ -1,100 +0,0 @@ -Examples -======== - -invalid public/secret key: -------------------------- -{ - "data": { - "code": "KEY_MISSING", - "message": "Rest-Key missing" - }, - "result": "error" -} - - -invalid market: --------------- -{ - "data": { - "code": "UNKNOWN_MARKETPLACE", - "message": "Unknown marketplace" - }, - "result": "error" -} - - -price too low: -------------- -{ - "data": { - "code": "PRICE_LESS_THAN_MINIMUM", - "message": "Price '1' less than marketplace minimum '1000'" - }, - "result": "error" -} - - -insufficient funds: ------------------- -{ - "data": { - "code": "INSUFFICIENT_FUNDS", - "message": "Insufficient available funds, available = 0 order value = 10000000" - }, - "result": "error" -} - - -market unavailable: ------------------- -{ - "data": { - "code": "ERR_TEMPORARILY_UNAVAILABLE", - "message": "Error creating address" - }, - "result": "error" -} - - -walletHistory(): -------------- -{ - "data": { - "max_page": 1, - "page": 1, - "records": 1, - "transactions": [ - { - "amount": { - "currency": "BTC", - "display": "0.01000000 BTC", - "display_short": "0.01 BTC", - "value": "0.01000000", - "value_int": "1000000" - }, - "balance": { - "currency": "BTC", - "display": "0.01000000 BTC", - "display_short": "0.01 BTC", - "value": "0.01000000", - "value_int": "1000000" - }, - "date": 1450353480, - "debit_credit": "credit", - "transaction_id": 575126, - "type": "deposit" - } - ] - }, - "result": "success" -} - - -getNewDepositAddress(): --------------------- -{ - "data": { - "address": "**********************************" - }, - "result": "success" -} diff --git a/examples/python/example.cfg b/examples/python/example.cfg deleted file mode 100644 index 3e98153..0000000 --- a/examples/python/example.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[bl3p] -public_key= -secret_key= diff --git a/examples/python/example.py b/examples/python/example.py deleted file mode 100755 index f268cb7..0000000 --- a/examples/python/example.py +++ /dev/null @@ -1,208 +0,0 @@ -#! /usr/bin/python - -# this code was written by folkert@vanheusden.com -# it has been released under AGPL v3.0 - -# it requires 'pycurl' -# in debian this can be found in the 'python-pycurl' package - -import base64 -import ConfigParser -import hashlib -import hmac -import json -import pycurl -import sys -import urllib - -try: - from io import BytesIO -except ImportError: - from StringIO import StringIO as BytesIO - -from datetime import datetime -from time import mktime - -class Bl3pApi: - url = None - pubKey = None - secKey = None - verbose = False - - def __init__(self, u, pk, sk): - self.url = u - self.pubKey = pk - self.secKey = sk - - def setVerbose(self, v): - self.verbose = v - - def apiCall(self, path, params): - dt = datetime.utcnow() - us = mktime(dt.timetuple()) * 1000 * 1000 + dt.microsecond - nonce = '%d' % us - - # generate the POST data string - post_data = urllib.urlencode(params) - - body = '%s%c%s' % (path, 0x00, post_data) - - privkey_bin = base64.b64decode(self.secKey) - - signature_bin = hmac.new(privkey_bin, body, hashlib.sha512).digest() - - signature = base64.b64encode(signature_bin) - - fullpath = '%s%s' % (self.url, path) - - headers = [ 'Rest-Key: %s' % self.pubKey, 'Rest-Sign: %s' % signature ] - - buffer = BytesIO() - - c = pycurl.Curl() - c.setopt(c.USERAGENT, 'Mozilla/4.0 (compatible; BL3P Python client written by folkert@vanheusden.com; 0.1)'); - c.setopt(c.WRITEFUNCTION, buffer.write) - c.setopt(c.URL, fullpath); - c.setopt(c.POST, 1); - c.setopt(c.POSTFIELDS, post_data); - c.setopt(c.HTTPHEADER, headers); - c.setopt(c.SSLVERSION, 1); - c.setopt(c.SSL_VERIFYPEER, True); - c.setopt(c.SSL_VERIFYHOST, 2); - c.setopt(c.CONNECTTIMEOUT, 5); - c.setopt(c.TIMEOUT, 10); - - if self.verbose: - c.setopt(c.VERBOSE, 1) - else: - c.setopt(c.VERBOSE, 0) - - c.perform() - - response_code = c.getinfo(c.RESPONSE_CODE) - if response_code != 200: - raise Exception('unexpected response code: %d' % response_code) - - c.close() - - return json.loads(buffer.getvalue()) - - # multiply the btc value (e.g 1.3BTC) with this and round-up/down - def getBtcMultiplier(self): - return 100000000 - - def getEurMutiplier(self): - return 100000 - - # Add order to your account. - # @method addOrder - # @param market 'EUR' - # @param order_type 'bid' or 'ask' - # bid: used if you want to buy bitcoins - # ask: if you want to sell bitcoins - # @param order_amount Amount to order *1e8 (so 1 bitcoin is 100000000) - # @param order_price Price of order *1e5 (1 euro is 100000) - # @return Result of the add order call - def addOrder(self, market, order_type, order_amount, order_price): - - params = { - 'type' : order_type, - 'amount_int' : order_amount, - 'price_int' : order_price, - 'fee_currency' : 'BTC' - } - - return self.apiCall('%sEUR/money/order/add' % market, params) - - # Cancel a specific order. - # @method cancelOrder - # @param market 'EUR' - # @param order_id Id of the order - # @return Direct resulf of the '/money/order/cancel' call - def cancelOrder(self, market, order_id): - params = { 'order_id' : order_id } - - return self.apiCall("%sEUR/money/order/cancel" % market, params) - - # Fetch information about an specific order - # @method orderInfo - # @param market 'EUR' - # @param order_id Id of the order - # @return Direct resulf of the '/money/order/result' call - def orderInfo(self, market, order_id): - params = { 'order_id' : order_id } - - return self.apiCall("%sEUR/money/order/result" % market, params) - - # Fetch complete orderbook - # @method fullDepth - # @param market 'EUR' - # @return Direct resulf of the '/money/depth/full' call - def fullDepth(self, market): - return self.apiCall("%sEUR/money/depth/full" % market, { }) - - # Get new deposit address. - # @method getNewDepositAddress - # @param market 'EUR' - # @return new deposit address - def getNewDepositAddress(self, market): - return self.apiCall("%sEUR/money/new_deposit_address" % market, { }) - - # Get the most recent generated deposit address - # @method getLastDepositAddress - # @param market 'EUR' - # @return most recent generated deposit address - def getLastDepositAddress(self, market): - return self.apiCall("%sEUR/money/deposit_address" % market, { }) - - # Get the last 1000 trades that where executed before an specific trade_id - # @method fetchTrades - # @param market 'EUR' - # @param trade_id id of the trade - # @return array of last 1000 executed trades. - def fetchLast1000Trades(self, market, trade_id): - params = { 'trade_id' : trade_id } - - return self.apiCall("%sEUR/money/trades/fetch" % market, params) - - # Get the transaction history - # @method walletHistory - # @param currency currency which currency - # @param n how many to retrieve - # @return array json structure with the transaction history - def walletHistory(self, currency, n): - params = { 'currency' : currency, 'recs_per_page' : n } - - return self.apiCall('GENMKT/money/wallet/history', params) - - # Get all open orders. - # @method getAllActiveOrders - # @param market 'EUR' - # @return array of open orders - def getAllActiveOrders(self, market): - return self.apiCall("%sEUR/money/orders" % market, { }); - - # Get the balances - # @method getBalances - # @return array json structure with the wallet balances - def getBalances(self): - params = { } - return self.apiCall('GENMKT/money/info', params) - -def d(j): - print json.dumps(j, sort_keys=True, indent=4, separators=(',', ': ')) - -# example: -config = ConfigParser.RawConfigParser() - -if len(sys.argv) == 2: - config.read(sys.argv[1]) -else: - config.read('example.cfg') - -public_key = config.get('bl3p', 'public_key') # ........-....-....-....-............ -secret_key = config.get('bl3p', 'secret_key') # (long string with a-z/A-Z/0-9 and =) - -b = Bl3pApi('https://api.bl3p.eu/1/', public_key, secret_key) - -d(b.walletHistory('BTC', 10)) diff --git a/setup.py b/setup.py index 1b0f55f..a338e19 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name='bl3p', - version='20171106.1', + version='20180112.0', description='BL3P.eu Python 3 exchange API', keywords='bl3p python3 exchange api', url='https://github.com/joosthoeks/bl3p-api', From a98fc29a830791e85a4f380480240902413d9bef Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Thu, 12 Apr 2018 18:26:03 +0000 Subject: [PATCH 09/12] moved some files --- README.md => examples/python3/README.md | 0 {bl3p => examples/python3/bl3p}/__init__.py | 0 {bl3p => examples/python3/bl3p}/api/__init__.py | 0 {bl3p => examples/python3/bl3p}/api/api.py | 0 setup.py => examples/python3/setup.py | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename README.md => examples/python3/README.md (100%) rename {bl3p => examples/python3/bl3p}/__init__.py (100%) rename {bl3p => examples/python3/bl3p}/api/__init__.py (100%) rename {bl3p => examples/python3/bl3p}/api/api.py (100%) rename setup.py => examples/python3/setup.py (100%) diff --git a/README.md b/examples/python3/README.md similarity index 100% rename from README.md rename to examples/python3/README.md diff --git a/bl3p/__init__.py b/examples/python3/bl3p/__init__.py similarity index 100% rename from bl3p/__init__.py rename to examples/python3/bl3p/__init__.py diff --git a/bl3p/api/__init__.py b/examples/python3/bl3p/api/__init__.py similarity index 100% rename from bl3p/api/__init__.py rename to examples/python3/bl3p/api/__init__.py diff --git a/bl3p/api/api.py b/examples/python3/bl3p/api/api.py similarity index 100% rename from bl3p/api/api.py rename to examples/python3/bl3p/api/api.py diff --git a/setup.py b/examples/python3/setup.py similarity index 100% rename from setup.py rename to examples/python3/setup.py From 60b0458ea31f60318f7f22388fdaf482eef867cb Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Thu, 12 Apr 2018 19:00:29 +0000 Subject: [PATCH 10/12] added files --- README.md | 14 + examples/go/bl3p/bl3p.go | 278 ++++++++ examples/go/callModels/callModels.go | 107 +++ examples/go/example/example.go | 39 ++ examples/java/ComingSoon.md | 0 examples/nodejs/example.md | 933 +++++++++++++++++++++++++++ examples/php/example.php | 280 ++++++++ examples/python/example-py.txt | 100 +++ examples/python/example.cfg | 3 + examples/python/example.py | 208 ++++++ 10 files changed, 1962 insertions(+) create mode 100644 README.md create mode 100644 examples/go/bl3p/bl3p.go create mode 100644 examples/go/callModels/callModels.go create mode 100644 examples/go/example/example.go create mode 100644 examples/java/ComingSoon.md create mode 100644 examples/nodejs/example.md create mode 100644 examples/php/example.php create mode 100644 examples/python/example-py.txt create mode 100644 examples/python/example.cfg create mode 100755 examples/python/example.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..67b3d02 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +BL3P exchange official documentation +=== + +Please access [docs](docs/) for the latest official documentation. + +API reference implementations +=== + +You can find each client reference implementation in: + +* [PHP](examples/php/) +* [NodeJs](examples/nodejs/) +* [Java](examples/java/) +* [Go](examples/go/) diff --git a/examples/go/bl3p/bl3p.go b/examples/go/bl3p/bl3p.go new file mode 100644 index 0000000..e3cb20a --- /dev/null +++ b/examples/go/bl3p/bl3p.go @@ -0,0 +1,278 @@ +package bl3p + +import ( + "bytes" + "crypto/hmac" + "crypto/sha512" + "encoding/base64" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strconv" + + "github.com/BitonicNL/bl3p-api/examples/go/callModels" +) + +//Bl3p struct +type Bl3p struct { + url string + pubkey string + privkey string + version string +} + +//Error struct +type Error struct { + Result string `json:"result"` + Data struct { + Code string `json:"code"` + Message string `json:"message"` + } `json:"data"` +} + +//NewBl3p | Returns new Bl3p struct +func NewBl3p(apiURL string, apiPubkey string, apiPrivkey string, apiVersion string) *Bl3p { + a := Bl3p{apiURL, apiPubkey, apiPrivkey, apiVersion} + return &a +} + +//Error | Extends default Error struct +func (e Error) Error() string { + return fmt.Sprintf("Message: %v: Code: %v", e.Data.Message, e.Data.Code) +} + +//requester | Creates the request to Bl3p API +func (b Bl3p) requester(call string, params map[string]string) (callModels.Bl3pResult, error) { + + //create empty bl3presult + result := callModels.Bl3pResult{} + + //build url + u, err := url.ParseRequestURI(b.url) + + //error handling + if err != nil { + return result, err + } + + u.Path = "/" + b.version + "/" + call + apiCallURL := fmt.Sprintf("%v", u) + + //prepare params + data := url.Values{} + + //convert params into querystring + if len(params) > 0 { + for k, p := range params { + data.Set(k, p) + } + } + + //create request + client := &http.Client{} + r, err := http.NewRequest("GET", apiCallURL, bytes.NewBufferString(data.Encode())) + + //error handling + if err != nil { + return result, err + } + + //request body + body := []byte(call + string(0) + data.Encode()) + + //decode privkey + base64Decode := make([]byte, base64.StdEncoding.DecodedLen(len(b.privkey))) + l, err := base64.StdEncoding.Decode(base64Decode, []byte(b.privkey)) + + //error handling + if err != nil { + return result, err + } + + decodedPrivkey := []byte(base64Decode[:l]) + + //sign + h := hmac.New(sha512.New, decodedPrivkey) + h.Write(body) + sign := h.Sum(nil) + + //encode signature + encodedSign := string(base64.StdEncoding.EncodeToString([]byte(sign))) + + //add headers for authentication + r.Header.Add("Rest-Key", b.pubkey) + r.Header.Add("Rest-Sign", encodedSign) + + //do request + res, err := client.Do(r) + + //error handling + if res.StatusCode != 200 { + return result, fmt.Errorf("Request didn't return a HTTP Status 200 but HTTP Status: %v.", res.StatusCode) + } + + //error handling + if err != nil { + return result, err + } + + //read request body + contents, err := ioutil.ReadAll(res.Body) + + //parse json + err = json.Unmarshal(contents, &result) + + //error handling + if err != nil { + return result, err + } + + //handle Bl3pResult error + if result.Result == "error" { + blerr := Error{} + json.Unmarshal(contents, &blerr) + err = blerr + } + + return result, err +} + +//AddOrder | Add new order to the orderbook +func (b Bl3p) AddOrder(orderType string, orderAmount int, orderPrice int) (interface{}, error) { + + price := strconv.FormatInt(int64(orderPrice), 10) + amount := strconv.FormatInt(int64(orderAmount), 10) + + params := map[string]string{"type": orderType, "amount_int": amount, "price_int": price, "fee_currency": "BTC"} + + addOrder, err := b.requester("BTCEUR/money/order/add", params) + + result := callModels.AddOrder{} + + if err == nil { + err = json.Unmarshal(addOrder.Data, &result) + } + + return result, err +} + +//WalletHistory | Retrieve your account transaction history +func (b Bl3p) WalletHistory(currency string) (callModels.Transactions, error) { + + params := map[string]string{"currency": currency, "recs_per_page": "25"} + + transactions, err := b.requester("GENMKT/money/wallet/history", params) + + result := callModels.Transactions{} + + if err == nil { + err = json.Unmarshal(transactions.Data, &result) + } + + return result, err +} + +//CancelOrder | Cancel an open order +func (b Bl3p) CancelOrder(orderID int) (callModels.Bl3pResult, error) { + + params := map[string]string{"order_id": strconv.FormatInt(int64(orderID), 10)} + + result, err := b.requester("BTCEUR/money/order/cancel", params) + + return result, err +} + +//OrderInfo | Retrieve information about an order +func (b Bl3p) OrderInfo(orderID int) (callModels.Order, error) { + + params := map[string]string{"order_id": strconv.FormatInt(int64(orderID), 10)} + + order, err := b.requester("BTCEUR/money/order/result", params) + + result := callModels.Order{} + + if err == nil { + err = json.Unmarshal(order.Data, &result) + } + + return result, err +} + +//FetchLast1000Trades | Retrieve the last 1000 trades or the last 1000 trades after the specified tradeID +func (b Bl3p) FetchLast1000Trades(tradeID int) (callModels.Trades, error) { + var trades callModels.Bl3pResult + var err error + + if tradeID != 0 { + params := map[string]string{"trade_id": strconv.FormatInt(int64(tradeID), 10)} + trades, err = b.requester("BTCEUR/money/trades/fetch", params) + } else { + trades, err = b.requester("BTCEUR/money/trades/fetch", nil) + } + + result := callModels.Trades{} + + if err == nil { + err = json.Unmarshal(trades.Data, &result) + } + + return result, err +} + +//FullDepth | Retrieve the orderbook +func (b Bl3p) FullDepth() (callModels.Fulldepth, error) { + + fullDepth, err := b.requester("BTCEUR/money/depth/full", nil) + + result := callModels.Fulldepth{} + + if err == nil { + err = json.Unmarshal(fullDepth.Data, &result) + } + + return result, err +} + +//GetAllActiveOrders | Retrieve all your open orders +func (b Bl3p) GetAllActiveOrders() (callModels.Orders, error) { + + allActiveOrders, err := b.requester("BTCEUR/money/orders", nil) + + result := callModels.Orders{} + + if err == nil { + err = json.Unmarshal(allActiveOrders.Data, &result) + } + + return result, err +} + +//GetNewDepositAddress | Create a new bitcoin deposit address +func (b Bl3p) GetNewDepositAddress() (callModels.DepositAddress, error) { + + depositAddress, err := b.requester("BTCEUR/money/new_deposit_address", nil) + + result := callModels.DepositAddress{} + + if err == nil { + err = json.Unmarshal(depositAddress.Data, &result) + } + + return result, err +} + +//GetLastDepositAddress | Retrieve the last created bitcoin deposit address +func (b Bl3p) GetLastDepositAddress() (callModels.DepositAddress, error) { + + depositAddress, err := b.requester("BTCEUR/money/deposit_address", nil) + + result := callModels.DepositAddress{} + + if err == nil { + err = json.Unmarshal(depositAddress.Data, &result) + } + + return result, err +} diff --git a/examples/go/callModels/callModels.go b/examples/go/callModels/callModels.go new file mode 100644 index 0000000..3883161 --- /dev/null +++ b/examples/go/callModels/callModels.go @@ -0,0 +1,107 @@ +package callModels + +import "encoding/json" + +//Bl3pResult | Main result struct +type Bl3pResult struct { + Result string `json:"result"` + Data json.RawMessage `json:"data"` +} + +//Fulldepth | FullDepth call struct +type Fulldepth struct { + Bids []OrderbookItem + Asks []OrderbookItem +} + +//OrderbookItem | Orderbook item struct +type OrderbookItem struct { + Count int `json:"count"` + PriceInt int64 `json:"price_int"` + AmountInt int64 `json:"amount_int"` +} + +//Orders | Order array struct +type Orders struct { + Order []Order `json:"orders"` +} + +//Trades | Trades array struct +type Trades struct { + Trade []Trade `json:"trades"` +} + +//Order | Order struct +type Order struct { + OrderID int64 `json:"order_id"` + Label string `json:"label"` + Currency string `json:"currency"` + Item string `json:"item"` + Type string `json:"type"` + Status string `json:"status"` + Date int64 `json:"date"` + Amount AmountObj `json:"amount"` + AmountExecuted AmountObj `json:"amount_executed"` + AmountFunds AmountObj `json:"amount_funds"` + AmountFundsExecuted AmountObj `json:"amount_funds_executed"` + Price AmountObj `json:"price"` + TotalAmount AmountObj `json:"total_amount"` + TotalSpent AmountObj `json:"total_spent"` + TotalFee AmountObj `json:"total_fee"` + AvgCost AmountObj `json:"avg_cost"` + Trades []Trade `json:"trades"` +} + +//Trade | Trade struct +type Trade struct { + TradeID int64 `json:"trade_id"` + Date int64 `json:"date"` + Currency string `json:"currency"` + Amount AmountObj `json:"amount"` + Price AmountObj `json:"price"` + AmountInt int64 `json:"amount_int"` + Item string `json:"item"` + PriceInt int64 `json:"price_int"` +} + +//AmountObj | AmountObj struct +type AmountObj struct { + ValueInt string `json:"value_int"` + DisplayShort string `json:"display_short"` + Display string `json:"display"` + Currency string `json:"currency"` + Value string `json:"value"` +} + +//DepositAddress | DepositAddress call struct +type DepositAddress struct { + Address string `json:"address"` +} + +//Transactions | WalletHistory call struct +type Transactions struct { + Page int64 `json:"page"` + Records int64 `json:"records"` + MaxPpage int64 `json:"max_page"` + Transactions []Transaction `json:"transactions"` +} + +//Transaction | Transaction struct +type Transaction struct { + TransactionID int64 `json:"transaction_id"` + Amount AmountObj `json:"amount"` + Date int64 `json:"date"` + DebitCredit string `json:"debit_credit"` + Price AmountObj `json:"price"` + OrderID int64 `json:"order_id"` + Type string `json:"type"` + Balance AmountObj `json:"balance"` + TradeID int64 `json:"trade_id"` + ContraAmount AmountObj `json:"contra_amount"` + Fee AmountObj `json:"fee"` +} + +//AddOrder | AddOrder call struct +type AddOrder struct { + OrderID int64 `json:"order_id"` +} diff --git a/examples/go/example/example.go b/examples/go/example/example.go new file mode 100644 index 0000000..bafdb6c --- /dev/null +++ b/examples/go/example/example.go @@ -0,0 +1,39 @@ +package main + +import ( + "fmt" + "time" + + bl3p "github.com/BitonicNL/bl3p-api/examples/go/bl3p" +) + +func main() { + + var bl3p = bl3p.NewBl3p( + "https://api.bl3p.eu", + "YOUR_PUBLIC_API_KEY", + "YOUR_PRIVATE_API_KEY", + "1", + ) + + depositAddress, err := bl3p.GetNewDepositAddress() + if err != nil { + panic(err) + } else { + fmt.Println(depositAddress) + } + + last1000trades, err := bl3p.FetchLast1000Trades(0) + if err != nil { + fmt.Println(err) + } else { + var dayvol float64 + for _, t := range last1000trades.Trade { + if int32(t.Date/1000) >= int32(time.Now().Unix()-86400) { + amountPrice := float64(t.AmountInt) / 1e8 + dayvol = dayvol + amountPrice + } + } + fmt.Printf("The volume of the last 24 hours is: %v \n", dayvol) + } +} diff --git a/examples/java/ComingSoon.md b/examples/java/ComingSoon.md new file mode 100644 index 0000000..e69de29 diff --git a/examples/nodejs/example.md b/examples/nodejs/example.md new file mode 100644 index 0000000..4755035 --- /dev/null +++ b/examples/nodejs/example.md @@ -0,0 +1,933 @@ +# BL3P NodeJS module + +## Table of contents + +1. Introduction + + 1. Installation + 2. Example code + +2. Basic functions + + 1. Create an order + 2. Cancel an order + 3. Get a specific order + 4. Get the whole orderbook + 5. Live trade stream + 6. Live orderbook stream + +3. Account info & functions + + 1. Get the transaction history + 2. Create a new deposit address + 3. Get the last deposit address + 4. Create a withdrawal + 5. Get account info & balance + 6. Get active orders + 7. Get the last 1000 trades after an specific trade + +4. Appendix - Error code + +--- + +## 1 - Introduction + +This document describes the usage of BL3P NodeJS module. +If you don't have an API-key you can signup and create one at https://bl3p.eu. + +## 1.1 - Installation + +The BL3P nodejs library is available within Node Package Manager. + +https://www.npmjs.com/package/bl3p + +To install, navigate into your nodejs project directory and run the defined command below in your command-line: +``` +npm install bl3p +``` + +## 1.2 - Example code + +```javascript +var bl3p = require('bl3p'); +var public_key = 'YOUR_PUBLIC_KEY'; +var private_key = 'YOUR_PRIVATE_KEY'; + +var bl3p_auth = new bl3p.Bl3pAuth(public_key, private_key); + +bl3p_auth.account_info(function(error, data){ + if(data){ + console.log(data); + }else{ + console.log(error); + } +}); + +bl3p.trades(function(error, data){ + if(data){ + console.log(data); + }else{ + console.log(error); + } +}); + +bl3p.orderbook(function(error, data){ + if(data){ + console.log(data); + }else{ + console.log(error); + } +}); +``` + +## 2 - Basic functions + +All the methods return a data and an error array in JSON format. +All methods also require a callback method. The callback method is always the last required parameter. +In case of an error, an error code will be retuned. The possible error codes are listed in the appendix. + +## 2.1 - Create an order + +### Method + +>```text +>add_order(amount, type, price, fee_currency, amount_funds, callback) +>``` + +### Parameters +>`type` string +>``` +>'bid', 'ask' +>``` +>___ +>`amount` int +>``` +>Amount BTC, amount LTC (*1e8) +>``` +>The field described above is optional +>___ +>`price` int +>``` +>Limit price in EUR (*1e5) +>``` +>The field described above is optional +>___ +>`amount_funds` int +>``` +>Maximal EUR amount to spend (*1e5) +>``` +>The field described above is optional +>___ +>`fee_currency` string +>``` +>Currency the fee is accounted in. Can be: 'EUR' or 'BTC' +>``` +>___ + +### Response +>`order_id` int +>``` +>The id of the order. +>``` + +## 2.2 - Cancel an order + +### Method + +>```text +>cancel_order(order_id, callback) +>``` + +### Parameters +>`order_id` int +>``` +>The id of the order that you wish to cancel. +>``` + +### Response +>``` +>For this call there is no specific result returned other then +>the result of the call which contains: 'success' or 'failed' and a optional error array. +>``` + + +## 2.3 - Get a specific order +### Method +>```text +>order_info(order_id, callback) +>``` + +### Parameters +>`order_id` int +>``` +>The id of the order that you wish to retrieve. +>``` + +### Response +>`order_id` int +>``` +>Id of the order. +>``` +>___ +>`label` string +>``` +>API-key label +>``` +>___ +>`currency` string +>``` +>Currency of the order. (Is now by default 'EUR') +>``` +>___ +>`item` string +>``` +>The item that will be traded for `currency`. (Can be: 'BTC' or 'LTC') +>``` +>___ +>`type` string +>``` +>Type of order. (Can be: 'bid', 'ask') +>``` +>___ +>`amount` amountObj +>``` +>Total order amount of BTC or LTC. +>``` +>The field described above is optional +>___ +>`price` amountObj +>``` +>Order limit price. +>``` +>The field described above is optional +>___ +>`status` string +>``` +>Status of the order. (Can be: 'pending’, ‘open’, ‘closed’, ‘cancelled’) +>``` +>___ +>`date` timestamp +>``` +>The time the order got added. +>``` +>___ +>`total_amount` amountObj +>``` +>Total amount of the trades that got executed. (Can be: BTC or LTC). +>``` +>___ +>`total_spent` amountObj +>``` +>Total amount in EUR of the trades that got executed. +>``` +>___ +>`total_fee` amountObj +>``` +>Total fee incurred in BTC or LTC. +>``` +>___ +>`avg_cost` amountObj +>``` +>Average cost of executed trades. +>``` +>The field described above is optional +>___ +>`trades` array +>``` +>Array of trades executed for the regarding order. +>``` +>**Each array item of 'trade' will contain:** +>>`amount` amountObj +>>``` +>>BTC or LTC amount. +>>``` +>>___ +>>`currency` string +>>``` +>>Currency of the regarding trade. +>>``` +>>___ +>>`date` timestamp +>>``` +>>The time of the trade execution. +>>``` +>>___ +>>`item` string +>>``` +>>'BTC' or 'LTC' +>>``` +>>___ +>>`price` amountObj +>>``` +>>Price of the executed trade in EUR. +>>``` +>>___ +>>`trade_id` int +>>``` +>>Id of trade. +>>``` +>> +>___ + +## 2.4 - Get the whole orderbook + +### Method + +>```text +>full_depth(callback) +>``` + +### Parameters + +>``` +>There are no specific parameters required for this call. +>``` + +### Response +>`asks` array +>``` +>Array of asks that are in the orderbook. +>``` +>**Each array item of 'asks' will contain:** +>> +>>`amount_int` int +>>``` +>>Amount BTC, amount LTC (*1e8) +>>``` +>>___ +>>`price_int` int +>>``` +>>Limit price in EUR (*1e5) +>>``` +>>___ +>>`count` int +>>``` +>>Count of orders at this price. +>>``` +>> +>___ +>> +>`bids` array +>``` +>Array of bids that are in the orderbook. +>``` +>**Each array item of 'bids' will contain:** +>> +>>`amount_int` int +>>``` +>>Amount BTC, amount LTC (*1e8) +>>``` +>>___ +>>`price_int` int +>>``` +>>Limit price in EUR (*1e5) +>>``` +>>___ +>>`count` int +>>``` +>>Count of orders at this price. +>>``` +>> +>___ + +## 2.5 - Live trade stream + +### Method + +>```text +>trades(callback) +>``` + +### Response + +>`amount_int` int +>``` +>Traded BTC Amount or traded LTC amount (*1e8) +>``` +>___ +>`price_int` int +>``` +>Trade price in EUR (*1e5) +>``` +>___ +>`date` timestamp +>``` +>The time of the trade execution. +>``` +___ + +## 2.6 - Live orderbook stream + +### Method + +>```text +>orderbook(callback) +>``` + +### Response +>`asks` array +>``` +>Array of asks that are in the orderbook. +>``` +>**Each array item of 'asks' will contain:** +> +>>`amount_int` int +>>``` +>>Amount BTC, amount LTC (*1e8) +>>``` +>>___ +>>`price_int` int +>>``` +>>Limit price in EUR (*1e5) +>>``` +>>___ +>>`count` int +>>``` +>>Count of orders at this price. +>>``` +>> +>___ +> +>`bids` array +>``` +>Array of bids that are in the orderbook. +>``` +>**Each array item of 'bids' will contain:** +>> +>>`amount_int` int +>>``` +>>Amount BTC, amount LTC (*1e8) +>>``` +>>___ +>>`price_int` int +>>``` +>>Limit price in EUR (*1e5) +>>``` +>>___ +>>`count` int +>>``` +>>Count of orders at this price. +>>``` +>> +>___ + +## 3 - Account info & functions + +## 3.1 - Get your transaction history + +### Method + +>```text +>wallet_history(currency, page, date_from, date_to, type, recs_per_page, callback) +>``` + +### Parameters + +>`currency` string +>``` +>Currency of the wallet. (Can be: 'BTC', 'EUR' or 'LTC') +>``` +>___ +>`page` int +>``` +>Page number. (1 = most recent transactions) +>``` +>The field described above is optional +>___ +>`date_from` timestamp +>``` +>Filter the result by an Unix-timestamp. Transactions before this date will not be returned. +>``` +>The field described above is optional +>___ +>`date_to` timestamp +>``` +>Filter the result by an Unix-timestamp. Transactions after this date will not be returned. +>``` +>The field described above is optional +>___ +>`type` string +>``` +>Filter the result by type. (Can be: ‘trade’, ‘fee’, ‘deposit’, ‘withdraw’) +>``` +>The field described above is optional +>___ +>`recs_per_page` int +>``` +>Number of records per page. +>``` +>The field described above is optional +>___ + +### Response + +>`page` int +>``` +>Current page number. +>``` +>___ +>`records` int +>``` +>Count of records in the result set. +>``` +>___ +>`max_page` int +>``` +>Number of last page. +>``` +>___ +>`transactions` array +>``` +>Array of transactions. +>``` +>**Each array item of 'transactions' will contain:** +>>`transaction_id` int +>>``` +>>Id of the transaction. +>>``` +>>`amount` amountObj +>>``` +>>BTC or LTC amount. +>>``` +>>___ +>>`date` timestamp +>>``` +>>Time when the regarding transaction took place. +>>``` +>>___ +>>`debit_credit` string +>>``` +>>Type of booking. (Can be: 'debit' or 'credit') +>>``` +>>___ +>>`price` amountObj +>>``` +>>Price of the executed trade. +>>``` +>>The field described above is optional +>>___ +>>`order_id` int +>>``` +>>Id of the order. +>>``` +>>The field described above is optional +>>___ +>>`type` string +>>``` +>>Type of transaction (Can be: 'trade’, ‘fee’, ‘deposit’, ‘withdraw’) +>>``` +>>___ +>>`balance` amountObj +>>``` +>>Balance of the user his account (for the regarding currency) after the transaction. +>>``` +>>___ +>>`trade_id` int +>>``` +>>Id of the trade. +>>``` +>>The field described above is optional +>>___ +>>`contra_amount` amountObj +>>``` +>>Contra amount of the trade. +>>``` +>>The field described above is optional +>>___ +>>`fee` amountObj +>>``` +>>Fee incurred by the regarding trade +>>``` +>> +>___ + +## 3.2 - Create a new deposit address + +### Method + +>```text +>new_deposit_address(callback) +>``` + +### Parameters + +>``` +>There are no specific parameters required for this call. +>``` + +### Response + +>`address` string +>``` +>Deposit address for the market leading currency +>``` + +## 3.3 - Get the last deposit address + +### Method + +>```text +>last_deposit_address +>``` + +### Parameters + +>``` +>There are no specific parameters required for this call. +>``` + +### Response + +>`address` string +>``` +>Deposit address for the market leading currency +>``` + +## 3.4 - Create a withdrawal + +### Method + +>```text +>withdraw(type, amount, account, callback) +>``` + +### Parameters +>`account` string +>``` +>IBAN account-id (that is available within the regarding BL3P account) or a Bitcoin address +>``` +>**Note: The kind of account value you need to specify depends on the 'type' parameter described below.** +>___ +>`type` string +>``` +>Can be 'EUR' or 'BTC' +>``` +>___ +>`amount` int +>``` +>Satoshis or 0,00001 EUR +>``` + +### Response + +>`id` int +>``` +>Id of the withdrawal +>``` + +## 3.5 - Get account info & balance +### Method + +>```text +>account_info(callback) +>``` + +### Parameters + +>``` +>There are no specific parameters required for this call. +>``` + +### Response + +>`user_id` int +>``` +>Id of the user. +>``` +>___ +>`trade_fee` float +>``` +>Percentage fee for the user +>``` +>___ +>`wallets` array +>``` +>Array of wallets. +>``` +>**Each array item of 'wallets' will contain:** +>> +>>`balance` amountObj +>>``` +>>Balance in this wallet +>>``` +>>___ +>>`available` amountObj +>>``` +>>Available in this wallet. +>>``` +>> +>___ + +## 3.6 Get active orders +### Method +>```text +>active_orders(callback) +>``` + +### Parameters + +>``` +>There are no specific parameters required for this call. +>``` + +### Response + +>`orders` array +>``` +>Array of active orders. +>``` +>**Each array item of 'orders' will contain:** +> +>>`order_id` int +>>``` +>>Id of the order. +>>``` +>>___ +>>`label` string +>>``` +>>API-key label +>>``` +>>___ +>>`currency` string +>>``` +>>Currency of the order. (Is now by default 'EUR') +>>``` +>>___ +>>`item` string +>>``` +>>The item that will be traded for `currency`. (Can be: 'BTC' or 'LTC') +>>``` +>>___ +>>`type` string +>>``` +>>Type of order. (Can be: 'bid', 'ask') +>>``` +>>___ +>>`status` string +>>``` +>>Status of the order. (Can be: 'pending’, ‘open’, ‘closed’, ‘cancelled’) +>>``` +>>___ +>>`date` timestamp +>>``` +>>The time the order got added. +>>``` +>>___ +>>`amount` amountObj +>>``` +>>Total order amount of BTC or LTC. +>>``` +>>The field described above is optional +>>___ +>>`amount_funds_executed` amountObj +>>``` +>>Amount in funds that is executed. +>>``` +>>___ +>>`amount_executed` amountObj +>>``` +>>Amount that is executed. +>>``` +>>___ +>>`price` amountObj +>>``` +>>Order limit price. +>>``` +>>The field described above is optional +>>___ +>>`amount_funds` amountObj +>>``` +>>Maximal EUR amount to spend (*1e5) +>>``` +>>The field described above is optional +>> +>___ + +## 3.7 - Get the last 1000 trades after an specific trade + +### Method + +>```text +>last_1000_trades(trade_id, callback) +>``` + +### Parameters + +>`trade_id` int +>``` +>Id of the trade +>``` +>The field described above is optional, if this field isn't specified, this call will return the last 1000 trades. +> + +### Response + +>`trades` array +>``` +>Array of trades. +>``` +>**Each array item of 'trades' will contain:** +>>`trade_id` int +>>``` +>>Id of the trade. +>>``` +>>___ +>>`date` timestamp +>>``` +>>The time of the trade execution. +>>``` +>>___ +>>`amount_int` int +>>``` +>>Amount traded. (*1e8) +>>``` +>>___ +>>`price_int` int +>>``` +>>Price of the traded item in EUR. (*1e5) +>>``` +>> +>___ + +## 4 - Appendix - Error codes + +The API can respond to invalid calls with the following error messages: + +`AMOUNT_FUNDS_LESS_THAN_MINIMUM` +``` +Order amount (amount_funds) smaller than the minimum. +``` +___ + +`AMOUNT_LESS_THAN_MINIMUM` +``` +Order amount is smaller than the minimum +``` +___ + +`INSUFFICIENT_FUNDS` +``` +Not enough money on account for this order. +``` +___ + +`INVALID_AMOUNT` +``` +Invalid field 'amount_int'. +``` +___ + +`INVALID_AMOUNT_FUNDS` +``` +Invalid field 'amount_funds_int'. +``` +___ + +`INVALID_FEE_CURRENCY` +``` +Invalid field 'fee_currency'. +``` +___ + +`INVALID_LIMIT_ORDER` +``` +Limitorders can't have both an 'amount' and an 'amount_funds'. +``` +___ + +`INVALID_PRICE` +``` +Invalid field 'price_int'. +``` +___ + +`INVALID_TYPE` +``` +Invalid field type (‘bid’ or ‘ask’). +``` +___ + +`KEY_MISSING` +``` +The Rest-Key header misses. +``` +___ + +`LIMIT_REACHED` +``` +User has done to much calls. +``` +___ + +`MARKETPLACE_INACCESSIBLE` +``` +Market (temporarily) closed. +``` +___ + +`MARKETPLACE_NOT_ACCEPTING_ORDERS` +``` +Market does (temporarily) not accepts orders. +``` +___ + +`MISSING_AMOUNT` +``` +The field 'amount' or 'amout_funds' is missing with this order. +``` +___ + +`MISSING_FIELD` +``` +A required field at this call is missing. +``` +___ + +`NOT_AUTHENTICATED` +``` +Signature-key-combination is invalid. +``` +___ + +`SIGN_MISSING` +``` +The Rest-Sign header misses. +``` +___ + +`UNKNOWN_ACCOUNT` +``` +User has no account for given currency (SystemServer) +``` +___ + +`UNKNOWN_CURRENCY` +``` +The requested currency doesn't exist. +``` +___ + +`UNKNOWN_ERROR` +``` +An unknown server error occured. +``` +___ + +`UNKNOWN_MARKETPLACE` +``` +The requested market doesn't exist. +``` +___ + +`UNKNOWN_ORDER` +``` +The order to cancel or fetch doesn't exist +``` +___ + + +`UNKNOWN_PATH` +``` +Requested path and/or call doesn't exist. +``` +___ diff --git a/examples/php/example.php b/examples/php/example.php new file mode 100644 index 0000000..1d524b0 --- /dev/null +++ b/examples/php/example.php @@ -0,0 +1,280 @@ + + */ +class Bl3pApi { + + private $pubkey; + private $privkey; + private $url; + + /** + * Set the url to call, the public key and the private key + * @method __construct + * @param string $url Url to call (https://api.bl3p.eu) + * @param string $pubkey Your Public API key + * @param string $privkey Your Private API key + */ + function __construct($url, $pubkey, $privkey) { + $this->url = $url; + $this->pubkey = $pubkey; + $this->privkey = $privkey; + } + + /** + * To make a call to BL3P API + * @method apiCall + * @param string $path path to call + * @param array $params parameters to add to the call + * @return array result of call + */ + public function apiCall($path, $params=array()) { + + // generate a nonce as microtime, with as-string handling to avoid problems with 32bits systems + $mt = explode(' ', microtime()); + $params['nonce'] = $mt[1].substr($mt[0], 2, 6); + + // generate the POST data string + $post_data = http_build_query($params, '', '&'); + $body = $path . chr(0). $post_data; + + //build signature for Rest-Sign + $sign = base64_encode(hash_hmac('sha512', $body, base64_decode($this->privkey), true)); + + //combine the url and the desired path + $fullpath = $this->url . $path; + + //set headers + $headers = array( + 'Rest-Key: '.$this->pubkey, + 'Rest-Sign: '. $sign, + ); + + //build curl call + $ch = curl_init(); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; BL3P PHP client; '.php_uname('s').'; PHP/'.phpversion().')'); + curl_setopt($ch, CURLOPT_URL, $fullpath); + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_SSLVERSION, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + + //execute curl request + $res = curl_exec($ch); + + //throw exception with additional information when curl request returns false + if ($res === false) { + throw new Exception("API request failed: Could not get reply from API: ".curl_error($ch)); + } + + //close curl connection + curl_close ($ch); + + //convert json into an array + $result = json_decode($res, true); + + //check json convert result and throw an exception if invalid + if (!$result) { + throw new Exception("API request failed: Invalid JSON-data received: ".substr($res,0,100)); + } + + if(!array_key_exists('result', $result)) { + //note that data now is the first element in the array. + $result['data'] = $result; + $result['result'] = 'success'; + + //remove all the keys in $result except 'result' and 'data' + return array_intersect_key($result, array_flip(['result', 'data'])); + } + + //check returned result of call, if not success then throw an exception with additional information + if ($result['result'] !== 'success') { + if (!isset($result['data']['code']) || !isset($result['data']['message'])) + throw new Exception(sprintf('Received unsuccessful state, and additionally a malformed response: %s', var_export($result['data'], true))); + + throw new Exception(sprintf("API request unsuccessful: [%s] %s", $result['data']['code'], $result['data']['message'])); + } + + return $result; + } +} + +/** + * =================================================== + * Code to make calls with help of the Bl3pApi class + * =================================================== + **/ + +$url = "https://api.bl3p.eu/1/"; +$pubkey = "YOUR_PUBLIC_API_KEY"; +$privkey = "YOUR_PRIVATE_API_KEY"; + +//Init Bl3pAPi class +$api = new Bl3pApi($url, $pubkey, $privkey); + +try { + + //Add an buy order for 0.01 @400 euro + + $result = addOrder('bid', 1000000, 40000000); + + echo '
'.var_export($result, true) . '
'; +} catch (Exception $ex) { + echo '
'.var_export($ex, true) . '
'; +} + +/** + * Add order to your account. + * @method addOrder + * @param string $order_type 'bid' or 'ask' + * @param int $order_amount Amount to order *1e8 + * @param int $order_price Price of order *1e5 + * @return array Result of the add order call + */ + +function addOrder($order_type, $order_amount, $order_price) { + + global $api; + + $params = array( + 'type' => $order_type, + 'amount_int' => $order_amount, + 'price_int' => $order_price, + 'fee_currency' => 'BTC' + ); + + $result = $api->apiCall("BTCEUR/money/order/add", $params); + + return $result; +} + +/** + * Cancel a specific order. + * @method cancelOrder + * @param int $order_id Id of the order + * @return array Direct resulf of the '/money/order/cancel' call + */ + +function cancelOrder($order_id) { + + global $api; + + $params = array( + 'order_id' => $order_id + ); + + return $api->apiCall("BTCEUR/money/order/cancel", $params); +} + +/** + * Fetch information about an specific order + * @method orderInfo + * @param int $order_id Id of the order + * @return array Direct resulf of the '/money/order/result' call + */ + +function orderInfo($order_id) { + + global $api; + + $params = array( + 'order_id' => $order_id + ); + + return $api->apiCall("BTCEUR/money/order/result", $params); +} + +/** + * Fetch complete orderbook + * @method fullDepth + * @return array Direct resulf of the '/money/depth/full' call + */ + +function fullDepth() { + + global $api; + + return $api->apiCall("BTCEUR/money/depth/full"); +} + +/** + * Get new deposit address. + * @method getNewDepositAddress + * @return array new deposit address + */ + +function getNewDepositAddress() { + + global $api; + + return $api->apiCall("BTCEUR/money/new_deposit_address"); +} + +/** + * Get the most recent generated deposit address + * @method getLastDepositAddress + * @return array most recent generated deposit address + */ + +function getLastDepositAddress() { + + global $api; + + return $api->apiCall("BTCEUR/money/deposit_address"); +} + +/** + * Get the last 1000 trades that where executed before an specific trade_id + * @method fetchTrades + * @param int $trade_id id of the trade + * @return array array of last 1000 executed trades. + */ + +function fetchLast1000Trades($trade_id) { + + global $api; + + $params = array( + 'trade_id' => $trade_id + ); + + return $api->apiCall("BTCEUR/money/trades/fetch", $params); +} + +/** + * Get the transaction history + * @method walletHistory + * @param string $currency type of currency + * @return array array of transactions + */ + +function walletHistory($currency) { + + global $api; + + $params = array( + 'currency' => $currency, + 'recs_per_page' => 25 + ); + + return $api->apiCall("GENMKT/money/wallet/history", $params); +} + + +/** + * Get all open orders. + * @method getAllActiveOrders + * @return array array of open orders + */ + +function getAllActiveOrders(){ + + global $api; + + return $api->apiCall("BTCEUR/money/orders"); +} diff --git a/examples/python/example-py.txt b/examples/python/example-py.txt new file mode 100644 index 0000000..1fd2089 --- /dev/null +++ b/examples/python/example-py.txt @@ -0,0 +1,100 @@ +Examples +======== + +invalid public/secret key: +------------------------- +{ + "data": { + "code": "KEY_MISSING", + "message": "Rest-Key missing" + }, + "result": "error" +} + + +invalid market: +-------------- +{ + "data": { + "code": "UNKNOWN_MARKETPLACE", + "message": "Unknown marketplace" + }, + "result": "error" +} + + +price too low: +------------- +{ + "data": { + "code": "PRICE_LESS_THAN_MINIMUM", + "message": "Price '1' less than marketplace minimum '1000'" + }, + "result": "error" +} + + +insufficient funds: +------------------ +{ + "data": { + "code": "INSUFFICIENT_FUNDS", + "message": "Insufficient available funds, available = 0 order value = 10000000" + }, + "result": "error" +} + + +market unavailable: +------------------ +{ + "data": { + "code": "ERR_TEMPORARILY_UNAVAILABLE", + "message": "Error creating address" + }, + "result": "error" +} + + +walletHistory(): +------------- +{ + "data": { + "max_page": 1, + "page": 1, + "records": 1, + "transactions": [ + { + "amount": { + "currency": "BTC", + "display": "0.01000000 BTC", + "display_short": "0.01 BTC", + "value": "0.01000000", + "value_int": "1000000" + }, + "balance": { + "currency": "BTC", + "display": "0.01000000 BTC", + "display_short": "0.01 BTC", + "value": "0.01000000", + "value_int": "1000000" + }, + "date": 1450353480, + "debit_credit": "credit", + "transaction_id": 575126, + "type": "deposit" + } + ] + }, + "result": "success" +} + + +getNewDepositAddress(): +-------------------- +{ + "data": { + "address": "**********************************" + }, + "result": "success" +} diff --git a/examples/python/example.cfg b/examples/python/example.cfg new file mode 100644 index 0000000..3e98153 --- /dev/null +++ b/examples/python/example.cfg @@ -0,0 +1,3 @@ +[bl3p] +public_key= +secret_key= diff --git a/examples/python/example.py b/examples/python/example.py new file mode 100755 index 0000000..f268cb7 --- /dev/null +++ b/examples/python/example.py @@ -0,0 +1,208 @@ +#! /usr/bin/python + +# this code was written by folkert@vanheusden.com +# it has been released under AGPL v3.0 + +# it requires 'pycurl' +# in debian this can be found in the 'python-pycurl' package + +import base64 +import ConfigParser +import hashlib +import hmac +import json +import pycurl +import sys +import urllib + +try: + from io import BytesIO +except ImportError: + from StringIO import StringIO as BytesIO + +from datetime import datetime +from time import mktime + +class Bl3pApi: + url = None + pubKey = None + secKey = None + verbose = False + + def __init__(self, u, pk, sk): + self.url = u + self.pubKey = pk + self.secKey = sk + + def setVerbose(self, v): + self.verbose = v + + def apiCall(self, path, params): + dt = datetime.utcnow() + us = mktime(dt.timetuple()) * 1000 * 1000 + dt.microsecond + nonce = '%d' % us + + # generate the POST data string + post_data = urllib.urlencode(params) + + body = '%s%c%s' % (path, 0x00, post_data) + + privkey_bin = base64.b64decode(self.secKey) + + signature_bin = hmac.new(privkey_bin, body, hashlib.sha512).digest() + + signature = base64.b64encode(signature_bin) + + fullpath = '%s%s' % (self.url, path) + + headers = [ 'Rest-Key: %s' % self.pubKey, 'Rest-Sign: %s' % signature ] + + buffer = BytesIO() + + c = pycurl.Curl() + c.setopt(c.USERAGENT, 'Mozilla/4.0 (compatible; BL3P Python client written by folkert@vanheusden.com; 0.1)'); + c.setopt(c.WRITEFUNCTION, buffer.write) + c.setopt(c.URL, fullpath); + c.setopt(c.POST, 1); + c.setopt(c.POSTFIELDS, post_data); + c.setopt(c.HTTPHEADER, headers); + c.setopt(c.SSLVERSION, 1); + c.setopt(c.SSL_VERIFYPEER, True); + c.setopt(c.SSL_VERIFYHOST, 2); + c.setopt(c.CONNECTTIMEOUT, 5); + c.setopt(c.TIMEOUT, 10); + + if self.verbose: + c.setopt(c.VERBOSE, 1) + else: + c.setopt(c.VERBOSE, 0) + + c.perform() + + response_code = c.getinfo(c.RESPONSE_CODE) + if response_code != 200: + raise Exception('unexpected response code: %d' % response_code) + + c.close() + + return json.loads(buffer.getvalue()) + + # multiply the btc value (e.g 1.3BTC) with this and round-up/down + def getBtcMultiplier(self): + return 100000000 + + def getEurMutiplier(self): + return 100000 + + # Add order to your account. + # @method addOrder + # @param market 'EUR' + # @param order_type 'bid' or 'ask' + # bid: used if you want to buy bitcoins + # ask: if you want to sell bitcoins + # @param order_amount Amount to order *1e8 (so 1 bitcoin is 100000000) + # @param order_price Price of order *1e5 (1 euro is 100000) + # @return Result of the add order call + def addOrder(self, market, order_type, order_amount, order_price): + + params = { + 'type' : order_type, + 'amount_int' : order_amount, + 'price_int' : order_price, + 'fee_currency' : 'BTC' + } + + return self.apiCall('%sEUR/money/order/add' % market, params) + + # Cancel a specific order. + # @method cancelOrder + # @param market 'EUR' + # @param order_id Id of the order + # @return Direct resulf of the '/money/order/cancel' call + def cancelOrder(self, market, order_id): + params = { 'order_id' : order_id } + + return self.apiCall("%sEUR/money/order/cancel" % market, params) + + # Fetch information about an specific order + # @method orderInfo + # @param market 'EUR' + # @param order_id Id of the order + # @return Direct resulf of the '/money/order/result' call + def orderInfo(self, market, order_id): + params = { 'order_id' : order_id } + + return self.apiCall("%sEUR/money/order/result" % market, params) + + # Fetch complete orderbook + # @method fullDepth + # @param market 'EUR' + # @return Direct resulf of the '/money/depth/full' call + def fullDepth(self, market): + return self.apiCall("%sEUR/money/depth/full" % market, { }) + + # Get new deposit address. + # @method getNewDepositAddress + # @param market 'EUR' + # @return new deposit address + def getNewDepositAddress(self, market): + return self.apiCall("%sEUR/money/new_deposit_address" % market, { }) + + # Get the most recent generated deposit address + # @method getLastDepositAddress + # @param market 'EUR' + # @return most recent generated deposit address + def getLastDepositAddress(self, market): + return self.apiCall("%sEUR/money/deposit_address" % market, { }) + + # Get the last 1000 trades that where executed before an specific trade_id + # @method fetchTrades + # @param market 'EUR' + # @param trade_id id of the trade + # @return array of last 1000 executed trades. + def fetchLast1000Trades(self, market, trade_id): + params = { 'trade_id' : trade_id } + + return self.apiCall("%sEUR/money/trades/fetch" % market, params) + + # Get the transaction history + # @method walletHistory + # @param currency currency which currency + # @param n how many to retrieve + # @return array json structure with the transaction history + def walletHistory(self, currency, n): + params = { 'currency' : currency, 'recs_per_page' : n } + + return self.apiCall('GENMKT/money/wallet/history', params) + + # Get all open orders. + # @method getAllActiveOrders + # @param market 'EUR' + # @return array of open orders + def getAllActiveOrders(self, market): + return self.apiCall("%sEUR/money/orders" % market, { }); + + # Get the balances + # @method getBalances + # @return array json structure with the wallet balances + def getBalances(self): + params = { } + return self.apiCall('GENMKT/money/info', params) + +def d(j): + print json.dumps(j, sort_keys=True, indent=4, separators=(',', ': ')) + +# example: +config = ConfigParser.RawConfigParser() + +if len(sys.argv) == 2: + config.read(sys.argv[1]) +else: + config.read('example.cfg') + +public_key = config.get('bl3p', 'public_key') # ........-....-....-....-............ +secret_key = config.get('bl3p', 'secret_key') # (long string with a-z/A-Z/0-9 and =) + +b = Bl3pApi('https://api.bl3p.eu/1/', public_key, secret_key) + +d(b.walletHistory('BTC', 10)) From 569c8cc74db40ffbb733da1877fb5f1f4c30e27a Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Thu, 12 Apr 2018 19:24:04 +0000 Subject: [PATCH 11/12] modified python 3 doc and setup.py --- README.md | 3 +++ examples/python3/README.md | 2 +- examples/python3/setup.py | 9 +++------ 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 67b3d02..67f9d99 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,6 @@ You can find each client reference implementation in: * [NodeJs](examples/nodejs/) * [Java](examples/java/) * [Go](examples/go/) +* [Python 2](examples/python/) +* [Python 3](examples/python3/) [doc](examples/python3/README.md) + diff --git a/examples/python3/README.md b/examples/python3/README.md index 2ecb937..f546df6 100644 --- a/examples/python3/README.md +++ b/examples/python3/README.md @@ -4,7 +4,7 @@ Unofficial Python 3 Bl3p client exchange api ## Install ``` $ git clone https://github.com/joosthoeks/bl3p-api.git -$ cd bl3p-api +$ cd bl3p-api/examples/python3 $ [sudo] pip3 install -e . ``` diff --git a/examples/python3/setup.py b/examples/python3/setup.py index a338e19..4630b64 100644 --- a/examples/python3/setup.py +++ b/examples/python3/setup.py @@ -1,19 +1,16 @@ -from setuptools import setup +from setuptools import setup, find_packages setup( name='bl3p', - version='20180112.0', + version='20180412.0', description='BL3P.eu Python 3 exchange API', keywords='bl3p python3 exchange api', url='https://github.com/joosthoeks/bl3p-api', author='Joost Hoeks', author_email='joosthoeks@gmail.com', license='GNU', - packages=[ - 'bl3p', - 'bl3p.api', - ], + packages=find_packages(), install_requires=[ # 'numpy', # 'pandas', From e64c1df4a5b1ac6ce8a76ba74ba3db998272da4b Mon Sep 17 00:00:00 2001 From: joosthoeks Date: Thu, 12 Apr 2018 20:50:57 +0000 Subject: [PATCH 12/12] changed pycurl to requests --- examples/python3/bl3p/api/api.py | 51 +++++++------------------------- 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/examples/python3/bl3p/api/api.py b/examples/python3/bl3p/api/api.py index 505bb77..4f3f450 100755 --- a/examples/python3/bl3p/api/api.py +++ b/examples/python3/bl3p/api/api.py @@ -1,22 +1,14 @@ # Unofficial Python 3 Bl3p client exchange api -# modified for Python 3 by Joost Hoeks (github.com/joosthoeks) - import base64 import hashlib import hmac import json -import pycurl +import requests import urllib.parse -try: - from io import BytesIO -except ImportError: - from StringIO import StringIO as BytesIO - - class Bl3pApi: url = None pubKey = None @@ -28,54 +20,31 @@ def __init__(self, u, pk, sk): self.pubKey = pk self.secKey = sk - def setVerbose(self, v): - self.verbose = v - def apiCall(self, path, params): post_data = urllib.parse.urlencode(params) - body = '%s%c%s' % (path, 0x00, post_data) - encoded_body = body.encode() + body = ('%s%c%s' % (path, 0x00, post_data)).encode() privkey_bin = base64.b64decode(self.secKey) - signature_bin = hmac.new(privkey_bin, encoded_body, hashlib.sha512) + signature_bin = hmac.new(privkey_bin, body, hashlib.sha512) signature = base64.b64encode(signature_bin.digest()).decode() fullpath = '%s%s' % (self.url, path) - headers = [ 'Rest-Key: %s' % self.pubKey, 'Rest-Sign: %s' % signature ] + headers = { + 'Rest-Key': self.pubKey, + 'Rest-Sign': signature + } - buffer = BytesIO() + r = requests.get(fullpath, headers=headers, data=post_data) - c = pycurl.Curl() - c.setopt(c.USERAGENT, 'Mozilla/4.0 (compatible; Unofficial Python 3 Bl3p client exchange api; 0.1)'); - c.setopt(c.WRITEFUNCTION, buffer.write) - c.setopt(c.URL, fullpath); - c.setopt(c.POST, 1); - c.setopt(c.POSTFIELDS, post_data); - c.setopt(c.HTTPHEADER, headers); - c.setopt(c.SSLVERSION, 1); - c.setopt(c.SSL_VERIFYPEER, True); - c.setopt(c.SSL_VERIFYHOST, 2); - c.setopt(c.CONNECTTIMEOUT, 5); - c.setopt(c.TIMEOUT, 10); - - if self.verbose: - c.setopt(c.VERBOSE, 1) - else: - c.setopt(c.VERBOSE, 0) - - c.perform() - - response_code = c.getinfo(c.RESPONSE_CODE) + response_code = r.status_code if response_code != 200: raise Exception('unexpected response code: %d' % response_code) - c.close() - - return json.loads(buffer.getvalue().decode()) + return r.json() # multiply the btc value (e.g 1.3BTC) with this and round-up/down def getBtcMultiplier(self):