liberty_reserve 0.1.0
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.
- data/LICENSE +1 -0
- data/README.md +2 -0
- data/lib/liberty_reserve.rb +3 -0
- data/lib/liberty_reserve/client.rb +238 -0
- data/lib/liberty_reserve/version.rb +5 -0
- metadata +72 -0
data/LICENSE
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
License goes here
|
data/README.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require 'cgi'
|
|
3
|
+
require 'nokogiri'
|
|
4
|
+
require 'digest'
|
|
5
|
+
require 'bigdecimal'
|
|
6
|
+
require 'net/https'
|
|
7
|
+
|
|
8
|
+
module LibertyReserve #:nodoc:
|
|
9
|
+
|
|
10
|
+
# The Liberty Reserve client, you must instantiate a client for each account API you are using.
|
|
11
|
+
#
|
|
12
|
+
# <b>Usage example :</b>
|
|
13
|
+
#
|
|
14
|
+
# lr = LibertyReserve::Client("U6542567", "MySecret", "My API name")
|
|
15
|
+
# lr.get_balance("LRUSD").to_f
|
|
16
|
+
# => 42.0
|
|
17
|
+
class Client
|
|
18
|
+
# Default Liberty Reserve API URI
|
|
19
|
+
API_URI = "https://api.libertyreserve.com/"
|
|
20
|
+
|
|
21
|
+
# Instantiates a client which will authenticate against the Liberty Reserve API
|
|
22
|
+
# using the supplied credentials :
|
|
23
|
+
# * +account+ : The Liberty Reserve account
|
|
24
|
+
# * +secret+ : The secret word defined for the particular API
|
|
25
|
+
# * +api_name+ : The API name defined in its parameters
|
|
26
|
+
#
|
|
27
|
+
# Returns a client instance to query the Liberty Reserve API.
|
|
28
|
+
#
|
|
29
|
+
# <b>Note</b> : all the API calls must be explicitly allowed in the Liberty Reserve API settings.
|
|
30
|
+
def initialize(account, secret, api_name, options = {})
|
|
31
|
+
super
|
|
32
|
+
|
|
33
|
+
defaults = {
|
|
34
|
+
api_uri: API_URI,
|
|
35
|
+
verify_peer: true
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@account = account
|
|
39
|
+
@secret = secret
|
|
40
|
+
@api_name = api_name
|
|
41
|
+
@options = defaults.merge options
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns the details of a given Liberty Reserve transaction given its ID
|
|
45
|
+
#
|
|
46
|
+
# lr = LibertyReserve::Client("U6542567", "MySecret", "My API name")
|
|
47
|
+
# lr.get_transaction("R836232")
|
|
48
|
+
# => {
|
|
49
|
+
# currency: "LRUSD",
|
|
50
|
+
# receipt_id: "R836232",
|
|
51
|
+
# payer_account: "U3832029",
|
|
52
|
+
# fee: BigDecimal("1.0"),
|
|
53
|
+
# transferred_amount: BigDecimal("100.0"),
|
|
54
|
+
# net_amount: BigDecimal("99.0")
|
|
55
|
+
# }
|
|
56
|
+
def get_transaction(transaction_id)
|
|
57
|
+
account_id = @account
|
|
58
|
+
|
|
59
|
+
r = send_request("history") do |xml|
|
|
60
|
+
xml.HistoryRequest :id => random_id do
|
|
61
|
+
authentication_block(xml)
|
|
62
|
+
|
|
63
|
+
xml.History do
|
|
64
|
+
xml.AccountId account_id
|
|
65
|
+
xml.ReceiptId transaction_id
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
format_transaction(r["HistoryResponse"]["Receipt"])
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Returns the current balance of the account in the supplied currency (LRUSD, LREUR or LRGLD)
|
|
74
|
+
#
|
|
75
|
+
# lr = LibertyReserve::Client("U6542567", "MySecret", "My API name")
|
|
76
|
+
# lr.get_balance("LRUSD").to_f
|
|
77
|
+
# => 340.35
|
|
78
|
+
def get_balance(currency)
|
|
79
|
+
account_id = @account
|
|
80
|
+
|
|
81
|
+
r = send_request("balance") do |xml|
|
|
82
|
+
xml.BalanceRequest :id => random_id do
|
|
83
|
+
authentication_block(xml)
|
|
84
|
+
|
|
85
|
+
xml.Balance do
|
|
86
|
+
xml.CurrencyId currency.to_s.upcase
|
|
87
|
+
xml.AccountId account_id
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
r["BalanceResponse"]["Balance"]["Value"].to_d
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Performs and account-to-account transfer to an aribitrary account, a memo can optionnally be supplied
|
|
96
|
+
#
|
|
97
|
+
# lr = LibertyReserve::Client("U6542567", "MySecret", "My API name")
|
|
98
|
+
# lr.transfer("U987655", 42.0, "LRUSD", :memo => "Hi there!")
|
|
99
|
+
# => "R345241"
|
|
100
|
+
def transfer(account, amount, currency, options = {})
|
|
101
|
+
send_request("transfer") do |xml|
|
|
102
|
+
xml.TransferRequest :id => random_id do
|
|
103
|
+
authentication_block(xml)
|
|
104
|
+
|
|
105
|
+
xml.Transfer do
|
|
106
|
+
xml.TransferType "transfer"
|
|
107
|
+
xml.Payer @account
|
|
108
|
+
xml.Payee account
|
|
109
|
+
xml.CurrencyId currency
|
|
110
|
+
xml.Amount amount
|
|
111
|
+
xml.Anonymous "false"
|
|
112
|
+
xml.Memo(options[:memo] || "")
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Returns the name of an account given its account number
|
|
119
|
+
#
|
|
120
|
+
# lr = LibertyReserve::Client("U6542567", "MySecret", "My API name")
|
|
121
|
+
# lr.get_name("U7262182")
|
|
122
|
+
# => "Alice"
|
|
123
|
+
def get_name(account)
|
|
124
|
+
r = send_request("accountname") do |xml|
|
|
125
|
+
xml.AccountNameRequest :id => random_id do
|
|
126
|
+
authentication_block(xml)
|
|
127
|
+
xml.AccountName do
|
|
128
|
+
xml.AccountId @account
|
|
129
|
+
xml.AccountToRetrieve account
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
r["AccountNameResponse"]["AccountName"]["Name"]
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Returns the history for an account given a currency as an array of transactions,
|
|
138
|
+
# see +get_transaction+ for the transaction format.
|
|
139
|
+
# Direction
|
|
140
|
+
# +direction+ can be any of :incoming, :outgoing, :any
|
|
141
|
+
def get_history(currency, till = DateTime.now, from = DateTime.now.advance(days: -14), options = {})
|
|
142
|
+
defaults = {
|
|
143
|
+
direction: 'any',
|
|
144
|
+
page_size: 20,
|
|
145
|
+
page_number: 1
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
opts = defaults.merge(options)
|
|
149
|
+
|
|
150
|
+
raise ArgumentError unless [:any, :outgoing, :incoming].include?(opts[:direction].to_sym)
|
|
151
|
+
|
|
152
|
+
r = send_request("history") do |xml|
|
|
153
|
+
xml.HistoryRequest :id => random_id do
|
|
154
|
+
authentication_block(xml)
|
|
155
|
+
xml.History do
|
|
156
|
+
xml.CurrencyId currency
|
|
157
|
+
xml.From from.strftime("%Y-%d-%m 00:00:00")
|
|
158
|
+
xml.Till till.strftime("%Y-%d-%m 23:59:59")
|
|
159
|
+
xml.CorrespondingAccountId opts[:corresponding_account_id] if opts[:corresponding_account_id]
|
|
160
|
+
xml.TransferType opts[:transfer_type] if opts[:transfer_type]
|
|
161
|
+
xml.Source opts[:source] if opts[:source]
|
|
162
|
+
xml.Direction opts[:direction].to_s
|
|
163
|
+
xml.AccountId @account
|
|
164
|
+
xml.Pager do |pager|
|
|
165
|
+
pager.PageSize opts[:page_size]
|
|
166
|
+
pager.PageNumber opts[:page_number]
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
if r["HistoryResponse"]["Pager"]["TotalCount"] != "0"
|
|
173
|
+
[r["HistoryResponse"]["Receipt"]].flatten.map { |t| format_transaction(t) }.compact
|
|
174
|
+
else
|
|
175
|
+
[]
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
private
|
|
181
|
+
|
|
182
|
+
def send_request(operation)
|
|
183
|
+
result = nil
|
|
184
|
+
uri = URI.parse(@options[:api_uri])
|
|
185
|
+
|
|
186
|
+
connection = Net::HTTP.new(uri.host, '443')
|
|
187
|
+
connection.use_ssl = true
|
|
188
|
+
connection.verify_mode = OpenSSL::SSL::VERIFY_PEER if @options[:verify_peer]
|
|
189
|
+
|
|
190
|
+
connection.start do |http|
|
|
191
|
+
req = Net::HTTP::Get.new("/xml/#{operation}.aspx?req=#{generate_xml{ |xml| yield(xml) }}")
|
|
192
|
+
response = http.request(req)
|
|
193
|
+
result = Hash.from_xml(response.body)
|
|
194
|
+
puts response.body
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
op = operation == "accountname" ? "account_name" : operation
|
|
198
|
+
|
|
199
|
+
if result["#{op.camelize}Response"]['Error']
|
|
200
|
+
raise "#{result["#{op.camelize}Response"]['Error']['Code']} - #{result["#{op.camelize}Response"]['Error']['Text']}"
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
result
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def generate_xml
|
|
207
|
+
request = Nokogiri::XML::Builder.new { |xml| yield(xml) }
|
|
208
|
+
puts request.to_xml
|
|
209
|
+
CGI::escape(request.to_xml)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def format_transaction(t)
|
|
213
|
+
{
|
|
214
|
+
currency: t["Transfer"]["CurrencyId"],
|
|
215
|
+
receipt_id: t["ReceiptId"],
|
|
216
|
+
payer_account: t["Transfer"]["Payer"],
|
|
217
|
+
fee: BigDecimal(t["Fee"]),
|
|
218
|
+
transferred_amount: BigDecimal(t["Amount"]),
|
|
219
|
+
net_amount: BigDecimal(t["Amount"]) - BigDecimal(t["Fee"]),
|
|
220
|
+
}
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def authentication_block(xml)
|
|
224
|
+
token = "#{@secret}:#{DateTime.now.new_offset(0).strftime("%Y%m%d:%H")}"
|
|
225
|
+
token = Digest::SHA2.hexdigest(token).upcase
|
|
226
|
+
|
|
227
|
+
xml.Auth do
|
|
228
|
+
xml.ApiName @api_name
|
|
229
|
+
xml.Token token
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def random_id
|
|
234
|
+
(rand * 10 ** 9).to_i
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
metadata
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: liberty_reserve
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- David FRANCOIS
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2011-09-04 00:00:00.000000000Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: nokogiri
|
|
16
|
+
requirement: &70170790609540 !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: 1.5.0
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: *70170790609540
|
|
25
|
+
- !ruby/object:Gem::Dependency
|
|
26
|
+
name: mocha
|
|
27
|
+
requirement: &70170790609160 !ruby/object:Gem::Requirement
|
|
28
|
+
none: false
|
|
29
|
+
requirements:
|
|
30
|
+
- - ! '>='
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: *70170790609160
|
|
36
|
+
description: Accesses the Liberty Reserve API
|
|
37
|
+
email:
|
|
38
|
+
- david@bitcoin-central.net
|
|
39
|
+
executables: []
|
|
40
|
+
extensions: []
|
|
41
|
+
extra_rdoc_files: []
|
|
42
|
+
files:
|
|
43
|
+
- lib/liberty_reserve/client.rb
|
|
44
|
+
- lib/liberty_reserve/version.rb
|
|
45
|
+
- lib/liberty_reserve.rb
|
|
46
|
+
- LICENSE
|
|
47
|
+
- README.md
|
|
48
|
+
homepage: https://github.com/davout/liberty_reserve
|
|
49
|
+
licenses: []
|
|
50
|
+
post_install_message:
|
|
51
|
+
rdoc_options: []
|
|
52
|
+
require_paths:
|
|
53
|
+
- lib
|
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
|
+
none: false
|
|
56
|
+
requirements:
|
|
57
|
+
- - ! '>='
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '0'
|
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
61
|
+
none: false
|
|
62
|
+
requirements:
|
|
63
|
+
- - ! '>='
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: 1.3.6
|
|
66
|
+
requirements: []
|
|
67
|
+
rubyforge_project:
|
|
68
|
+
rubygems_version: 1.8.6
|
|
69
|
+
signing_key:
|
|
70
|
+
specification_version: 3
|
|
71
|
+
summary: A Liberty Reserve API client for Ruby and Rails
|
|
72
|
+
test_files: []
|