Bitcoin Forum
May 10, 2024, 02:24:21 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的例子

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

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






1715351061
Hero Member
*
Offline Offline

Posts: 1715351061

View Profile Personal Message (Offline)

Ignore
1715351061
Reply with quote  #2

1715351061
Report to moderator
Be very wary of relying on JavaScript for security on crypto sites. The site can change the JavaScript at any time unless you take unusual precautions, and browsers are not generally known for their airtight security.
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!