maicoin 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +50 -0
- data/LICENSE.txt +22 -0
- data/README.md +1 -0
- data/example-key-secret.rb +58 -0
- data/example-oauth.rb +41 -0
- data/lib/maicoin.rb +5 -0
- data/lib/maicoin/ca-maicoin.crt +215 -0
- data/lib/maicoin/client.rb +286 -0
- data/lib/maicoin/oauth_client.rb +78 -0
- data/lib/maicoin/version.rb +3 -0
- data/maicoin.gemspec +31 -0
- metadata +194 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ae6c23652ae277cf0cefc52422d1d14ef030a12b
|
4
|
+
data.tar.gz: 03cc2002e25a59751d9c088271bbafae7ebb5d5c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2f8beb5dbf37fc948c8d2eacc4d3a83cdba1cecf15bbd7b2f2f4a5cbba533f1c8848f2c1896cb68f777900f3eb3afeef5796fdc585203ce51db00b9fac20fdcf
|
7
|
+
data.tar.gz: cdcdea9836f9c44ae963abcbb13169c5c8ea804c56dce5dc9ccb6aced2e13992550f0dc5edcc3b5c52e40f17451b79302c5183a0b422e28d00cb433b5406276e
|
data/.gitignore
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile '~/.gitignore_global'
|
6
|
+
|
7
|
+
# Ignore bundler config.
|
8
|
+
/.bundle
|
9
|
+
|
10
|
+
# Ignore all logfiles and tempfiles.
|
11
|
+
/log/*.log
|
12
|
+
/tmp
|
13
|
+
|
14
|
+
# bundler state
|
15
|
+
.bundle
|
16
|
+
vendor/bundle/
|
17
|
+
vendor/ruby/
|
18
|
+
|
19
|
+
# scm revert files
|
20
|
+
**.orig
|
21
|
+
|
22
|
+
# Mac finder artifacts
|
23
|
+
.DS_Store
|
24
|
+
|
25
|
+
# Netbeans project directory
|
26
|
+
/nbproject/
|
27
|
+
|
28
|
+
# RubyMine project files
|
29
|
+
.idea
|
30
|
+
|
31
|
+
# Textmate project files
|
32
|
+
/*.tmproj
|
33
|
+
|
34
|
+
# Aptana/eclipse files
|
35
|
+
.project
|
36
|
+
.settings
|
37
|
+
|
38
|
+
# vim artifacts
|
39
|
+
**.swp
|
40
|
+
**.swo
|
41
|
+
|
42
|
+
.rvmrc
|
43
|
+
*.swo
|
44
|
+
|
45
|
+
# Others
|
46
|
+
Gemfile*
|
47
|
+
Rakefile
|
48
|
+
.ruby-version
|
49
|
+
.editorconfig
|
50
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 MaiCoin
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# maicoin-ruby
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'maicoin'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
# Public API
|
5
|
+
client = MaiCoin::Client.new
|
6
|
+
puts 'Get prices'
|
7
|
+
puts client.prices
|
8
|
+
puts client.prices 'USD'
|
9
|
+
|
10
|
+
puts 'Get currencies'
|
11
|
+
puts client.currencies
|
12
|
+
|
13
|
+
# Authorized API
|
14
|
+
API_KEY = ENV['API_KEY'] # Replace with your MaiCoin api key
|
15
|
+
API_SECRET = ENV['API_SECRET'] # Replace with your MaiCoin api secret
|
16
|
+
client = MaiCoin::Client.new(API_KEY, API_SECRET)
|
17
|
+
|
18
|
+
puts 'Account'
|
19
|
+
puts client.balance
|
20
|
+
puts client.user
|
21
|
+
puts client.receive_address
|
22
|
+
puts client.addresses
|
23
|
+
puts client.generate_receive_address
|
24
|
+
pin = '1234'
|
25
|
+
puts client.create_account_pin(pin)
|
26
|
+
|
27
|
+
puts 'Orders'
|
28
|
+
puts client.orders
|
29
|
+
puts client.orders(1, {limit: 10})
|
30
|
+
puts client.buy_btc 1.5
|
31
|
+
puts client.sell_btc 8.67548553
|
32
|
+
|
33
|
+
puts 'Transactions'
|
34
|
+
puts client.transactions
|
35
|
+
puts client.transactions(1, {limit: 5})
|
36
|
+
puts client.transaction('b09af0fc364a2d1b5cfe3e2a9e717dfe7309f302a9de386d')
|
37
|
+
trans = client.request_btc('yute@maicoin.com', 1, 'btc', {notes: 'Show me the coin'})
|
38
|
+
puts trans
|
39
|
+
puts client.cancel_request_btc(trans['transaction']['id'])
|
40
|
+
puts client.send_transaction('yute@maicoin.com', 0.001, 'btc', pin)
|
41
|
+
puts client.send_transaction('1FTv5Ymfq1uT9N9ZrmYRgpKw69U6grnm64', 0.0011, 'btc', pin)
|
42
|
+
|
43
|
+
puts 'Checkouts' ## Only available for merchant account
|
44
|
+
checkout = MaiCoin::CheckoutParamBuilder.new
|
45
|
+
checkout.set_checkout_data(5, 'twd', 'http://my.com/return', 'http://my.com/cancel', 'http://i.my.com/callback',
|
46
|
+
{'merchant_ref_id'=>'32', 'pos_data'=>'Test POS data', 'locale'=>'en'})
|
47
|
+
checkout.set_buyer_data('name' => 'abc', 'address1'=> 'apt 123', 'address2'=> 'road 456', 'city'=> 'sf',
|
48
|
+
'state'=> 'ca', 'zip'=> '94305', 'email'=>'abc@gmail.com',
|
49
|
+
'phone'=>'6504349399', 'country'=>'US')
|
50
|
+
checkout.add_item('description'=>'desc1', 'code'=> '1111', 'price'=> '3243', 'currency_type'=> 'twd', 'is_physical'=> true)
|
51
|
+
checkout.add_item('description'=> 'desc2', 'code'=> '2222', 'price'=> '3243', 'currency_type'=> 'twd', 'is_physical'=> false)
|
52
|
+
puts checkout.build.to_json
|
53
|
+
checkout_result = client.create_checkout(checkout.build)
|
54
|
+
puts checkout_result
|
55
|
+
puts checkout_result['checkout']['checkout_url']
|
56
|
+
|
57
|
+
puts client.checkout(checkout_result['checkout']['uid']).to_json
|
58
|
+
puts client.checkouts(2, {limit: 1}).to_json
|
data/example-oauth.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'maicoin'
|
2
|
+
|
3
|
+
#### OAuth2
|
4
|
+
client_id = ENV['CLIENT_ID'] # Replace with your MaiCoin OAuth2 application id
|
5
|
+
client_secret = ENV['CLIENT_SECRET'] # Replace with your MaiCoin OAuth2 application secret
|
6
|
+
access_token = ENV['ACCESS_TOKEN'] # Replace with user's access token
|
7
|
+
refresh_token = ENV['REFRESH_TOKEN'] # Replace with user's refresh token
|
8
|
+
|
9
|
+
user_credentials = {
|
10
|
+
:access_token => access_token,
|
11
|
+
:refresh_token => refresh_token,
|
12
|
+
:expires_at => Time.now + 7200
|
13
|
+
}
|
14
|
+
|
15
|
+
client = MaiCoin::OAuthClient.new(client_id, client_secret, user_credentials)
|
16
|
+
|
17
|
+
puts 'Account'
|
18
|
+
puts client.user
|
19
|
+
puts client.balance
|
20
|
+
pin = '1234'
|
21
|
+
puts client.create_account_pin(pin)
|
22
|
+
puts client.receive_address
|
23
|
+
puts client.addresses
|
24
|
+
puts client.generate_receive_address
|
25
|
+
|
26
|
+
puts 'Orders'
|
27
|
+
puts client.orders
|
28
|
+
puts client.orders(1, {limit: 10})
|
29
|
+
puts client.buy_btc 1.5
|
30
|
+
puts client.sell_btc 8.67548553
|
31
|
+
|
32
|
+
puts 'Transactions'
|
33
|
+
puts client.transactions
|
34
|
+
puts client.transactions(1, {limit: 5})
|
35
|
+
puts client.transaction('3186b3ed822e8db414e4a6145a45934e01e3038911ebd9ef')
|
36
|
+
trans = client.request_btc('yute@maicoin.com', 1, 'btc', {notes: 'Show me the coin'})
|
37
|
+
puts trans
|
38
|
+
puts client.cancel_request_btc(trans['transaction']['id'])
|
39
|
+
puts client.send_transaction('yute@maicoin.com', 0.001, 'btc', pin)
|
40
|
+
puts client.send_transaction('1FTv5Ymfq1uT9N9ZrmYRgpKw69U6grnm64', 0.0011, 'btc', pin)
|
41
|
+
|
data/lib/maicoin.rb
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
## DigiCert High Assurance EV Root CA
|
2
|
+
-----BEGIN CERTIFICATE-----
|
3
|
+
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
|
4
|
+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
5
|
+
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
|
6
|
+
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
|
7
|
+
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
|
8
|
+
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
|
9
|
+
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
|
10
|
+
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
|
11
|
+
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
|
12
|
+
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
|
13
|
+
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
|
14
|
+
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
|
15
|
+
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
|
16
|
+
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
|
17
|
+
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
|
18
|
+
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
|
19
|
+
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
|
20
|
+
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
|
21
|
+
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
|
22
|
+
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
|
23
|
+
+OkuE6N36B9K
|
24
|
+
-----END CERTIFICATE-----
|
25
|
+
|
26
|
+
## DigiCert Assured ID Root CA
|
27
|
+
-----BEGIN CERTIFICATE-----
|
28
|
+
MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
|
29
|
+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
30
|
+
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
|
31
|
+
b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
|
32
|
+
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
|
33
|
+
cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
|
34
|
+
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
|
35
|
+
JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
|
36
|
+
mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
|
37
|
+
wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
|
38
|
+
VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
|
39
|
+
AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
|
40
|
+
AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
|
41
|
+
BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
|
42
|
+
pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
|
43
|
+
dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
|
44
|
+
fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
|
45
|
+
NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
|
46
|
+
H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
|
47
|
+
+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
|
48
|
+
-----END CERTIFICATE-----
|
49
|
+
|
50
|
+
## DigiCert Global Root CA
|
51
|
+
-----BEGIN CERTIFICATE-----
|
52
|
+
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
|
53
|
+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
54
|
+
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
|
55
|
+
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
|
56
|
+
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
|
57
|
+
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
|
58
|
+
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
|
59
|
+
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
|
60
|
+
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
|
61
|
+
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
|
62
|
+
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
|
63
|
+
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
|
64
|
+
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
|
65
|
+
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
|
66
|
+
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
|
67
|
+
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
|
68
|
+
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
|
69
|
+
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
|
70
|
+
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
|
71
|
+
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
|
72
|
+
-----END CERTIFICATE-----
|
73
|
+
|
74
|
+
## DigiCert Assured ID Root G2
|
75
|
+
-----BEGIN CERTIFICATE-----
|
76
|
+
MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
|
77
|
+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
78
|
+
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
|
79
|
+
b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
|
80
|
+
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
|
81
|
+
cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
|
82
|
+
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
|
83
|
+
n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
|
84
|
+
biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
|
85
|
+
EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
|
86
|
+
bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
|
87
|
+
YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
|
88
|
+
AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
|
89
|
+
BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
|
90
|
+
QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
|
91
|
+
0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
|
92
|
+
lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
|
93
|
+
B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
|
94
|
+
ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
|
95
|
+
IhNzbM8m9Yop5w==
|
96
|
+
-----END CERTIFICATE-----
|
97
|
+
|
98
|
+
## DigiCert Assured ID Root G3
|
99
|
+
-----BEGIN CERTIFICATE-----
|
100
|
+
MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
|
101
|
+
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
|
102
|
+
ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
|
103
|
+
RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
|
104
|
+
UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
|
105
|
+
Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
|
106
|
+
hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
|
107
|
+
Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
|
108
|
+
RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
|
109
|
+
BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
|
110
|
+
AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
|
111
|
+
JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
|
112
|
+
6pZjamVFkpUBtA==
|
113
|
+
-----END CERTIFICATE-----
|
114
|
+
|
115
|
+
## DigiCert Global Root G2
|
116
|
+
-----BEGIN CERTIFICATE-----
|
117
|
+
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
|
118
|
+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
119
|
+
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
|
120
|
+
MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
|
121
|
+
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
|
122
|
+
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
|
123
|
+
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
|
124
|
+
2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
|
125
|
+
1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
|
126
|
+
q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
|
127
|
+
tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
|
128
|
+
vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
|
129
|
+
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
|
130
|
+
5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
|
131
|
+
1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
|
132
|
+
NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
|
133
|
+
Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
|
134
|
+
8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
|
135
|
+
pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
|
136
|
+
MrY=
|
137
|
+
-----END CERTIFICATE-----
|
138
|
+
|
139
|
+
## DigiCert Global Root G3
|
140
|
+
-----BEGIN CERTIFICATE-----
|
141
|
+
MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
|
142
|
+
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
|
143
|
+
ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
|
144
|
+
Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
|
145
|
+
EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
|
146
|
+
IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
|
147
|
+
K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
|
148
|
+
fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
|
149
|
+
Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
|
150
|
+
BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
|
151
|
+
AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
|
152
|
+
oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
|
153
|
+
sycX
|
154
|
+
-----END CERTIFICATE-----
|
155
|
+
|
156
|
+
## DigiCert Trusted Root G4
|
157
|
+
-----BEGIN CERTIFICATE-----
|
158
|
+
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
|
188
|
+
-----END CERTIFICATE-----
|
189
|
+
|
190
|
+
## Add Trust External CA Root
|
191
|
+
-----BEGIN CERTIFICATE-----
|
192
|
+
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
|
193
|
+
MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
|
194
|
+
IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
|
195
|
+
MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
|
196
|
+
FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
|
197
|
+
bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
|
198
|
+
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
|
199
|
+
H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
|
200
|
+
uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
|
201
|
+
mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
|
202
|
+
a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
|
203
|
+
E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
|
204
|
+
WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
|
205
|
+
VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
|
206
|
+
Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
|
207
|
+
cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
|
208
|
+
IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
|
209
|
+
AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
|
210
|
+
YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
|
211
|
+
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
|
212
|
+
Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
|
213
|
+
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
|
214
|
+
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
|
215
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,286 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'multi_json'
|
3
|
+
require 'hashie'
|
4
|
+
require 'money'
|
5
|
+
require 'monetize'
|
6
|
+
require 'time'
|
7
|
+
require 'securerandom'
|
8
|
+
|
9
|
+
module MaiCoin
|
10
|
+
class Client
|
11
|
+
include HTTParty
|
12
|
+
|
13
|
+
BASE_URI = 'https://api.maicoin.com/v1'
|
14
|
+
|
15
|
+
def initialize(api_key='', api_secret='', options={})
|
16
|
+
@api_key = api_key
|
17
|
+
@api_secret = api_secret
|
18
|
+
|
19
|
+
# defaults
|
20
|
+
options[:base_uri] ||= BASE_URI
|
21
|
+
@base_uri = options[:base_uri]
|
22
|
+
options[:format] ||= :json
|
23
|
+
options.each do |k,v|
|
24
|
+
self.class.send k, v
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
######### Start of API #########
|
29
|
+
|
30
|
+
### Prices
|
31
|
+
def prices (currency='TWD')
|
32
|
+
get '/prices/' + currency
|
33
|
+
end
|
34
|
+
|
35
|
+
### Currencies
|
36
|
+
def currencies
|
37
|
+
get '/currencies'
|
38
|
+
end
|
39
|
+
|
40
|
+
### Account
|
41
|
+
def balance
|
42
|
+
get '/account/balance'
|
43
|
+
end
|
44
|
+
|
45
|
+
def receive_address(currency='btc')
|
46
|
+
get "/account/receive_address/#{currency}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def addresses(currency='btc')
|
50
|
+
get "/account/addresses/#{currency}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def generate_receive_address(currency='btc', options={})
|
54
|
+
options.merge!({currency: currency})
|
55
|
+
post '/account/receive_address', options
|
56
|
+
end
|
57
|
+
|
58
|
+
def user
|
59
|
+
get '/user'
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_account_pin(pin, options={})
|
63
|
+
options.merge!( {pin: pin})
|
64
|
+
post '/user/account_pin', options
|
65
|
+
end
|
66
|
+
|
67
|
+
def update_account_pin(old_pin, new_pin, options={})
|
68
|
+
options.merge!( {old_pin: old_pin, new_pin: new_pin})
|
69
|
+
put '/user/account_pin', options
|
70
|
+
end
|
71
|
+
|
72
|
+
### Orders, options:{limit:25}
|
73
|
+
def orders (page=1, options ={})
|
74
|
+
get '/orders',{page: page}.merge(options)
|
75
|
+
end
|
76
|
+
|
77
|
+
def order (txid)
|
78
|
+
get "/orders/#{txid}"
|
79
|
+
end
|
80
|
+
|
81
|
+
def buy_btc (amount)
|
82
|
+
buy_order(amount, 'btc')
|
83
|
+
end
|
84
|
+
|
85
|
+
def buy_order(amount, currency='btc')
|
86
|
+
options = {amount: amount, type: 'buy', currency: currency}
|
87
|
+
create_order(options)
|
88
|
+
end
|
89
|
+
|
90
|
+
def sell_btc (amount)
|
91
|
+
options = {amount: amount, type: 'sell'}
|
92
|
+
create_order(options)
|
93
|
+
end
|
94
|
+
|
95
|
+
def create_order (options={})
|
96
|
+
post '/orders', options
|
97
|
+
end
|
98
|
+
|
99
|
+
### Transactions, option:{limit:25}
|
100
|
+
def transactions (page=1, options={})
|
101
|
+
get '/transactions', {page:page}.merge(options)
|
102
|
+
end
|
103
|
+
|
104
|
+
def transaction (txid)
|
105
|
+
get "/transactions/#{txid}"
|
106
|
+
end
|
107
|
+
|
108
|
+
# options:{notes: ""}
|
109
|
+
def request_btc (address, amount, currency, options = {})
|
110
|
+
request_transaction(address, amount, currency, options)
|
111
|
+
end
|
112
|
+
|
113
|
+
def cancel_request_btc (txid)
|
114
|
+
cancel_request_transaction(txid)
|
115
|
+
end
|
116
|
+
|
117
|
+
# btc transactions
|
118
|
+
def send_transaction(address, amount, currency, account_pin=nil, options={})
|
119
|
+
options.merge!( { type: 'send',
|
120
|
+
account_pin: account_pin,
|
121
|
+
currency: currency,
|
122
|
+
address: address,
|
123
|
+
amount: amount})
|
124
|
+
post '/transactions', options
|
125
|
+
end
|
126
|
+
|
127
|
+
def request_transaction(address, amount, currency, options={})
|
128
|
+
options.merge!( { type: 'request',
|
129
|
+
address: address,
|
130
|
+
amount: amount,
|
131
|
+
currency: currency})
|
132
|
+
post '/transactions', options
|
133
|
+
end
|
134
|
+
|
135
|
+
def cancel_request_transaction(txid)
|
136
|
+
delete "/transactions/#{txid}"
|
137
|
+
end
|
138
|
+
|
139
|
+
### Checkouts
|
140
|
+
def create_checkout(options = {})
|
141
|
+
post '/checkouts', options
|
142
|
+
end
|
143
|
+
|
144
|
+
def checkout(uid)
|
145
|
+
get "/checkouts/#{uid}"
|
146
|
+
end
|
147
|
+
|
148
|
+
def checkouts (page=1, options={})
|
149
|
+
get '/checkouts', {page:page}.merge(options)
|
150
|
+
end
|
151
|
+
|
152
|
+
######### End of API #########
|
153
|
+
|
154
|
+
|
155
|
+
# Wrappers for the main HTTP verbs
|
156
|
+
def get(path, options={})
|
157
|
+
http_verb :get, path, options
|
158
|
+
end
|
159
|
+
|
160
|
+
def post(path, options={})
|
161
|
+
http_verb :post, path, options
|
162
|
+
end
|
163
|
+
|
164
|
+
def put(path, options={})
|
165
|
+
http_verb :put, path, options
|
166
|
+
end
|
167
|
+
|
168
|
+
def delete(path, options={})
|
169
|
+
http_verb :delete, path, options
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.whitelisted_cert_store
|
173
|
+
@@cert_store ||= build_whitelisted_cert_store
|
174
|
+
end
|
175
|
+
|
176
|
+
def self.build_whitelisted_cert_store
|
177
|
+
path = File.expand_path(File.join(File.dirname(__FILE__), 'ca-maicoin.crt'))
|
178
|
+
|
179
|
+
certs = [ [] ]
|
180
|
+
File.readlines(path).each{|line|
|
181
|
+
next if ["\n","#"].include?(line[0])
|
182
|
+
certs.last << line
|
183
|
+
certs << [] if line == "-----END CERTIFICATE-----\n"
|
184
|
+
}
|
185
|
+
|
186
|
+
result = OpenSSL::X509::Store.new
|
187
|
+
|
188
|
+
certs.each{|lines|
|
189
|
+
next if lines.empty?
|
190
|
+
cert = OpenSSL::X509::Certificate.new(lines.join)
|
191
|
+
result.add_cert(cert)
|
192
|
+
}
|
193
|
+
|
194
|
+
result
|
195
|
+
end
|
196
|
+
|
197
|
+
def ssl_options
|
198
|
+
{ verify: true, cert_store: self.class.whitelisted_cert_store }
|
199
|
+
end
|
200
|
+
|
201
|
+
def http_verb(verb, path, options={})
|
202
|
+
|
203
|
+
nonce = options[:nonce] || (Time.now.to_f * 1e6).to_i
|
204
|
+
|
205
|
+
if [:get, :delete].include? verb
|
206
|
+
request_options = {}
|
207
|
+
path = "#{path}?#{URI.encode_www_form(options)}" if !options.empty?
|
208
|
+
hmac_message = nonce.to_s + @base_uri + path
|
209
|
+
else
|
210
|
+
request_options = {body: options.to_json}
|
211
|
+
hmac_message = nonce.to_s + @base_uri + path + options.to_json
|
212
|
+
end
|
213
|
+
|
214
|
+
signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), @api_secret, hmac_message)
|
215
|
+
|
216
|
+
headers = {
|
217
|
+
'ACCESS_KEY' => @api_key,
|
218
|
+
'ACCESS_SIGNATURE' => signature,
|
219
|
+
'ACCESS_NONCE' => nonce.to_s,
|
220
|
+
'Content-Type' => 'application/json',
|
221
|
+
}
|
222
|
+
request_options[:headers] = headers
|
223
|
+
r = self.class.send(verb, path, request_options.merge(ssl_options))
|
224
|
+
Hashie::Mash.new(JSON.parse(r.body))
|
225
|
+
end
|
226
|
+
|
227
|
+
class Error < StandardError; end
|
228
|
+
end
|
229
|
+
|
230
|
+
class CheckoutParamBuilder
|
231
|
+
|
232
|
+
def initialize
|
233
|
+
@checkout_data = {}
|
234
|
+
@buyer_data = {}
|
235
|
+
@items = []
|
236
|
+
end
|
237
|
+
|
238
|
+
def set_checkout_data(amount, currency, return_url, cancel_url, callback_url,options={})
|
239
|
+
@checkout_data.merge!({
|
240
|
+
'amount'=>amount.to_s,
|
241
|
+
'currency'=>currency.to_s,
|
242
|
+
'return_url'=>return_url.to_s,
|
243
|
+
'cancel_url'=>cancel_url.to_s,
|
244
|
+
'callback_url'=>callback_url.to_s,
|
245
|
+
'merchant_ref_id'=>options['merchant_ref_id'].to_s,
|
246
|
+
'pos_data'=>options['pos_data'].to_s,
|
247
|
+
'locale'=>options['locale'].to_s
|
248
|
+
})
|
249
|
+
end
|
250
|
+
|
251
|
+
def set_buyer_data(options={})
|
252
|
+
@buyer_data.merge!({
|
253
|
+
'buyer_name' => options['name'].to_s,
|
254
|
+
'buyer_address1' => options['address1'].to_s,
|
255
|
+
'buyer_address2' => options['address2'].to_s,
|
256
|
+
'buyer_city' => options['city'].to_s,
|
257
|
+
'buyer_state' => options['state'].to_s,
|
258
|
+
'buyer_zip' => options['zip'].to_s,
|
259
|
+
'buyer_email' => options['email'].to_s,
|
260
|
+
'buyer_phone' => options['phone'].to_s,
|
261
|
+
'buyer_country' => options['country'].to_s
|
262
|
+
})
|
263
|
+
end
|
264
|
+
|
265
|
+
def add_item(options={})
|
266
|
+
@items << {
|
267
|
+
'item' => {
|
268
|
+
'description'=>options['description'].to_s,
|
269
|
+
'code'=>options['code'].to_s,
|
270
|
+
'price'=>options['price'].to_s,
|
271
|
+
'currency'=>options['currency_type'].to_s,
|
272
|
+
'is_physical'=>options['is_physical'].to_s}
|
273
|
+
}
|
274
|
+
end
|
275
|
+
|
276
|
+
def build
|
277
|
+
buyer = {'buyer'=>@buyer_data}
|
278
|
+
items = {'items'=>@items}
|
279
|
+
result = {
|
280
|
+
'checkout' => @checkout_data.merge(buyer).merge(items)
|
281
|
+
}
|
282
|
+
return result
|
283
|
+
end
|
284
|
+
|
285
|
+
end
|
286
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'oauth2'
|
2
|
+
|
3
|
+
module MaiCoin
|
4
|
+
class OAuthClient < Client
|
5
|
+
|
6
|
+
AUTHORIZE_URL = 'https://www.maicoin.com/oauth/authorize'
|
7
|
+
TOKEN_URL = 'https://www.maicoin.com/oauth/token'
|
8
|
+
|
9
|
+
# Initializes a MaiCoin Client using OAuth 2.0 credentials
|
10
|
+
#
|
11
|
+
# @param [String] client_id this application's MaiCoin OAuth2 CLIENT_ID
|
12
|
+
# @param [String] client_secret this application's MaiCoin OAuth2 CLIENT_SECRET
|
13
|
+
# @param [Hash] user_credentials OAuth 2.0 credentials to use
|
14
|
+
# @option user_credentials [String] access_token Must pass either this or token
|
15
|
+
# @option user_credentials [String] token Must pass either this or access_token
|
16
|
+
# @option user_credentials [String] refresh_token Optional
|
17
|
+
# @option user_credentials [Integer] expires_at Optional
|
18
|
+
# @option user_credentials [Integer] expires_in Optional
|
19
|
+
#
|
20
|
+
# Please note access tokens will be automatically refreshed when expired
|
21
|
+
# Use the credentials method when finished with the client to retrieve up-to-date credentials
|
22
|
+
def initialize(client_id, client_secret, user_credentials, options={})
|
23
|
+
client_opts = {
|
24
|
+
:site => options[:base_uri] || BASE_URI,
|
25
|
+
:authorize_url => options[:authorize_url] || AUTHORIZE_URL,
|
26
|
+
:token_url => options[:token_url] || TOKEN_URL,
|
27
|
+
:ssl => {
|
28
|
+
:verify => true,
|
29
|
+
:cert_store => ::MaiCoin::Client.whitelisted_cert_store
|
30
|
+
}
|
31
|
+
}
|
32
|
+
@oauth_client = OAuth2::Client.new(client_id, client_secret, client_opts)
|
33
|
+
token_hash = user_credentials.dup
|
34
|
+
token_hash[:access_token] ||= token_hash[:token]
|
35
|
+
token_hash.delete :expires
|
36
|
+
raise "No access token provided" unless token_hash[:access_token]
|
37
|
+
@oauth_token = OAuth2::AccessToken.from_hash(@oauth_client, token_hash)
|
38
|
+
end
|
39
|
+
|
40
|
+
def http_verb(verb, path, options={})
|
41
|
+
path = remove_leading_slash(path)
|
42
|
+
|
43
|
+
if [:get, :delete].include? verb
|
44
|
+
request_options = {params: options}
|
45
|
+
else
|
46
|
+
request_options = {headers: {"Content-Type" => "application/json"}, body: options.to_json}
|
47
|
+
end
|
48
|
+
response = nil
|
49
|
+
begin
|
50
|
+
response = oauth_token.request(verb, path, request_options)
|
51
|
+
rescue Exception => e
|
52
|
+
response = e.response
|
53
|
+
end
|
54
|
+
Hashie::Mash.new(JSON.parse(response.body))
|
55
|
+
end
|
56
|
+
|
57
|
+
def refresh!
|
58
|
+
raise "Access token not initialized." unless @oauth_token
|
59
|
+
@oauth_token = @oauth_token.refresh!
|
60
|
+
end
|
61
|
+
|
62
|
+
def oauth_token
|
63
|
+
raise "Access token not initialized." unless @oauth_token
|
64
|
+
refresh! if @oauth_token.expired?
|
65
|
+
@oauth_token
|
66
|
+
end
|
67
|
+
|
68
|
+
def credentials
|
69
|
+
@oauth_token.to_hash
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def remove_leading_slash(path)
|
75
|
+
path.sub(/^\//, '')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/maicoin.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'maicoin/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "maicoin"
|
8
|
+
spec.version = MaiCoin::VERSION
|
9
|
+
spec.authors = ["MaiCoin"]
|
10
|
+
spec.email = [""]
|
11
|
+
spec.summary = [""]
|
12
|
+
spec.description = [""]
|
13
|
+
spec.homepage = ""
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency "fakeweb", "~> 1.3.0"
|
23
|
+
spec.add_development_dependency 'simplecov', '~> 0.7.1'
|
24
|
+
|
25
|
+
spec.add_dependency "httparty", ">= 0.8.3"
|
26
|
+
spec.add_dependency "multi_json", ">= 1.3.4"
|
27
|
+
spec.add_dependency "money", "~> 6.0"
|
28
|
+
spec.add_dependency "monetize", "~> 0.3.0"
|
29
|
+
spec.add_dependency "hashie", ">= 1.2.0"
|
30
|
+
spec.add_dependency "oauth2", "~> 1.0"
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: maicoin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- MaiCoin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: fakeweb
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.3.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.3.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.7.1
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.7.1
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: httparty
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.8.3
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.8.3
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: multi_json
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.3.4
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.3.4
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: money
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '6.0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '6.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: monetize
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.3.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.3.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: hashie
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 1.2.0
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 1.2.0
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: oauth2
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '1.0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '1.0'
|
153
|
+
description: '[""]'
|
154
|
+
email:
|
155
|
+
- ''
|
156
|
+
executables: []
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- ".gitignore"
|
161
|
+
- LICENSE.txt
|
162
|
+
- README.md
|
163
|
+
- example-key-secret.rb
|
164
|
+
- example-oauth.rb
|
165
|
+
- lib/maicoin.rb
|
166
|
+
- lib/maicoin/ca-maicoin.crt
|
167
|
+
- lib/maicoin/client.rb
|
168
|
+
- lib/maicoin/oauth_client.rb
|
169
|
+
- lib/maicoin/version.rb
|
170
|
+
- maicoin.gemspec
|
171
|
+
homepage: ''
|
172
|
+
licenses: []
|
173
|
+
metadata: {}
|
174
|
+
post_install_message:
|
175
|
+
rdoc_options: []
|
176
|
+
require_paths:
|
177
|
+
- lib
|
178
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
requirements: []
|
189
|
+
rubyforge_project:
|
190
|
+
rubygems_version: 2.4.3
|
191
|
+
signing_key:
|
192
|
+
specification_version: 4
|
193
|
+
summary: '[""]'
|
194
|
+
test_files: []
|