liberty_reserve 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1 @@
1
+ License goes here
@@ -0,0 +1,2 @@
1
+ = Liberty Reserve API client
2
+ This gem makes it easy to connect to the Liberty Reserve interface and perform the operations exposed by the XML API.
@@ -0,0 +1,3 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'liberty_reserve/version'
3
+ require 'liberty_reserve/client'
@@ -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
+
@@ -0,0 +1,5 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module LibertyReserve
3
+ # Liberty Reserve gem version
4
+ VERSION = "0.1.0"
5
+ end
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: []