UNPKG

shapeshift.io

Version:

A component for shapeshift.io crypto currency API.

844 lines (732 loc) 24.7 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.shapeshift = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ var xhr = require('xhr') function get (url, callback) { xhr({ method: 'GET', url: url, json: undefined, timeout: 30000 }, function (err, resp, body) { if (err) return callback(err) if (resp.statusCode !== 200) return callback(new Error('HTTP status code: ' + resp.statusCode)) callback(null, body) }) } function post (url, data, callback) { xhr({ method: 'POST', url: url, json: data, timeout: 30000 }, function (err, resp, body) { if (err) return callback(err) if (resp.statusCode !== 200) return callback(new Error('HTTP status code: ' + resp.statusCode)) callback(null, body) }) } module.exports = { get: get, post: post } },{"xhr":10}],2:[function(require,module,exports){ (function (process){ if (!process.browser) { module.exports = require('./http' + '-node') } else { module.exports = require('./http-browser') } }).call(this,require('_process')) },{"./http-browser":1,"_process":8}],3:[function(require,module,exports){ // poor man's clone exports.clone = function clone (o) { return JSON.parse(JSON.stringify(o)) } },{}],4:[function(require,module,exports){ var isFunction = require('is-function') module.exports = forEach var toString = Object.prototype.toString var hasOwnProperty = Object.prototype.hasOwnProperty function forEach(list, iterator, context) { if (!isFunction(iterator)) { throw new TypeError('iterator must be a function') } if (arguments.length < 3) { context = this } if (toString.call(list) === '[object Array]') forEachArray(list, iterator, context) else if (typeof list === 'string') forEachString(list, iterator, context) else forEachObject(list, iterator, context) } function forEachArray(array, iterator, context) { for (var i = 0, len = array.length; i < len; i++) { if (hasOwnProperty.call(array, i)) { iterator.call(context, array[i], i, array) } } } function forEachString(string, iterator, context) { for (var i = 0, len = string.length; i < len; i++) { // no such thing as a sparse string. iterator.call(context, string.charAt(i), i, string) } } function forEachObject(object, iterator, context) { for (var k in object) { if (hasOwnProperty.call(object, k)) { iterator.call(context, object[k], k, object) } } } },{"is-function":6}],5:[function(require,module,exports){ (function (global){ if (typeof window !== "undefined") { module.exports = window; } else if (typeof global !== "undefined") { module.exports = global; } else if (typeof self !== "undefined"){ module.exports = self; } else { module.exports = {}; } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],6:[function(require,module,exports){ module.exports = isFunction var toString = Object.prototype.toString function isFunction (fn) { var string = toString.call(fn) return string === '[object Function]' || (typeof fn === 'function' && string !== '[object RegExp]') || (typeof window !== 'undefined' && // IE8 and below (fn === window.setTimeout || fn === window.alert || fn === window.confirm || fn === window.prompt)) }; },{}],7:[function(require,module,exports){ var trim = require('trim') , forEach = require('for-each') , isArray = function(arg) { return Object.prototype.toString.call(arg) === '[object Array]'; } module.exports = function (headers) { if (!headers) return {} var result = {} forEach( trim(headers).split('\n') , function (row) { var index = row.indexOf(':') , key = trim(row.slice(0, index)).toLowerCase() , value = trim(row.slice(index + 1)) if (typeof(result[key]) === 'undefined') { result[key] = value } else if (isArray(result[key])) { result[key].push(value) } else { result[key] = [ result[key], value ] } } ) return result } },{"for-each":4,"trim":9}],8:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it // don't break things. But we need to wrap it in a try catch in case it is // wrapped in strict mode code which doesn't define any globals. It's inside a // function because try/catches deoptimize in certain engines. var cachedSetTimeout; var cachedClearTimeout; function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } function defaultClearTimeout () { throw new Error('clearTimeout has not been defined'); } (function () { try { if (typeof setTimeout === 'function') { cachedSetTimeout = setTimeout; } else { cachedSetTimeout = defaultSetTimout; } } catch (e) { cachedSetTimeout = defaultSetTimout; } try { if (typeof clearTimeout === 'function') { cachedClearTimeout = clearTimeout; } else { cachedClearTimeout = defaultClearTimeout; } } catch (e) { cachedClearTimeout = defaultClearTimeout; } } ()) function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations return setTimeout(fun, 0); } // if setTimeout wasn't available but was latter defined if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); } catch(e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); } catch(e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations return clearTimeout(marker); } // if clearTimeout wasn't available but was latter defined if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); } catch (e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); } catch (e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}],9:[function(require,module,exports){ exports = module.exports = trim; function trim(str){ return str.replace(/^\s*|\s*$/g, ''); } exports.left = function(str){ return str.replace(/^\s*/, ''); }; exports.right = function(str){ return str.replace(/\s*$/, ''); }; },{}],10:[function(require,module,exports){ "use strict"; var window = require("global/window") var isFunction = require("is-function") var parseHeaders = require("parse-headers") var xtend = require("xtend") module.exports = createXHR createXHR.XMLHttpRequest = window.XMLHttpRequest || noop createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { options = initParams(uri, options, callback) options.method = method.toUpperCase() return _createXHR(options) } }) function forEachArray(array, iterator) { for (var i = 0; i < array.length; i++) { iterator(array[i]) } } function isEmpty(obj){ for(var i in obj){ if(obj.hasOwnProperty(i)) return false } return true } function initParams(uri, options, callback) { var params = uri if (isFunction(options)) { callback = options if (typeof uri === "string") { params = {uri:uri} } } else { params = xtend(options, {uri: uri}) } params.callback = callback return params } function createXHR(uri, options, callback) { options = initParams(uri, options, callback) return _createXHR(options) } function _createXHR(options) { if(typeof options.callback === "undefined"){ throw new Error("callback argument missing") } var called = false var callback = function cbOnce(err, response, body){ if(!called){ called = true options.callback(err, response, body) } } function readystatechange() { if (xhr.readyState === 4) { loadFunc() } } function getBody() { // Chrome with requestType=blob throws errors arround when even testing access to responseText var body = undefined if (xhr.response) { body = xhr.response } else { body = xhr.responseText || getXml(xhr) } if (isJson) { try { body = JSON.parse(body) } catch (e) {} } return body } var failureResponse = { body: undefined, headers: {}, statusCode: 0, method: method, url: uri, rawRequest: xhr } function errorFunc(evt) { clearTimeout(timeoutTimer) if(!(evt instanceof Error)){ evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ) } evt.statusCode = 0 return callback(evt, failureResponse) } // will load the data & process the response in a special response object function loadFunc() { if (aborted) return var status clearTimeout(timeoutTimer) if(options.useXDR && xhr.status===undefined) { //IE8 CORS GET successful response doesn't have a status field, but body is fine status = 200 } else { status = (xhr.status === 1223 ? 204 : xhr.status) } var response = failureResponse var err = null if (status !== 0){ response = { body: getBody(), statusCode: status, method: method, headers: {}, url: uri, rawRequest: xhr } if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE response.headers = parseHeaders(xhr.getAllResponseHeaders()) } } else { err = new Error("Internal XMLHttpRequest Error") } return callback(err, response, response.body) } var xhr = options.xhr || null if (!xhr) { if (options.cors || options.useXDR) { xhr = new createXHR.XDomainRequest() }else{ xhr = new createXHR.XMLHttpRequest() } } var key var aborted var uri = xhr.url = options.uri || options.url var method = xhr.method = options.method || "GET" var body = options.body || options.data || null var headers = xhr.headers = options.headers || {} var sync = !!options.sync var isJson = false var timeoutTimer if ("json" in options && options.json !== false) { isJson = true headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user if (method !== "GET" && method !== "HEAD") { headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user body = JSON.stringify(options.json === true ? body : options.json) } } xhr.onreadystatechange = readystatechange xhr.onload = loadFunc xhr.onerror = errorFunc // IE9 must have onprogress be set to a unique function. xhr.onprogress = function () { // IE must die } xhr.onabort = function(){ aborted = true; } xhr.ontimeout = errorFunc xhr.open(method, uri, !sync, options.username, options.password) //has to be after open if(!sync) { xhr.withCredentials = !!options.withCredentials } // Cannot set timeout with sync request // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent if (!sync && options.timeout > 0 ) { timeoutTimer = setTimeout(function(){ if (aborted) return aborted = true//IE9 may still call readystatechange xhr.abort("timeout") var e = new Error("XMLHttpRequest timeout") e.code = "ETIMEDOUT" errorFunc(e) }, options.timeout ) } if (xhr.setRequestHeader) { for(key in headers){ if(headers.hasOwnProperty(key)){ xhr.setRequestHeader(key, headers[key]) } } } else if (options.headers && !isEmpty(options.headers)) { throw new Error("Headers cannot be set on an XDomainRequest object") } if ("responseType" in options) { xhr.responseType = options.responseType } if ("beforeSend" in options && typeof options.beforeSend === "function" ) { options.beforeSend(xhr) } xhr.send(body) return xhr } function getXml(xhr) { if (xhr.responseType === "document") { return xhr.responseXML } var firefoxBugTakenEffect = xhr.status === 204 && xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror" if (xhr.responseType === "" && !firefoxBugTakenEffect) { return xhr.responseXML } return null } function noop() {} },{"global/window":5,"is-function":6,"parse-headers":7,"xtend":11}],11:[function(require,module,exports){ module.exports = extend var hasOwnProperty = Object.prototype.hasOwnProperty; function extend() { var target = {} for (var i = 0; i < arguments.length; i++) { var source = arguments[i] for (var key in source) { if (hasOwnProperty.call(source, key)) { target[key] = source[key] } } } return target } },{}],12:[function(require,module,exports){ module.exports={ "name": "shapeshift.io", "version": "1.2.0", "description": "A component for shapeshift.io crypto currency API.", "main": "lib/shapeshift.js", "scripts": { "build-browser": "browserify ./ -s shapeshift -o dist/shapeshift.js", "lint": "standard", "test": "npm run lint && npm run unit", "unit": "tape test/*test.js | tap-spec" }, "repository": { "type": "git", "url": "https://github.com/exodusmovement/shapeshift.io" }, "keywords": [ "crypto", "crypto", "currency", "currency", "shapeshift", "bitcoin", "litecoin", "dogecoin", "dash", "monero", "counterparty", "blackcoin" ], "author": "JP Richardson", "license": "MIT", "bugs": { "url": "https://github.com/exodusmovement/shapeshift.io/issues" }, "homepage": "https://github.com/exodusmovement/shapeshift.io", "devDependencies": { "browserify": "^13.1.1", "cb-insight": "^0.1.0", "coininfo": "^0.4.0", "coinkey": "^1.4.0", "decimal.js": "^4.0.2", "ms": "^0.7.1", "nock": "^1.6.0", "proxyquire": "^1.4.0", "spend": "0.0.1", "standard": "^8.6.0", "tap-spec": "^4.1.1", "tape": "^4.6.3" }, "dependencies": { "request": "^2.55.0", "xhr": "^2.0.1" }, "standard": { "ignore": [ "dist/shapeshift.js" ] } } },{}],13:[function(require,module,exports){ var http = require('./http') var util = require('./util') var pkg = require('../package') exports.coins = function (callback) { var url = getBaseUrl() + '/getcoins' http.get(url, function (err, data) { if (err) return callback(err) callback(null, data) }) } exports.depositLimit = function (pair, callback) { if (pair.indexOf('_') === -1) return callback(new Error('Invalid currency pair string.')) pair = pair.toLowerCase() var url = getBaseUrl() + '/limit/' + pair http.get(url, function (err, data) { if (err) return callback(err) callback(null, data.limit) }) } exports.emailReceipt = function (emailAddress, txId, callback) { var url = getBaseUrl() + '/mail' http.post(url, { email: emailAddress, txid: txId }, function (err, data) { if (err) return callback(err) if (data.error) return callback(new Error(data.error), data) callback(null, data.email) }) } exports.exchangeRate = function (pair, callback) { if (pair.indexOf('_') === -1) return callback(new Error('Invalid currency pair string.')) pair = pair.toLowerCase() var url = getBaseUrl() + '/rate/' + pair http.get(url, function (err, data) { if (err) return callback(err) callback(null, data.rate) }) } exports.isDown = function (callback) { marketInfo('btc_ltc', function (err, info) { if (err) return callback(err, true) else return callback(null, false) }) } exports.marketInfo = marketInfo function marketInfo (pair, callback) { // no pair passed if (typeof pair === 'function') { callback = pair pair = '' } var url = getBaseUrl() + '/marketinfo/' + pair http.get(url, function (err, info) { if (err) return callback(err) callback(null, info) }) } exports.recent = function (callback) { var url = getBaseUrl() + '/recenttx/50' http.get(url, function (err, data) { if (err) return callback(err) callback(null, data) }) } exports.quote = function (pair, options, callback) { options = util.clone(options) if (!('depositAmount' in options) && !('withdrawalAmount' in options)) { throw new Error('quote() expected depositAmount or withdrawalAmount') } if (options.despositAmount) { options.amount = options.depositAmount delete options.depositAmount } sendAmount(pair, options, callback) } exports.shift = function (withdrawalAddress, pair, options, callback) { if (options.amount) { _shiftFixed(withdrawalAddress, pair, options.amount, options, callback) } else { _shift(withdrawalAddress, pair, options, callback) } } exports._shift = _shift function _shift (withdrawalAddress, pair, options, callback) { var url = getBaseUrl() + '/shift' var payload = util.clone(options) payload.withdrawal = withdrawalAddress payload.pair = pair http.post(url, payload, function (err, data) { if (err) return callback(err, data) if (data.error) return callback(new Error(data.error), data) callback(null, data) }) } exports._shiftFixed = _shiftFixed function _shiftFixed (withdrawalAddress, pair, amount, options, callback) { var url = getBaseUrl() + '/sendamount' var payload = util.clone(options) payload.withdrawal = withdrawalAddress payload.pair = pair payload.amount = amount http.post(url, payload, function (err, data) { if (err) return callback(err, data) if (data.error) return callback(new Error(data.error), data) // shapeshift is inconsistent here, notice in `shift()` there is no success field callback(null, data.success) }) } exports.sendAmount = sendAmount function sendAmount (pair, payload, callback) { payload = util.clone(payload) payload.pair = pair var url = getBaseUrl() + '/sendamount' http.post(url, payload, function (err, data) { if (err) return callback(err, data) if (data.error) return callback(new Error(data.error), data) // shapeshift is inconsistent here, notice in `shift()` there is no success field callback(null, data.success) }) } exports.status = function (depositAddress, callback) { var url = getBaseUrl() + '/txStat/' + depositAddress http.get(url, function (err, data) { if (err) return callback(err) if (data.error) return callback(new Error(data.error), data.status, data) callback(null, data.status, data) }) } exports.transactions = function (apiKey, address, callback) { if (typeof address === 'function') { callback = address address = null } var url if (!address) url = getBaseUrl() + '/txbyapikey/' + apiKey else url = getBaseUrl() + '/txbyaddress/' + address + '/' + apiKey http.get(url, function (err, data) { if (err) return callback(err, data) if (!Array.isArray(data)) return callback(new Error('Data is not of type array. Possible error?'), data) callback(null, data) }) } function getBaseUrl () { var endpoint = 'shapeshift.io' // https://shapeshift.io/api.html#cors return module.exports.cors ? 'https://cors.' + endpoint : 'https://' + endpoint } exports.cors = true exports.http = http exports.__version = pkg.version },{"../package":12,"./http":2,"./util":3}]},{},[13])(13) });