BitPirate (OP)
Full Member
Offline
Activity: 238
Merit: 100
RMBTB.com: The secure BTC:CNY exchange. 0% fee!
|
|
August 04, 2013, 02:14:04 PM Last edit: August 12, 2013, 04:34:50 PM by BitPirate |
|
我们秉承在建立之初的宗旨,“安全、简单、快速”,所以我们不断脚踏实地的对我们的网站进行改进。 人盟比特币最新的API"Secure API"正式上线了.像其他交易网站一样,我们的API可以让你用自行设计的程序或第三方软件更方便地观察市场,进行交易。 我们的API基本和其他市场的API相当,但研究了各个API后,我们对API的安全有一些改进的解决方案。 - sign API的密钥与IP地址相锁定,同时每两个小时更新一次. 签API的密钥通常共享储存.大多数的网站在数据库内储存密钥。这种方式会有安全隐患--所以我们用一个长口令来申请与IP地址锁定的密钥,来替代在数据库储存API。由于密钥和IP地址锁定,同时我们数据库不储存你的密钥,这会提高你的账户安全性。
- 你可以为每个API设置单独的接入权限级别.可以设置为仅仅查看市场数据,或者仅仅查看你的账户余额,或是可以进行完整操作。这意味着你可以根据不同应用的需求来进行不同级别的接入,将风险尽可能隔离。
- IP 地址安全名单. 你可以设置允许使用你密钥和口令的IP 地址。你可以使用几个IPv4或IPv6 ranges。这意味即使有人偷了你的口令,他也无法使用。
- API 交易额度. 你可以设置通过API进行交易的额度,如果你的程度出现问题,也可以将交易控制在一个范围内。
- 优惠的交易费. 目前,用API进行交易可以享受50%的交易费优惠,意味着仅仅只有0.15%的交易费用!
. . API目前无法进行提现,所有的提现还是需要我们人工进行复核和操作。 使用手册Python的例子PHP的例子JavaScript(Node.js)的例子Ruby的例子Java的例子你可以任意使用我们的示范代码,但是请阅读以下我们的声明. 其他语言也在进行中,我们会陆续发布! 如果您想知道特定语言,也可以告知我们。
|
|
|
|
BitPirate (OP)
Full Member
Offline
Activity: 238
Merit: 100
RMBTB.com: The secure BTC:CNY exchange. 0% fee!
|
|
August 06, 2013, 02:25:18 PM Last edit: August 08, 2013, 04:51:01 PM by BitPirate |
|
Python: # -*- coding: utf-8 -*- # # PYTHON RMBTB SECURE API WRAPPER # # 版权和限制 # (c) 2013人盟比特币公布以下的代码遵循BSD条款。您可以按您的意愿使用或修改,用于个人或商业用途。 # # 然而您不可以以 "RMBTB", "人盟比特币"来标识您的程序,也不可以有意或无意示意您的软件或服务是由人盟比特币提供的。 # # # 使用示例 # >>> rmbtb = RmbtbSecureAPI("API_KEY_HERE", "API_PASSPHRASE_HERE", "BTCCNY") # >>> rmbtb.ticker() # >>> rmbtb.add_order(type="ask", amount=3.1, price=650.00) # # // 或... # >>> rmbtb = RmbtbSecureAPIInt("API_KEY_HERE", "API_PASSPHRASE_HERE", "BTCCNY") # >>> rmbtb.add_order(type="bid", amount=310000000, price=65000000) # import time, datetime, json, urllib, urllib2, base64, hmac, gzip from hashlib import sha512 from os import path class RmbtbSecureAPI(object): """The base RMBTB class""" #Set the following to a local, secure, writeable location to store temporary secrets. RMBTB_LOCAL_STORAGE_LOC = "rmbtb-store.dat" RMBTB_BASE_URL = "https://www.rmbtb.com/api/secure/" def __init__(self, key, passphrase, currencyPair="BTCCNY"): self.key = key self.passphrase = passphrase self.currencyPair = currencyPair self._load_secret(self.RMBTB_LOCAL_STORAGE_LOC) def get_info(self): """Get account information""" return self._request(api="getinfo", httpMethod="GET") def get_funds(self): """Get wallet balances""" return self._request(api="wallets", httpMethod="GET") def ticker(self): """Get ticker data""" return self._request(api="ticker", httpMethod="GET", auth=False) def get_orders(self): """Get my orders""" return self._request(api="orders", httpMethod="GET") def add_order(self, type, amount, price): """Place an order""" params = { 'type': type, 'amount': amount, 'price': price } return self._request(api="order/add", params=params, httpMethod="POST") def cancel_order(self, orderid): """Cancel an order""" params = { 'oid': orderid } return self._request(api="order/cancel", params=params, httpMethod="POST") def fetch_order(self, orderid): """Get order details""" params = { 'oid': orderid } return self._request(api="order/fetch", params=params, httpMethod="GET") def get_trades(self): """Get your recent trades""" return self._request(api="trades/mine", httpMethod="GET") def last_trades(self): """Get recent market trades data""" return self._request(api="trades/all", httpMethod="GET", auth=False) def get_depth(self): """Get market depth""" return self._request(api="depth", httpMethod="GET", auth=False) def _load_secret(self, loc): """Private method; loads secret from storage""" self.secret = False self.secretExpiryTime = False if path.exists(loc): storTime = datetime.datetime.fromtimestamp(path.getmtime(loc)) timeNow = datetime.datetime.now() self.secretExpiryTime = storTime + datetime.timedelta(hours=2) if (datetime.datetime.now() < self.secretExpiryTime): # secret has not expired self.secret = open(loc).read().strip() return True #secret has expired or we've never created one before return self._refresh_secret(loc) def _refresh_secret(self, loc): """Private method; refreshes the secret""" self.secret = str(self._obtain_new_secret(loc)) if self.secret != False: f = open(loc, 'w') f.write(self.secret) f.close() self.secretExpiryTime = datetime.datetime.now() + datetime.timedelta(hours=2) return self.secret def _obtain_new_secret(self, loc): """Private method; Gets the new secret""" postData = "api_passphrase=" + urllib2.quote(self.passphrase) headers = { "Rest-Key": self.key } data = self._curl_call(api="getsecret", paramStr=postData, headers=headers, httpMethod="POST") return data["data"]["secret"] def _request(self, api, params={}, httpMethod="GET", auth=True): """Private method; creates the API request parameters / auth headers""" 'GET' if (httpMethod == 'GET') else 'POST' if auth: #refresh secret if necessary if (self.secret == False) or (datetime.datetime.now() > (self.secretExpiryTime - datetime.timedelta(seconds=60))): self._refresh_secret(self.RMBTB_LOCAL_STORAGE_LOC) params[u"nonce"] = str(int(time.time()*1e6)) sendParams = urllib.urlencode(params) mac = hmac.new(self.secret, str(sendParams), sha512) sig = base64.b64encode(str(mac.digest())) headers = { "Rest-Key": self.key, "Rest-Sign": sig, "Content-Type": "application/x-www-form-urlencoded", } else: sendParams = urllib.urlencode(params) headers = {} data = self._curl_call(api=api, paramStr=sendParams, headers=headers, httpMethod=httpMethod) return data def _curl_call(self, api, paramStr=None, httpMethod="GET", headers={}, timeout=8): """Private method; performs the request""" url = self.RMBTB_BASE_URL + self.currencyPair + "/" + api headers.update({ 'User-Agent': "Mozilla/4.0 (compatible; RMBTB Python client)", 'Accept-Encoding': 'GZIP', }) if httpMethod == "POST": headers["Content-Type"] = "application/x-www-form-urlencoded" sendParams = paramStr else: url = url + "?" + paramStr sendParams = False if sendParams: request = urllib2.Request(url, sendParams, headers=headers) else: request = urllib2.Request(url, headers=headers) response = urllib2.urlopen(request, timeout=timeout) data = json.loads(response.read()) if not(u"data" in data): if(u"error" in data): raise Exception(u"Error received: " + data[u"error"]) else: raise Exception("An error occurred") return data class RmbtbSecureAPIInt(RmbtbSecureAPI): """Use this class if you prefer to deal with integers""" def add_order(self, type_int, amount_int, price): """Place an order""" params = { 'type': type, 'amount_int': amount_int, 'price_int': price_int } return self._request(api="order/add", params=params, httpMethod="POST")
|
|
|
|
BitPirate (OP)
Full Member
Offline
Activity: 238
Merit: 100
RMBTB.com: The secure BTC:CNY exchange. 0% fee!
|
|
August 06, 2013, 02:26:35 PM Last edit: August 07, 2013, 03:00:57 PM by BitPirate |
|
PHP: 此代码会检查我们的SSL证书。您可以自行下载(在Firefox中,点击地址栏安全报告, 更多信息… → 查看证书… → 详细信息→ Save)然后将其保存在安全的地方. < ? php /** * PHP RMBTB SECURE API WRAPPER * 版权和限制 * (c) 2013人盟比特币公布以下的代码遵循BSD条款。您可以按您的意愿使用或修改,用于个人或商业用途。 * * 然而您不可以以 "RMBTB", "人盟比特币"来标识您的程序,也不可以有意或无意示意您的软件或服务是由人盟比特币提供的。 * * 你可以使用默认的浮点型或者整数型的. * 请仔细阅读下面的设置和安全建议 * * 使用示例 * $rmbtbApi = new Rmbtb_Secure_API('BTCCNY', RMBTB_API_PUBKEY, RMBTB_API_PASSPHRASE); * print_r($rmbtbApi->get_info()); * print_r($rmbtbApi->add_order('bid', 5, 650)); * * // 或... * $rmbtbApiInt = new Rmbtb_Secure_API_Integer('BTCCNY', RMBTB_API_PUBKEY, RMBTB_API_PASSPHRASE); * print_r($rmbtbApiInt->add_order('ask', 500000000, 65000000)); */ /** * 配置 * * 于此设置您的配置选项 * 建议您将这些文件存在另一个文件里,在服务器一个更安全的地方上。要包含将() 在文件中 * * e.g. require('/path/to/rmbtb/config.php'); */ // 你的API用户名和口令 define('RMBTB_API_PUBKEY', 'r-api-e888a-1111d-181818-6fafa7-fa18fa-8888a-9fsx'); define('RMBTB_API_PASSPHRASE', 'n4ajpX/df*2A%%xxT>Pq<_24pxcpH|^Q5nhQab==!=IIh%/x-'); /* * 存放人盟比特币SSL证书副本的地方。用此来确定您不是和冒名者在沟通。你可以下载此文件并导到你的浏览器内。 */ define('RMBTB_CERT_LOC', 'rmbtb-cert.pem'); /* * 一个安全,可写的地方来存放你零时的API 密钥。文件未必需要存在,但是文件夹必须存在,并且可写。 * 不要将其放在很容易找到的地方! */ define('RMBTB_LOCAL_STORAGE_LOC', 'rmbtb-store.dat'); /** * 配置部分结束 */ /** * * The base API class. This is extended below if you need to deal with integers rather than floats. */ class Rmbtb_Secure_API { private $urlBase = 'https://www.rmbtb.com/api/secure/', $currencyPair, $key, $passphrase, $secret, $secretExpiryTime, $debug; /** * Constructor * @param string $key your RMBTB Secure API public key * @param string $passphrase the passphrase given to you with your key */ public function __construct($currencyPair, $key, $passphrase, $debug = false) { $this->debug = $debug; $this->currencyPair = $currencyPair; $this->key = $key; $this->passphrase = $passphrase; $this->load_secret(RMBTB_LOCAL_STORAGE_LOC); } /** * get_info() * Get useful information about your account * Authentication required. * @return Array representation of JSON object */ public function get_info() { return $this->request('getinfo', array(), 'GET'); } /** * get_funds() * Get balance information * Authentication required. * @return Array representation of JSON object */ public function get_funds() { return $this->request('wallets', array(), 'GET'); } /** * ticker() * Get market information * @return Array representation of JSON object */ public function ticker() { return $this->request('ticker', array(), 'GET', false); } /** * get_orders() * Get your 50 most recent orders * Authentication required. * @return Array representation of JSON object */ public function get_orders() { return $this->request('orders', array(), 'GET'); } /** * add_order() * Place a new order * Authentication required. * @param string bid|ask $type * @param float $amount amount of BTC to buy/sell * @param float $price bid or ask price * @return Array representation of JSON object */ public function add_order($type, $amount, $price) { return $this->request('order/add', array('type' => $type, 'amount' => $amount, 'price' => $price), 'POST'); } /** * add_order() * Cancel an order * Authentication required. * @param integer $orderid the Order ID to cancel * @return Array representation of JSON object */ public function cancel_order($orderid) { return $this->request('order/cancel', array('oid' => $orderid), 'POST'); } /** * fetch_order() * Fetch order details * Authentication required. * @param integer $orderid the Order ID to fetch * @return Array representation of JSON object */ public function fetch_order($orderid) { return $this->request('order/fetch', array('oid' => $orderid), 'GET'); } /** * get_trades() * Get your 50 most recent trades * Authentication required. * @return Array representation of JSON object */ public function get_trades() { return $this->request('trades/mine', array(), 'GET'); } /** * last_trades() * View the last 80 public trades * @return Array representation of JSON object */ public function last_trades() { return $this->request('trades/all', array(), 'GET', false); } /** * get_depth() * View the market depth * @return Array representation of JSON object */ public function get_depth() { return $this->request('depth', array(), 'GET', false); } /** * Performs the request. * @param string $method the API address * @param array $params the API method parameters * @param string GET|POST $http_method the HTTP method * @param bool $auth whether to sign the request * @return array with the returned data * @access protected */ protected function request($method, $params = array(), $http_method = 'GET', $auth = true) { $http_method = ($http_method == 'GET') ? 'GET' : 'POST'; if($auth) { // refresh secret if necessary $secretExpires = $this->secretExpiryTime - time(); if($secretExpires < 60) { $this->refresh_secret(RMBTB_LOCAL_STORAGE_LOC); } // generate an always-increasing nonce using microtime $mt = explode(' ', microtime()); $params['nonce'] = $mt[1].substr($mt[0], 2, 6); // generate the POST data string $data = http_build_query($params, '', '&'); // generate the extra headers for message verification $headers = array( 'Rest-Key: ' . $this->key, 'Rest-Sign: '. base64_encode(hash_hmac('sha512', $data, $this->secret, true)) ); } else { $data = http_build_query($params, '', '&'); $headers = array(); } $data = $this->do_curl($method, $data, $headers, $http_method); return $data; }
/** * Loads the last API secret from your local storage file. * Secrets expire every two hours, so we only use the secret if it was stored less than two hours ago. * If it has expired, we load a new one. * @param string $loc the location where the last secret was stored. * @return bool false on failure * @access private */ private function load_secret($loc) { $this->secret = false; $this->secretExpiryTime = false; if(file_exists($loc)) { $storTime = @filemtime($loc); // Account for a bug in Windows where daylight saving is not reflected correctly $isDST = (date('I', $storTime) == 1); $systemDST = (date('I') == 1); $adjustment = 0; if($isDST == false && $systemDST == true) { $adjustment = 3600; } else if($isDST == true && $systemDST == false) { $adjustment = -3600; } $storTime += $adjustment; $elapsed = time() - $storTime; if($elapsed < 7200) { // secret has not yet expired $this->secret = trim(file_get_contents($loc)); $this->secretExpiryTime = $storTime + 7200; return true; } } // secret has expired or we've never created one before return $this->refresh_secret($loc); } /** * Fetch a new secret from the API * @param string $loc the location to store the secret * @return bool true on success * @access private */ private function refresh_secret($loc) { if($this->secret = $this->obtain_new_secret()) { file_put_contents($loc, $this->secret); $this->secretExpiryTime = time() + 7200; return true; } return false; } /** * Requests a new API secret, which will be tied to our IP and will * last for 2 hours. * @return string our new secret, or false on error. * @access private */ private function obtain_new_secret() { $postData = 'api_passphrase=' . urlencode($this->passphrase); $headers = array( 'Rest-Key: ' . $this->key ); $data = $this->do_curl('getsecret', $postData, $headers, 'POST'); return $data['data']['secret']; } /** * Performs the request * @param string $path the API method path * @param string $data the GET url string, or the POST body * @param array $headers headers to send -- e.g. our Rest-Key and Rest-Sign * @param string GET|POST $http_method the HTTP method to use * @return array representation of JSON response, or an error. * @access private */ private function do_curl($path, $data, $headers, $http_method) { static $ch = null; $url = $this->urlBase . $this->currencyPair . '/' . $path; if($this->debug) { echo "Sending request to $url\n"; } if (is_null($ch)) { $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; RMBTB PHP client; '.php_uname('s').'; PHP/'.phpversion().')'); } if($http_method == 'GET') { $url .= '?' . $data; } else { curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE); curl_setopt($ch, CURLOPT_CAINFO, RMBTB_CERT_LOC); // run the query $response = curl_exec($ch); if($this->debug) { echo "Response: $response\n"; } if (empty($response)) { throw new Exception('Could not get reply: ' . curl_error($ch)); } $data = json_decode($response, true); if (!is_array($data)) { throw new Exception('Invalid data received, please make sure connection is working and requested API exists'); } $this->quit_on_error($data); return $data; } /** * Parses the returned data, and bails if it contains an error. * @param array $data an array representation of returned JSON data * @return void * @access private */ private function quit_on_error($data) { if($data['error'] !== false) { throw new Exception("\n\nError received from API: {$data['code']}\n-----------------------------------\n{$data['error']}\n\n"); exit(); } } } /** * * Use this if you prefer to use integers to order. */ class Rmbtb_Secure_API_Integer extends Rmbtb_Secure_API { /** * add_order() * Place a new order * Authentication required. * @param string bid|ask $type * @param integer $amount_int amount of BTC to buy/sell * @param integer $price_int bid or ask price * @return Array representation of JSON object */ public function add_order($type, $amount_int, $price_int) { return $this->request('order/add', array('type' => $type, 'amount_int' => $amount_int, 'price_int' => $price_int)); } }
|
|
|
|
BitPirate (OP)
Full Member
Offline
Activity: 238
Merit: 100
RMBTB.com: The secure BTC:CNY exchange. 0% fee!
|
|
August 06, 2013, 02:32:34 PM Last edit: August 08, 2013, 04:52:23 PM by BitPirate |
|
JavaScript (Node.js): /** * * JavaScript (Node.js) secure API wrapper * * 版权和限制 (c) 2013人盟比特币公布以下的代码遵循BSD条款。您可以按您的意愿使用或修改,用于个人或商业用途。 * * 然而您不可以以 "RMBTB", "人盟比特币"来标识您的程序,也不可以有意或无意示意您的软件或服务是由人盟比*特币提供的。 * * Usage: * All functions are fully asynchronous, so you need to provide a callback function. * * var rmbtb = new rmbtbSecureApi('BTCCNY', myPubKey, myPassPhrase); * * rmbtb.addOrder('bid', 3, 591, function(result) { * console.log('Result: %j', result); * }); * */ // Location where you will store temporary secrets: var rmbtbStoreLocation = 'rmbtb-secret.dat'; // Node.js dependencies var fs = require('fs'), https = require('https'), querystring = require('querystring'), crypto = require('crypto'); function rmbtbSecureApi(currPair, pubKey, passphrase) { this.currPair = currPair; this.pubKey = pubKey; this.passphrase = passphrase; this.storeLoc = rmbtbStoreLocation; this.apiHost = 'www.rmbtb.com'; this.apiPath = '/api/secure/' + currPair + '/'; this.secret = false; this.secretExpiryTime = false; var that = this; var twoHrs = 7200000; // fetches a new secret if necessary, before performing the main request this.apiCall = function(api, params, httpMethod, auth, callback) { var cb = function() { prepRequest(api, params, httpMethod, auth, callback); }; if(auth) { if((this.secret === false) || (this.secretExpiryTime === false)) { loadSecret(cb); } else if((this.secretExpiryTime.getTime() - 60000) > (new Date()).getTime()) { rereshSecret(cb); } else { cb.call(this); } } else { cb.call(this); } }; // prepares the request function prepRequest(api, params, httpMethod, auth, callback) { var data = '', headers = {}; if(this.secret === false) { throw 'No valid secret!'; } if(auth) { params.nonce = (new Date()).getTime() * 1000; data = querystring.stringify(params); var hmac = crypto.createHmac("sha512", that.secret); hmac.update(data); headers['Rest-Key'] = that.pubKey; headers['Rest-sign'] = hmac.digest('base64'); } else { data = querystring.stringify(params); } if(httpMethod == 'POST') { headers['Content-Type'] = 'application/x-www-form-urlencoded'; headers['Content-Length'] = data.length; } headers['User-Agent'] = 'Mozilla/4.0 (compatible; RMBTB JavaScript client)';
var opts = { method: httpMethod, headers: headers }; if(httpMethod == 'GET') { api += '?' + data; } doRequest(api, data, opts, callback); } // sends a prepared request to the API function doRequest(api, data, opts, callback) { opts.host = that.apiHost; opts.path = that.apiPath + api; var req = https.request(opts, function(response) { var resultStr = ''; response.setEncoding('utf8'); response.on('data', function(chunk) { resultStr += chunk; }); response.on('error', function(err) { throw err; }); response.on('end', function() { try { var obj = JSON.parse(resultStr); } catch(e) { throw 'Could not understand response'; } if(obj.error !== false) { throw 'API returned an error: ' + obj.error; } var result = obj.data; callback.call(that, result); }); }); req.on('error', function(err) { throw 'Error communicating: ' + err; }); if(opts.method == 'POST') { req.write(data); } req.end(); } // refreshes the temporary secret function refreshSecret(cb) { var data = querystring.stringify({'api_passphrase': that.passphrase}); var opts = { method: 'POST', headers: { 'Rest-Key': that.pubKey, 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': data.length, } }; doRequest('getsecret', data, opts, function(result) { that.secret = result.secret; that.secretExpiryTime = new Date((new Date()).getTime() + twoHrs); fs.writeFile(that.storeLoc, that.secret, 'utf8', function() { cb.call(that) }); }); } // loads the stored secret from the save file function loadSecret(cb) { fs.stat(that.storeLoc, function(err, stat) { if(!err) { that.secretExpiryTime = new Date(stat.mtime.getTime() + twoHrs); if((new Date()).getTime() < that.secretExpiryTime.getTime()) { fs.readFile(that.storeLoc, 'utf8', function(err, data) { if(!err) { that.secret = data; cb.call(that); } else { refreshSecret(cb); } }); } else { refreshSecret(cb); } } else { refreshSecret(cb); } }); } } /** * * The public, callable methods: * */ rmbtbSecureApi.prototype.getInfo = function(callback) { this.apiCall('getinfo', {}, 'GET', true, callback); }; rmbtbSecureApi.prototype.getFunds = function(callback) { this.apiCall('wallets', {}, 'GET', true, callback); }; rmbtbSecureApi.prototype.ticker = function(callback) { this.apiCall('ticker', {}, 'GET', false, callback); }; rmbtbSecureApi.prototype.getOrders = function(callback) { this.apiCall('orders', {}, 'GET', true, callback); }; rmbtbSecureApi.prototype.addOrder = function(type, amount, price, callback) { var params = { 'type': type, 'amount': amount, 'price': price }; this.apiCall('order/add', params, 'POST', true, callback); }; rmbtbSecureApi.prototype.addOrderInt = function(type, amount, price, callback) { var params = { 'type': type, 'amount_int': amount, 'price_int': price }; this.apiCall('order/add', params, 'POST', true, callback); }; rmbtbSecureApi.prototype.cancelOrder = function(orderid, callback) { var params = { 'oid': orderid, }; this.apiCall('order/cancel', params, 'POST', true, callback); }; rmbtbSecureApi.prototype.fetchOrder = function(orderid, callback) { var params = { 'oid': orderid, }; this.apiCall('order/fetch', params, 'POST', true, callback); }; rmbtbSecureApi.prototype.getTrades = function(callback) { this.apiCall('trades/mine', {}, 'GET', true, callback); }; rmbtbSecureApi.prototype.lastTrades = function(callback) { this.apiCall('trades/all', {}, 'GET', false, callback); }; rmbtbSecureApi.prototype.getDepth = function(callback) { this.apiCall('depth', {}, 'GET', false, callback); };
|
|
|
|
fisker
Newbie
Offline
Activity: 1
Merit: 0
|
|
August 07, 2013, 12:35:40 PM |
|
get_funds 貌似不能工作,我用get_info代替了
|
|
|
|
BitPirate (OP)
Full Member
Offline
Activity: 238
Merit: 100
RMBTB.com: The secure BTC:CNY exchange. 0% fee!
|
|
August 07, 2013, 01:25:37 PM |
|
get_funds 貌似不能工作,我用get_info代替了
谢谢,这个问题现在已经解决了。如果有其他问题也可以及时联系我们
|
|
|
|
|
BitPirate (OP)
Full Member
Offline
Activity: 238
Merit: 100
RMBTB.com: The secure BTC:CNY exchange. 0% fee!
|
|
August 08, 2013, 02:56:51 PM |
|
不错
谢谢!
|
|
|
|
BitPirate (OP)
Full Member
Offline
Activity: 238
Merit: 100
RMBTB.com: The secure BTC:CNY exchange. 0% fee!
|
|
August 08, 2013, 02:58:34 PM Last edit: August 08, 2013, 04:53:28 PM by BitPirate |
|
还有 Ruby #!/usr/bin/env ruby # # coding: utf-8 # # Ruby wrapper for the RMBTB.com Secure API # (c) RMBTB.com. Released under the BSD license. Modification & redistribution allowed, but you may not use the RMBTB brand or name. # # Example usage: # rmbtb = RmbtbSecureApi.new(pubkey, passphrase, 'BTCCNY') # p rmbtb.add_order('bid', 3.1, 570.2) # require 'base64' require 'openssl' require 'time' require 'uri' require 'cgi' require 'net/http' require 'net/https'
require 'rubygems' require 'json'
# RMBTB API layer class RmbtbSecureApi
def initialize(key, passphrase, currpair = 'BTCCNY') @base = 'https://www.rmbtb.com/api/secure/' @storloc = 'rmbtb-store.dat'
@key = key @passphrase = passphrase @currpair = currpair @secret = nil @expiry = nil end
# Public: Retrieve account information # # Returns a JSON object def get_info return prepare_request('getinfo', :httpMethod => 'GET', :auth => true) end # Public: Retrieve wallet balances # # Returns a JSON object of wallet balances def get_funds return prepare_request('wallets', :httpMethod => 'GET', :auth => true) end # Public: Retrieve market information # # Returns a JSON object def ticker return prepare_request('ticker', :httpMethod => 'GET') end # Public: Retrieve my last 50 orders # # Returns a JSON object of orders def get_orders return prepare_request('ticker', :httpMethod => 'GET', :auth => true) end # Public: Add an order, using floats # # type - String, 'bid' or 'ask' # amount - Float, amount to buy or sell # price - Float, the price # # Returns a JSON object containing the Order ID def add_order(type, amount, price) params = { :type => type, :amount => amount, :price => price } return prepare_request('order/add', :params => params, :httpMethod => 'POST', :auth => true) end # Public: Add an order, using integers # # type - String, 'bid' or 'ask' # amount - Float, amount to buy or sell # price - Float, the price # # Returns a JSON object containing the Order ID def add_order_int(type, amount, price) params = { :type => type, :amount_int => amount, :price_int => price } return prepare_request('order/add', :params => params, :httpMethod => 'POST', :auth => true) end # Public: Cancel an order # # orderid - Integer, the order ID to cancel # # Returns a JSON object containing the Order ID def cancel_order(orderid) params = { :oid => orderid } return prepare_request('order/cancel', :params => params, :httpMethod => 'POST', :auth => true) end # Public: Fetch information about an order # # orderid - Integer, the order ID to cancel # # Returns order information def fetch_order(orderid) params = { :oid => orderid } return prepare_request('order/fetch', :params => params, :httpMethod => 'GET', :auth => true) end # Public: Get my trades # # Returns my latest trades def get_trades return prepare_request('trades/mine', :httpMethod => 'GET', :auth => true) end # Public: Get all market trades # # Returns the latest market trades def last_trades return prepare_request('trades/all', :httpMethod => 'GET') end # Public: Get depth # # Returns the market depth def get_depth return prepare_request('depth', :httpMethod => 'GET') end
private # Prepares the request def prepare_request(api, options = { }) httpMethod = (options[:httpMethod] == 'GET') && 'GET' || 'POST' auth = options[:auth] ||= false params = options[:params] ||= { } if auth load_secret if !@secret || !@expiry || (@expiry < (Time.now - 60)) # Add nonce params = params.merge(:nonce => (Time.now.to_f * 1e6).to_i.to_s) sendParams = params.map{ |k,v| "#{ CGI::escape(k.to_s) }=#{ CGI::escape(v.to_s) }" }.join('&') mac = Base64.encode64(OpenSSL::HMAC.digest('sha512', @secret, sendParams)).gsub(/\n/, '') headers = { 'Rest-Key' => @key, 'Rest-Sign' => mac } else sendParams = params.map{ |k,v| "#{CGI::escape(k.to_s) }=#{ CGI::escape(v.to_s)}" }.join('&') headers = { } end return send_request(api, :paramStr => sendParams, :httpMethod => httpMethod, :headers => headers) end
# fetch or load/refresh the temporary secret def load_secret if !@secret && File.exists?(@storloc) @expiry = File.mtime(@storloc) + 7200 if @expiry > (Time.now - 60) @secret = File.open(@storloc).read return end end
result = send_request('getsecret', :paramStr => "api_passphrase=#{ CGI::escape(@passphrase) }", :httpMethod => 'POST', :headers => { 'Rest-Key' => @key }) @secret = result['secret'] File.open(@storloc, 'w') { |f| f.write(@secret) } @expiry = Time.now + 7200 end
# Send the request out def send_request(api, options={ })
httpMethod = (options[:httpMethod] == 'GET') && 'GET' || 'POST' headers = options[:headers] ||= { } data = options[:paramStr] ||= ''
url = "#{ @base }#{ @currpair }/#{ api }"
if httpMethod == 'POST' headers.merge({'Content-Type' => 'application/x-www-form-urlencoded'}) elsif data != '' url = "#{ url }?#{ data }" end
headers.merge({'User-Agent' => 'Mozilla/4.0 (compatible); RMBTB Ruby API Client'})
url = URI.parse(url) https = Net::HTTP.new(url.host, url.port) https.use_ssl = true result = nil begin req, body = ((httpMethod == 'POST') ? https.post(url.path, data, headers) : https.get(url.request_uri, headers)) result = JSON.parse(body) rescue raise 'Could not communicate with server' end raise "Error: #{ result['error'] }" if result['error'] return result['data']
end
end
|
|
|
|
azwccc
|
|
August 08, 2013, 09:36:59 PM |
|
support!
|
Bitrated user: azwccc.
|
|
|
BitPirate (OP)
Full Member
Offline
Activity: 238
Merit: 100
RMBTB.com: The secure BTC:CNY exchange. 0% fee!
|
|
August 12, 2013, 04:32:37 PM |
|
support!
|
|
|
|
BitPirate (OP)
Full Member
Offline
Activity: 238
Merit: 100
RMBTB.com: The secure BTC:CNY exchange. 0% fee!
|
|
August 12, 2013, 04:33:54 PM Last edit: August 12, 2013, 11:47:50 PM by BitPirate |
|
还有。。。Java! /** * JAVA RMBTB SECURE API CLASS * * 版权和限制 * (c)2013人盟比特币公布以下的代码遵循BSD条款。您可以按您的意愿使用或修改,用于个人或商业用途。 * * 然而您不可以以 "RMBTB", "人盟比特币"来标识您的程序,也不可以有意或无意示意您的软件或服务是由人盟比特币提供的。 * * 你可以使用默认的浮点型或者整数型的. * 请仔细阅读下面的设置和安全建议 * * 使用示例 * This class relies on the Apache commons codec and the json-simple modules. * * RmbtbSecureApi r = new RmbtbSecureApi("pubkey", "passphrase", "BTCCNY"); * Sytem.out.print(r.addOrder("bid", 1.1, 600.0)); * * Full documentation is at https://www.rmbtb.com/help-secureapi-en/ * */ import java.util.*; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.text.DecimalFormat; import javax.net.ssl.HttpsURLConnection; import java.net.ProtocolException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException;
// http://commons.apache.org/proper/commons-codec/ import org.apache.commons.codec.binary.Base64;
// json-simple http://code.google.com/p/json-simple/ import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException;
/** * The RMBTB Secure API class. Set the constants here. */ interface RmbtbApi { // Set this to the location you want to store temporary secrets public static final String StorLocation = "rmbtb-secret-data.dat"; public static final String urlBaseLoc = "https://www.rmbtb.com/api/secure/";
/** * Gets useful information about your account * Authentication required. * @return JSONObject account details */ public JSONObject getInfo() throws Exception; /** * Gets your wallet balances * Authentication required. * @return JSONObject account balances */ public JSONObject getFunds() throws Exception; /** * Gets your wallet balances * Authentication required. * @return JSONObject account balances */ public JSONObject ticker() throws Exception; /** * Gets useful market information * @return JSONObject market info */ public JSONObject getOrders() throws Exception; /** * Adds an order -- double params * @param String type bid | ask * @param double amount the amount to buy/sell * @param souble price the price to buy/sell at * @return JSONObject containing the Order ID */ public JSONObject addOrder(String type, double amount, double price) throws Exception;
/** * Adds an order -- long integer params * @param String type bid | ask * @param long amount the amount to buy/sell * @param long price the price to buy/sell at * @return JSONObject containing the Order ID */ public JSONObject addOrder(String type, long amount, long price) throws Exception;
/** * Cancels an order * @param long orderId the Order ID to cancel * @return JSONObject containing the Order ID */ public JSONObject cancelOrder(long orderId) throws Exception; /** * fetches info about an order * @param long orderId the Order ID to cancel * @return JSONObject of info */ public JSONObject fetchOrder(long orderId) throws Exception; /** * Gets your 50 most recent trades * @return JSONObject of info */ public JSONObject getTrades() throws Exception; /** * returns the most recent market transactions * @return JSONObject of info */ public JSONObject lastTrades() throws Exception; /** * returns the market depth * @return JSONObject showing bids and asks */ public JSONObject getDepth() throws Exception; }
public class RmbtbSecureApi implements RmbtbApi { private String currPair; private String pubkey; private String passphrase; private String secret; private Calendar expires;
public RmbtbSecureApi(String pubkey, String passphrase) { this(pubkey, passphrase, "BTCCNY"); }
public RmbtbSecureApi(String pubkey, String passphrase, String currPair) {
this.currPair = currPair; this.pubkey = pubkey; this.passphrase = passphrase; this.secret = ""; this.expires = Calendar.getInstance();
} public JSONObject getInfo() throws Exception { return doRequest("getinfo", "GET", true); } public JSONObject getFunds() throws Exception { return doRequest("wallets", "GET", true); } public JSONObject ticker() throws Exception { return doRequest("ticker", "GET", false); } public JSONObject getOrders() throws Exception { return doRequest("orders", "GET", true); } public JSONObject addOrder(String type, double amount, double price) throws Exception { HashMap<String,String> params = new HashMap<String, String>(); params.put("type", type == "ask" ? "ask" : "bid"); params.put("amount", new DecimalFormat("00000000.00000000").format(amount)); params.put("price", new DecimalFormat("00000000.00000000").format(price));
return doRequest("order/add", "POST", true, params); } public JSONObject addOrder(String type, long amount, long price) throws Exception {
HashMap<String,String> params = new HashMap<String, String>(); params.put("type", type == "ask" ? "ask" : "bid"); params.put("amount_int", String.valueOf(amount)); params.put("price_int", String.valueOf(price));
return doRequest("order/add", "POST", true, params); } public JSONObject cancelOrder(long orderId) throws Exception { HashMap<String,String> params = new HashMap<String, String>(); params.put("oid", String.valueOf(orderId));
return doRequest("order/cancel", "POST", true, params); } public JSONObject fetchOrder(long orderId) throws Exception { HashMap<String,String> params = new HashMap<String, String>(); params.put("oid", String.valueOf(orderId));
return doRequest("order/fetch", "GET", true, params); } public JSONObject getTrades() throws Exception { return doRequest("trades/mine", "GET", true); } public JSONObject lastTrades() throws Exception { return doRequest("trades/all", "GET", false); } public JSONObject getDepth() throws Exception { return doRequest("depth", "GET", false); } private JSONObject doRequest(String api, String httpMethod, boolean auth) throws Exception {
HashMap<String,String> params = new HashMap<String, String>(); return doRequest(api, httpMethod, auth, params); }
private JSONObject doRequest(String api, String httpMethod, boolean auth, HashMap<String,String> params) throws Exception {
if(auth) { Calendar maxAge = Calendar.getInstance(); maxAge.add(Calendar.MINUTE, -1); if((this.secret == "") || this.expires.before(maxAge)) { this.loadSecret(); } params.put("nonce", String.valueOf(System.nanoTime())+"000"); } String paramStr = ""; int i = 0; for(Map.Entry<String, String> entry : params.entrySet()) { paramStr += entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), "UTF-8"); i++; if(i < params.size()) { paramStr += "&"; } } HashMap<String,String> headers = new HashMap<String, String>(); if(auth) { headers.put("Rest-Key", this.pubkey); headers.put("Rest-Sign", this.getRequestSig(paramStr)); } JSONObject data = this.doHttpRequest(api, httpMethod, paramStr, headers); return data; } private void loadSecret() throws UnsupportedEncodingException, IOException, ParseException {
File dat = new File(this.StorLocation); // Load secret from file if(dat.exists()) { this.expires.setTimeInMillis(dat.lastModified()); this.expires.add(Calendar.HOUR, 2);
Calendar maxAge = Calendar.getInstance(); maxAge.add(Calendar.MINUTE, -1);
if(this.expires.after(maxAge)) { StringBuilder datContents = new StringBuilder((int)dat.length()); Scanner scanner = null; try { scanner = new Scanner(dat); while(scanner.hasNextLine()) { datContents.append(scanner.nextLine()); } } catch (FileNotFoundException e) { } finally { scanner.close(); } this.secret = datContents.toString(); this.expires = Calendar.getInstance(); this.expires.add(Calendar.HOUR, 2); return; } }
// Need to fetch a new secret HashMap<String,String> headers = new HashMap<String, String>(); headers.put("Rest-Key", this.pubkey); String params = "api_passphrase=" + URLEncoder.encode(this.passphrase, "UTF-8");
JSONObject data = this.doHttpRequest("getsecret", "POST", params, headers); this.secret = (String)data.get("secret"); this.expires = Calendar.getInstance(); this.expires.add(Calendar.HOUR, 2); FileWriter fw = new FileWriter(dat); try { fw.write(this.secret); } catch(IOException e) { System.out.println(e); } finally { fw.close(); } } // Perform the request private JSONObject doHttpRequest(String api, String httpMethod, String params, HashMap<String,String> headers) throws IOException, ProtocolException, ParseException { api = (httpMethod == "GET") ? api += "?" + params : api; URL uObj = new URL(this.urlBaseLoc + this.currPair + "/" + api); HttpsURLConnection conn = (HttpsURLConnection) uObj.openConnection(); conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; RMBTB Java client)"); for(Map.Entry<String, String> entry : headers.entrySet()) { conn.setRequestProperty(entry.getKey(), entry.getValue()); } if(httpMethod == "POST") { conn.setRequestMethod("POST"); conn.setDoOutput(true); DataOutputStream out = new DataOutputStream(conn.getOutputStream()); out.writeBytes(params); out.flush(); out.close(); } else { conn.setRequestMethod("GET"); } BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inLine; StringBuffer response = new StringBuffer();
while((inLine = in.readLine()) != null) { response.append(inLine); } in.close(); JSONParser parser = new JSONParser(); JSONObject respJSON = (JSONObject)(parser.parse(response.toString()));
if(respJSON.get("error").getClass().getName() != "java.lang.Boolean") { String strErr = (String)(respJSON.get("error")); throw new RuntimeException(strErr); } JSONObject data = (JSONObject)respJSON.get("data"); return data; } // Signs using HMAC private String getRequestSig(String data) throws NoSuchAlgorithmException, InvalidKeyException {
Mac mac = Mac.getInstance("HmacSHA512"); SecretKeySpec secret_spec = new SecretKeySpec(this.secret.getBytes(), "HmacSHA512"); mac.init(secret_spec); return Base64.encodeBase64String(mac.doFinal(data.getBytes())).toString(); } }
|
|
|
|
marinamao
Member
Offline
Activity: 69
Merit: 10
|
|
August 12, 2013, 05:30:45 PM |
|
完了弯了,一点都不懂这是什么东东
|
|
|
|
|
BitPirate (OP)
Full Member
Offline
Activity: 238
Merit: 100
RMBTB.com: The secure BTC:CNY exchange. 0% fee!
|
|
August 12, 2013, 11:58:09 PM |
|
完了弯了,一点都不懂这是什么东东 如果有人用java设计安卓程序的就可以用到这个了
|
|
|
|
|