Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Robert Myers
committed
Nov 22, 2013
1 parent
f05740d
commit fe88c1a
Showing
4 changed files
with
257 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
kraken-api is released under the MIT license. | ||
|
||
>Permission is hereby granted, free of charge, to any person obtaining | ||
>a copy of this software and associated documentation files (the | ||
>"Software"), to deal in the Software without restriction, including | ||
>without limitation the rights to use, copy, modify, merge, publish, | ||
>distribute, sublicense, and/or sell copies of the Software, and to | ||
>permit persons to whom the Software is furnished to do so, subject to | ||
>the following conditions: | ||
> | ||
>The above copyright notice and this permission notice shall be | ||
>included in all copies or substantial portions of the Software. | ||
> | ||
>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
>EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
>MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
>NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
>LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
>OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
>WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
var request = require('request'); | ||
var crypto = require('crypto'); | ||
var querystring = require('querystring'); | ||
var microtime = require('microtime'); | ||
|
||
/** | ||
* KrakenClient connects to the Kraken.com API | ||
* @param {String} key API Key | ||
* @param {String} secret API Secret | ||
* @param {String} [otp] Two-factor password (optional) (also, doesn't work) | ||
*/ | ||
function KrakenClient = function(key, secret, otp) { | ||
var self = this; | ||
|
||
var config = { | ||
url: 'https://api.kraken.com', | ||
version: '0', | ||
key: key, | ||
secret: secret, | ||
otp: otp | ||
}; | ||
|
||
/** | ||
* This method makes a public or private API request. | ||
* @param {String} method The API method (public or private) | ||
* @param {Object} params Arguments to pass to the api call | ||
* @param {Function} callback A callback function to be executed when the request is complete | ||
* @return {Object} The request object | ||
*/ | ||
function api(method, params, callback) { | ||
var methods = { | ||
public: ['Time', 'Assets', 'AssetPairs', 'Ticker', 'Depth', 'Trades', 'Spread'], | ||
private: ['Balance', 'TradeBalance', 'OpenOrders', 'ClosedOrders', 'QueryOrders', 'TradesHistory', 'QueryTrades', 'OpenPositions', 'Ledgers', 'QueryLedgers', 'TradeVolume', 'AddOrder', 'CancelOrder'] | ||
}; | ||
if(methods.public.indexOf(method) !== -1) { | ||
return publicMethod(method, params, callback); | ||
} | ||
else if(methods.private.indexOf(method) !== -1) { | ||
return privateMethod(method, params, callback); | ||
} | ||
else { | ||
throw new Error(method + ' is not a valid API method.'); | ||
} | ||
} | ||
|
||
/** | ||
* This method makes a public API request. | ||
* @param {String} method The API method (public or private) | ||
* @param {Object} params Arguments to pass to the api call | ||
* @param {Function} callback A callback function to be executed when the request is complete | ||
* @return {Object} The request object | ||
*/ | ||
function publicMethod(method, params, callback) { | ||
params = params || {}; | ||
|
||
var path = '/' + config.version + '/public/' + method; | ||
var url = config.url + path; | ||
|
||
return rawRequest(url, {}, params, callback); | ||
} | ||
|
||
/** | ||
* This method makes a private API request. | ||
* @param {String} method The API method (public or private) | ||
* @param {Object} params Arguments to pass to the api call | ||
* @param {Function} callback A callback function to be executed when the request is complete | ||
* @return {Object} The request object | ||
*/ | ||
function privateMethod(method, params, callback) { | ||
params = params || {}; | ||
|
||
var path = '/' + config.version + '/private/' + method; | ||
var url = config.url + path; | ||
|
||
params.nonce = microtime.now(); | ||
|
||
// Two-factor authentication doesn't seem to work for API requests. | ||
// I need to contact Kraken support about this. | ||
// if(config.otp !== undefined) { | ||
// params.otp = config.otp; | ||
// } | ||
|
||
var signature = getMessageSignature(path, params, params.nonce); | ||
|
||
var headers = { | ||
'API-Key': config.key, | ||
'API-Sign': signature | ||
}; | ||
|
||
return rawRequest(url, headers, params, callback); | ||
} | ||
|
||
/** | ||
* This method returns a signature for a request as a Base64-encoded string | ||
* @param {String} path The relative URL path for the request | ||
* @param {Object} request The POST body | ||
* @param {Integer} nonce A unique, incrementing integer | ||
* @return {String} The request signature | ||
*/ | ||
function getMessageSignature(path, request, nonce) { | ||
var secret = new Buffer(config.secret, 'base64'); | ||
var message = querystring.stringify(request); | ||
|
||
var hash = sha256(nonce + message); | ||
var hmac = hmac_sha512(path + hash.toString('binary'), secret); | ||
|
||
return hmac.toString('base64'); | ||
} | ||
|
||
/** | ||
* This method sends the actual HTTP request | ||
* @param {String} url The URL to make the request | ||
* @param {Object} headers Request headers | ||
* @param {Object} params POST body | ||
* @param {Function} callback A callback function to call when the request is complete | ||
* @return {Object} The request object | ||
*/ | ||
function rawRequest(url, headers, params, callback) { | ||
// Set custom User-Agent string | ||
headers['User-Agent'] = 'Kraken Javascript API Client'; | ||
|
||
var options = { | ||
url: url, | ||
method: 'POST', | ||
headers: headers, | ||
form: params | ||
}; | ||
|
||
var req = request.post(options, function(error, response, body) { | ||
if(error) { | ||
throw new Error('Error in server response: ' + JSON.stringify(error)); | ||
} | ||
else if(typeof callback === 'function') { | ||
try { | ||
callback.call(self, body); | ||
} | ||
catch(e) { | ||
throw new Error('Could not understand response from server.'); | ||
} | ||
} | ||
}); | ||
|
||
return req; | ||
} | ||
|
||
/** | ||
* A helper function to get a SHA256 hash | ||
* @param {String} input Input string | ||
* @return {Object} Output hash as a Buffer object | ||
*/ | ||
function sha256(input) { | ||
var hash = new crypto.createHash('sha256'); | ||
|
||
hash.write(input); | ||
hash.end(); | ||
|
||
var buffer = new Buffer(hash.read()); | ||
|
||
return buffer; | ||
} | ||
|
||
/** | ||
* A helper function to get a SHA512-encrypted signature | ||
* @param {String} message The message to sign | ||
* @param {String} secret The secret (private) key | ||
* @return {Object} Output hash as a Buffer object | ||
*/ | ||
function hmac_sha512(message, secret) { | ||
var hmac = new crypto.createHmac('sha512', secret); | ||
|
||
hmac.write(message); | ||
hmac.end(); | ||
|
||
var buffer = new Buffer(hmac.read()); | ||
|
||
return buffer; | ||
} | ||
|
||
self.api = api; | ||
self.publicMethod = publicMethod; | ||
self.privateMethod = privateMethod; | ||
} | ||
|
||
module.exports = KrakenClient; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "kraken-api", | ||
"version": "0.0.1", | ||
"description": "kraken.com API client library for NodeJS", | ||
"keywords": [ | ||
"btc", | ||
"bitcoin", | ||
"kraken" | ||
], | ||
"author": "Robert Myers (https://github.com/nothingisdead)", | ||
"contributors": [ | ||
], | ||
"license": "MIT", | ||
"dependencies": { | ||
"querystring": ">=0.2.0", | ||
"request": ">=2.27.0", | ||
"microtime": ">=0.5.0" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/nothingisdead/npm-kraken-api" | ||
}, | ||
"main": "kraken.js", | ||
"engines": { | ||
"node": ">=0.10" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/nothingisdead/npm-kraken-api/issues", | ||
"email": "rbmyr8@gmail.com" | ||
}, | ||
"readmeFilename": "README.md" | ||
} |