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 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: []