Bitcoin Forum
April 27, 2024, 04:48:47 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: 人盟比特币交易型API上线,让交易,市场套利更加方便快速  (Read 1468 times)
BitPirate (OP)
Full Member
***
Offline Offline

Activity: 238
Merit: 100


RMBTB.com: The secure BTC:CNY exchange. 0% fee!


View Profile
August 04, 2013, 02:14:04 PM
Last edit: August 12, 2013, 04:34:50 PM by BitPirate
 #1

我们秉承在建立之初的宗旨,“安全、简单、快速”,所以我们不断脚踏实地的对我们的网站进行改进。

人盟比特币最新的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的例子

你可以任意使用我们的示范代码,但是请阅读以下我们的声明.

其他语言也在进行中,我们会陆续发布! 如果您想知道特定语言,也可以告知我们。






"This isn't the kind of software where we can leave so many unresolved bugs that we need a tracker for them." -- Satoshi
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
BitPirate (OP)
Full Member
***
Offline Offline

Activity: 238
Merit: 100


RMBTB.com: The secure BTC:CNY exchange. 0% fee!


View Profile
August 06, 2013, 02:25:18 PM
Last edit: August 08, 2013, 04:51:01 PM by BitPirate
 #2

Python:

Code:
# -*- 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 Offline

Activity: 238
Merit: 100


RMBTB.com: The secure BTC:CNY exchange. 0% fee!


View Profile
August 06, 2013, 02:26:35 PM
Last edit: August 07, 2013, 03:00:57 PM by BitPirate
 #3

PHP:

此代码会检查我们的SSL证书。您可以自行下载(在Firefox中,点击地址栏安全报告, 更多信息… → 查看证书… → 详细信息→ Save)然后将其保存在安全的地方.

Code:
< ? 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&gt;Pq&lt;_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 Offline

Activity: 238
Merit: 100


RMBTB.com: The secure BTC:CNY exchange. 0% fee!


View Profile
August 06, 2013, 02:32:34 PM
Last edit: August 08, 2013, 04:52:23 PM by BitPirate
 #4

JavaScript (Node.js):

Code:
/**
 *
 *  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 Offline

Activity: 1
Merit: 0


View Profile
August 07, 2013, 12:35:40 PM
 #5

get_funds 貌似不能工作,我用get_info代替了
BitPirate (OP)
Full Member
***
Offline Offline

Activity: 238
Merit: 100


RMBTB.com: The secure BTC:CNY exchange. 0% fee!


View Profile
August 07, 2013, 01:25:37 PM
 #6

get_funds 貌似不能工作,我用get_info代替了

谢谢,这个问题现在已经解决了。如果有其他问题也可以及时联系我们 Cheesy

bitcoinchina
Sr. Member
****
Offline Offline

Activity: 280
Merit: 250


View Profile
August 07, 2013, 02:32:51 PM
 #7

不错
BitPirate (OP)
Full Member
***
Offline Offline

Activity: 238
Merit: 100


RMBTB.com: The secure BTC:CNY exchange. 0% fee!


View Profile
August 08, 2013, 02:56:51 PM
 #8

不错

谢谢!  Grin

BitPirate (OP)
Full Member
***
Offline Offline

Activity: 238
Merit: 100


RMBTB.com: The secure BTC:CNY exchange. 0% fee!


View Profile
August 08, 2013, 02:58:34 PM
Last edit: August 08, 2013, 04:53:28 PM by BitPirate
 #9

还有 Ruby  Cool

Code:
#!/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
Sr. Member
****
Offline Offline

Activity: 243
Merit: 250


View Profile
August 08, 2013, 09:36:59 PM
 #10

support!

Bitrated user: azwccc.
BitPirate (OP)
Full Member
***
Offline Offline

Activity: 238
Merit: 100


RMBTB.com: The secure BTC:CNY exchange. 0% fee!


View Profile
August 12, 2013, 04:32:37 PM
 #11

support!

 Cool

BitPirate (OP)
Full Member
***
Offline Offline

Activity: 238
Merit: 100


RMBTB.com: The secure BTC:CNY exchange. 0% fee!


View Profile
August 12, 2013, 04:33:54 PM
Last edit: August 12, 2013, 11:47:50 PM by BitPirate
 #12

还有。。。Java!

Code:
/**
 * 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 Offline

Activity: 69
Merit: 10



View Profile
August 12, 2013, 05:30:45 PM
 #13

完了弯了,一点都不懂这是什么东东 Shocked

bitcoinchina
Sr. Member
****
Offline Offline

Activity: 280
Merit: 250


View Profile
August 12, 2013, 11:22:04 PM
 #14

牛东东 Grin
BitPirate (OP)
Full Member
***
Offline Offline

Activity: 238
Merit: 100


RMBTB.com: The secure BTC:CNY exchange. 0% fee!


View Profile
August 12, 2013, 11:58:09 PM
 #15

完了弯了,一点都不懂这是什么东东 Shocked

如果有人用java设计安卓程序的就可以用到这个了  Grin

Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!