xapo_sdk 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/README.md +88 -11
- data/lib/xapo_api.rb +58 -0
- data/lib/xapo_sdk/version.rb +1 -1
- data/lib/xapo_tools.rb +16 -10
- data/lib/xapo_utils.rb +20 -5
- data/test/test_xapo_api.rb +41 -0
- data/test/test_xapo_tools.rb +4 -0
- data/test/test_xapo_utils.rb +1 -0
- data/xapo_sdk.gemspec +2 -1
- metadata +22 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdaab05a3afda55428323f8265651693e3948492
|
4
|
+
data.tar.gz: 7ba9c92091a9cd8a41b570c8a8c8d8aecd450898
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dcb891c258e36aeb2cb4f35aa5ac2b7946a3a5dd4dc9fdc5df0f13c002130a6038e7977d08105eae815da584209d027be1e779468812f5e1e1289c31fea224d7
|
7
|
+
data.tar.gz: 4da60607edf072a52bf30a2d48c9612e547f914c279ee6ca3b252c1a45ff3eed3402396839d61b316bfd68761958a391a1fddb14cd3298a3c52de4cb8d689b7d
|
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -8,17 +8,21 @@
|
|
8
8
|
|
9
9
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
10
10
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
11
|
-
## Table of Contents
|
12
|
-
|
13
|
-
- [
|
14
|
-
|
15
|
-
|
16
|
-
- [
|
17
|
-
- [
|
18
|
-
- [
|
19
|
-
- [
|
20
|
-
|
21
|
-
- [
|
11
|
+
## Table of Contents
|
12
|
+
|
13
|
+
- [Build](#build)
|
14
|
+
- [Installation](#installation)
|
15
|
+
- [API](#api)
|
16
|
+
- [Credit](#credit)
|
17
|
+
- [Parameters](#parameters)
|
18
|
+
- [Result](#result)
|
19
|
+
- [Usage Example](#usage-example)
|
20
|
+
- [Micro Payment Widgets](#micro-payment-widgets)
|
21
|
+
- [IFrame Widget](#iframe-widget)
|
22
|
+
- [Div Widget](#div-widget)
|
23
|
+
- [Widgets Gallery](#widgets-gallery)
|
24
|
+
- [Contributing](#contributing)
|
25
|
+
- [TODO](#todo)
|
22
26
|
|
23
27
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
24
28
|
|
@@ -52,6 +56,79 @@ Or install it yourself as:
|
|
52
56
|
|
53
57
|
$ gem install xapo_sdk
|
54
58
|
|
59
|
+
## API
|
60
|
+
|
61
|
+
The of the API allows third party application to interact with Xapo wallets and resources in a simple and intuitive way.
|
62
|
+
|
63
|
+
|
64
|
+
Development Environment:
|
65
|
+
|
66
|
+
> http://dev.xapo.com/api/v1
|
67
|
+
|
68
|
+
### Credit
|
69
|
+
|
70
|
+
The Credit API allows any Third Party Application (TPA) to load Bitcoins into any Xapo Wallet using a secure App_ID + App_Shared_Key authentication method.
|
71
|
+
|
72
|
+
#### Parameters
|
73
|
+
|
74
|
+
- **To:** ``(string, mandatory)`` any email, BTC address or mobile number.
|
75
|
+
- **Currency:** ``(Currency, mandatory)`` any of ``Currency.BTC`` or ``Currency.SAT`` .
|
76
|
+
- **Amount:** ``(numeric, mandatory)`` amount to be credited.
|
77
|
+
- **Comments:** ``(string, optional)`` note or message to attach to the transaction.
|
78
|
+
- **Subject:** ``(string, optional)`` if specified, will be used as email subject (when crediting an email address) or SMS text (when crediting a mobile #).
|
79
|
+
- **Timestamp:** ``(int, mandatory)`` UTC Unix Timestamp. The request will be rejected if using a timestamp not equal or greater than the last used by previous request.
|
80
|
+
- **Resquest Id:** ``(string, mandatory)`` any ID that uniquely identifies this request. Cannot be repeated with any new request.
|
81
|
+
|
82
|
+
#### Result
|
83
|
+
|
84
|
+
The result is a dictionary containing:
|
85
|
+
|
86
|
+
| Key | Type | Description |
|
87
|
+
|---------| ------- | ----------- |
|
88
|
+
| success | boolean | Indicates whether the request was successfully processed or not |
|
89
|
+
| code | string | A response |
|
90
|
+
| message | string | Description of the result |
|
91
|
+
|
92
|
+
Error codes:
|
93
|
+
|
94
|
+
| Code | Message |
|
95
|
+
| --------------- | ------- |
|
96
|
+
Success | Wallet successfully credited |
|
97
|
+
InvalidRequest | Either the App token or Hash are invalid |
|
98
|
+
ExpiredRequest | The request timestamp and/or unique_request_id have expired |
|
99
|
+
InvalidWallet | Wallet not linked with this APP |
|
100
|
+
InvalidEmail | The destination email is invalid |
|
101
|
+
InvalidBTCAddress | The destination BTC address is invalid |
|
102
|
+
InvalidCellphone | The destination mobile number is invalid |
|
103
|
+
InvalidCurrency | The currency is invalid |
|
104
|
+
InvalidAmount | The amount to deposit is invalid |
|
105
|
+
MinimumAmount | The amount to deposit must be at least XXX |
|
106
|
+
InsufficientFunds | The wallet you are withdrawing from does not have enough available balance to fulfill the Deposit |
|
107
|
+
|
108
|
+
|
109
|
+
#### Usage Example
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
|
113
|
+
require "xapo_api"
|
114
|
+
require "securerandom"
|
115
|
+
|
116
|
+
...
|
117
|
+
|
118
|
+
# config the api
|
119
|
+
api = Xapo::API.new(SERVICE_URL, APP_ID, APP_SECRET)
|
120
|
+
|
121
|
+
...
|
122
|
+
|
123
|
+
# call cerdit service
|
124
|
+
res = api.credit('sample@xapo.com', 0.5, SecureRandom.hex,
|
125
|
+
currency: Xapo::Currency::BTC,
|
126
|
+
comments: "Sample deposit")
|
127
|
+
|
128
|
+
puts(res)
|
129
|
+
```
|
130
|
+
|
131
|
+
|
55
132
|
## Micro Payment Widgets
|
56
133
|
Micro payment widgets allow to dynamically get a HTML snippet pre-configured and insert into your web page. Micro payment widgets provides 4 kind of pre-configured actions __Pay, Donate, Tip__ and __Deposit__. The widgets allow the following configurations:
|
57
134
|
|
data/lib/xapo_api.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require "xapo_sdk/version"
|
2
|
+
require "xapo_utils"
|
3
|
+
|
4
|
+
require "json"
|
5
|
+
require "uri"
|
6
|
+
require "net/http"
|
7
|
+
|
8
|
+
# Xapo's API.
|
9
|
+
#
|
10
|
+
# This class allows the interaction with bitcoins APIs provided with Xapo.
|
11
|
+
#
|
12
|
+
# Attributes:
|
13
|
+
# service_url (str): The endpoint URL that returns the payment widget.
|
14
|
+
# app_id (str, optional): The id of the TPA for which the widget will be created.
|
15
|
+
# app_secret (str, optional): The TPA secret used to encrypt widget configuration.
|
16
|
+
module Xapo
|
17
|
+
|
18
|
+
module_function
|
19
|
+
|
20
|
+
module Currency
|
21
|
+
BTC = "BTC"
|
22
|
+
SAT = "SAT"
|
23
|
+
end
|
24
|
+
|
25
|
+
class API
|
26
|
+
def initialize(service_url, app_id, app_secret)
|
27
|
+
@service_url = service_url
|
28
|
+
@app_id = app_id
|
29
|
+
@app_secret = app_secret
|
30
|
+
@credit_resource = '/credit/'
|
31
|
+
end
|
32
|
+
|
33
|
+
def credit(to, amount, request_id, currency: Xapo::Currency::BTC,
|
34
|
+
comments: "", subject: "")
|
35
|
+
timestamp = XapoUtils.timestamp
|
36
|
+
payload = {
|
37
|
+
:to => to,
|
38
|
+
:currency => currency,
|
39
|
+
:amount => amount,
|
40
|
+
:comments => comments,
|
41
|
+
:subject => subject,
|
42
|
+
:timestamp => timestamp,
|
43
|
+
:unique_request_id => request_id
|
44
|
+
}
|
45
|
+
|
46
|
+
json_payload = JSON.generate(payload)
|
47
|
+
encrypted_payload = XapoUtils.encrypt(json_payload, @app_secret, false)
|
48
|
+
|
49
|
+
uri = URI(@service_url + @credit_resource)
|
50
|
+
query = URI.encode_www_form(:appID => @app_id,
|
51
|
+
:hash => encrypted_payload)
|
52
|
+
uri.query = query
|
53
|
+
res = Net::HTTP.get_response(uri)
|
54
|
+
|
55
|
+
return JSON.parse(res.body)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/xapo_sdk/version.rb
CHANGED
data/lib/xapo_tools.rb
CHANGED
@@ -29,11 +29,17 @@ module XapoTools
|
|
29
29
|
# pay_type (str): The string representing the type of operation
|
30
30
|
# ("Tip", "Pay", "Deposit" or "Donate").
|
31
31
|
def micro_payment_config
|
32
|
-
return Hash[
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
32
|
+
return Hash[
|
33
|
+
:sender_user_id => "",
|
34
|
+
:sender_user_email => "",
|
35
|
+
:sender_user_cellphone => "",
|
36
|
+
:receiver_user_id => "",
|
37
|
+
:receiver_user_email => "",
|
38
|
+
:pay_object_id => "",
|
39
|
+
:amount_BIT => 0,
|
40
|
+
:timestamp => XapoUtils.timestamp,
|
41
|
+
:pay_type => ""
|
42
|
+
]
|
37
43
|
end
|
38
44
|
|
39
45
|
# Xapo's payment buttons snippet builder.
|
@@ -58,16 +64,16 @@ module XapoTools
|
|
58
64
|
|
59
65
|
if @app_secret == nil || @app_id == nil
|
60
66
|
query_str = URI.encode_www_form(
|
61
|
-
|
62
|
-
|
67
|
+
:payload => json_config,
|
68
|
+
:customization => JSON.generate({:button_text => config[:pay_type]})
|
63
69
|
)
|
64
70
|
else
|
65
71
|
encrypted_config = XapoUtils.encrypt(json_config, @app_secret)
|
66
72
|
|
67
73
|
query_str = URI.encode_www_form(
|
68
|
-
|
69
|
-
|
70
|
-
|
74
|
+
:app_id => @app_id,
|
75
|
+
:button_request => encrypted_config,
|
76
|
+
:customization => JSON.generate({:button_text => config[:pay_type]})
|
71
77
|
)
|
72
78
|
end
|
73
79
|
|
data/lib/xapo_utils.rb
CHANGED
@@ -8,15 +8,23 @@ module XapoUtils
|
|
8
8
|
# Do PKCS#7 padding and encrypting.
|
9
9
|
#
|
10
10
|
# Args:
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
11
|
+
# payload (str): The text to encode.
|
12
|
+
# secret (str): the encoding key.
|
13
|
+
# default_padding (bool): whether it uses default padding or not
|
14
|
+
#
|
14
15
|
# Returns:
|
15
16
|
# str: The padded bytestring.
|
16
|
-
def encrypt(payload, secret)
|
17
|
+
def encrypt(payload, secret, default_padding=true)
|
17
18
|
cipher = OpenSSL::Cipher::AES.new("256-ECB")
|
18
19
|
cipher.encrypt
|
19
|
-
cipher.key = secret
|
20
|
+
cipher.key = secret
|
21
|
+
|
22
|
+
# TODO zero padding is not handled correctly, it's too specific
|
23
|
+
# and inflexible making it hard to change.
|
24
|
+
if !default_padding
|
25
|
+
cipher.padding = 0
|
26
|
+
payload = zero_padding(payload)
|
27
|
+
end
|
20
28
|
|
21
29
|
encrypted = cipher.update(payload) + cipher.final
|
22
30
|
|
@@ -24,4 +32,11 @@ module XapoUtils
|
|
24
32
|
end
|
25
33
|
|
26
34
|
def timestamp; (Time.now.to_f * 1000).to_i end
|
35
|
+
|
36
|
+
def zero_padding(payload)
|
37
|
+
l = 16 - payload.length % 16
|
38
|
+
res = payload + "\0" * l
|
39
|
+
|
40
|
+
return res
|
41
|
+
end
|
27
42
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "xapo_api"
|
3
|
+
require "securerandom"
|
4
|
+
|
5
|
+
class TestXapoAPI < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@api = Xapo::API.new(
|
8
|
+
"http://dev.xapo.com/api/v1",
|
9
|
+
"b91014cc28c94841",
|
10
|
+
"c533a6e606fb62ccb13e8baf8a95cbdc"
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_credit()
|
15
|
+
res = @api.credit('sample@xapo.com', 1, SecureRandom.hex,
|
16
|
+
currency: Xapo::Currency::SAT,
|
17
|
+
comments: "Sample deposit")
|
18
|
+
|
19
|
+
puts("test_credit -> ", res)
|
20
|
+
|
21
|
+
assert(res["success"])
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_credit_bad_ammount()
|
25
|
+
res = @api.credit('sample@xapo.com', -0.5, SecureRandom.hex)
|
26
|
+
|
27
|
+
puts("test_credit -> ", res)
|
28
|
+
|
29
|
+
refute(res["success"])
|
30
|
+
assert_equal("InvalidAmount", res["code"])
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_credit_missing_to()
|
34
|
+
res = @api.credit('', -0.5, SecureRandom.hex)
|
35
|
+
|
36
|
+
puts("test_credit -> ", res)
|
37
|
+
|
38
|
+
refute(res["success"])
|
39
|
+
assert_equal("Failure", res["code"])
|
40
|
+
end
|
41
|
+
end
|
data/test/test_xapo_tools.rb
CHANGED
@@ -24,6 +24,7 @@ class TestXapoTools < Minitest::Test
|
|
24
24
|
config[:pay_type] = PayType::DONATE
|
25
25
|
|
26
26
|
actual = @xapo_tools.build_iframe_widget(config)
|
27
|
+
puts("test_build_iframe_widget -> ", actual)
|
27
28
|
|
28
29
|
assert_match(/<iframe(.*)button_request(.*)>(.*)<\/iframe>\n/m, actual)
|
29
30
|
end
|
@@ -39,6 +40,7 @@ class TestXapoTools < Minitest::Test
|
|
39
40
|
config[:pay_type] = PayType::DONATE
|
40
41
|
|
41
42
|
actual = @xapo_tools_notpa.build_iframe_widget(config)
|
43
|
+
puts("test_build_iframe_widget_notpa -> ", actual)
|
42
44
|
|
43
45
|
assert_match(/<iframe(.*)payload(.*)>(.*)<\/iframe>\n/m, actual)
|
44
46
|
end
|
@@ -59,6 +61,7 @@ class TestXapoTools < Minitest::Test
|
|
59
61
|
/mx
|
60
62
|
|
61
63
|
actual = @xapo_tools.build_div_widget(config)
|
64
|
+
puts("test_build_div_widget -> ", actual)
|
62
65
|
|
63
66
|
assert_match(regex, actual)
|
64
67
|
end
|
@@ -79,6 +82,7 @@ class TestXapoTools < Minitest::Test
|
|
79
82
|
/mx
|
80
83
|
|
81
84
|
actual = @xapo_tools_notpa.build_div_widget(config)
|
85
|
+
puts("test_build_div_widget_notpa -> ", actual)
|
82
86
|
|
83
87
|
assert_match(regex, actual)
|
84
88
|
end
|
data/test/test_xapo_utils.rb
CHANGED
@@ -22,6 +22,7 @@ class TestXapoUtils < Minitest::Test
|
|
22
22
|
'GB++p7zK4NmOdrGEX9f+EwBjYuyKSsNez7kXPAWzwEvoi1o8gu4bxA1ng=='
|
23
23
|
|
24
24
|
actual = XapoUtils.encrypt(json, "bc4e142dc053407b0028accffc289c18").tr("\n","")
|
25
|
+
puts("test_encrypt -> \n", json, actual)
|
25
26
|
|
26
27
|
assert_equal(expected, actual)
|
27
28
|
end
|
data/xapo_sdk.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler", "~> 1.
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6.2"
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "minitest", "~> 5.4.2"
|
23
24
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xapo_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Federico Repond
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.6.2
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.6.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 5.4.2
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 5.4.2
|
41
55
|
description: Xapo bitcoin sdk & tools.
|
42
56
|
email:
|
43
57
|
- federico.repond@leapsight.com
|
@@ -46,14 +60,17 @@ extensions: []
|
|
46
60
|
extra_rdoc_files: []
|
47
61
|
files:
|
48
62
|
- ".gitignore"
|
63
|
+
- ".travis.yml"
|
49
64
|
- CHANGELOG.md
|
50
65
|
- Gemfile
|
51
66
|
- LICENSE.txt
|
52
67
|
- README.md
|
53
68
|
- Rakefile
|
69
|
+
- lib/xapo_api.rb
|
54
70
|
- lib/xapo_sdk/version.rb
|
55
71
|
- lib/xapo_tools.rb
|
56
72
|
- lib/xapo_utils.rb
|
73
|
+
- test/test_xapo_api.rb
|
57
74
|
- test/test_xapo_tools.rb
|
58
75
|
- test/test_xapo_utils.rb
|
59
76
|
- xapo_sdk.gemspec
|
@@ -82,6 +99,7 @@ signing_key:
|
|
82
99
|
specification_version: 4
|
83
100
|
summary: Xapo bitcoin sdk & tools.
|
84
101
|
test_files:
|
102
|
+
- test/test_xapo_api.rb
|
85
103
|
- test/test_xapo_tools.rb
|
86
104
|
- test/test_xapo_utils.rb
|
87
105
|
has_rdoc:
|