buda_api 1.0.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/README.md ADDED
@@ -0,0 +1,526 @@
1
+ # Unofficial Buda API Ruby SDK
2
+
3
+ A comprehensive Ruby SDK for [Buda.com](https://buda.com) cryptocurrency exchange API with built-in debugging, error handling, and extensive examples.
4
+
5
+ [![Ruby](https://img.shields.io/badge/Ruby-2.7%2B-red)](https://ruby-lang.org)
6
+ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
+ [![Documentation](https://img.shields.io/badge/Documentation-YARD-blue)](https://rubydoc.info/)
8
+
9
+ ## Features
10
+
11
+ - โœ… **Complete API Coverage** - All public and authenticated endpoints
12
+ - ๐Ÿ›ก๏ธ **Robust Error Handling** - Comprehensive exception handling with detailed error context
13
+ - ๐Ÿ” **Debug Mode** - Detailed HTTP request/response logging for development
14
+ - ๐Ÿ“Š **Rich Data Models** - Object-oriented response models with helper methods
15
+ - ๐Ÿ” **Secure Authentication** - HMAC-SHA384 authentication with automatic signature generation
16
+ - โšก **Automatic Retries** - Built-in retry logic for transient failures
17
+ - ๐Ÿ“– **Extensive Documentation** - Complete API reference and examples
18
+ - ๐Ÿงช **Comprehensive Examples** - Real-world usage examples including a trading bot
19
+
20
+ ## Installation
21
+
22
+ Add this line to your application's Gemfile:
23
+
24
+ ```ruby
25
+ gem 'buda_api'
26
+ ```
27
+
28
+ And then execute:
29
+
30
+ ```bash
31
+ $ bundle install
32
+ ```
33
+
34
+ Or install it yourself as:
35
+
36
+ ```bash
37
+ $ gem install buda_api
38
+ ```
39
+
40
+ ## Quick Start
41
+
42
+ ### Public API (No Authentication Required)
43
+
44
+ ```ruby
45
+ require 'buda_api'
46
+
47
+ # Create a public client
48
+ client = BudaApi.public_client
49
+
50
+ # Get all markets
51
+ markets = client.markets
52
+ puts "Available markets: #{markets.map(&:id).join(', ')}"
53
+
54
+ # Get ticker information
55
+ ticker = client.ticker("BTC-CLP")
56
+ puts "BTC-CLP price: #{ticker.last_price}"
57
+ puts "24h change: #{ticker.price_variation_24h}%"
58
+
59
+ # Get order book
60
+ order_book = client.order_book("BTC-CLP")
61
+ puts "Best ask: #{order_book.best_ask.price}"
62
+ puts "Best bid: #{order_book.best_bid.price}"
63
+ puts "Spread: #{order_book.spread_percentage}%"
64
+ ```
65
+
66
+ ### Authenticated API (Trading)
67
+
68
+ ```ruby
69
+ require 'buda_api'
70
+
71
+ # Create authenticated client
72
+ client = BudaApi.authenticated_client(
73
+ api_key: "your_api_key",
74
+ api_secret: "your_api_secret"
75
+ )
76
+
77
+ # Check your balance
78
+ balance = client.balance("BTC")
79
+ puts "Available BTC: #{balance.available_amount}"
80
+
81
+ # Place a limit buy order
82
+ order = client.place_order("BTC-CLP", "Bid", "limit", 0.001, 50000000)
83
+ puts "Order placed: #{order.id}"
84
+
85
+ # Cancel the order
86
+ cancelled = client.cancel_order(order.id)
87
+ puts "Order cancelled: #{cancelled.state}"
88
+ ```
89
+
90
+ ## Configuration
91
+
92
+ Configure the SDK globally:
93
+
94
+ ```ruby
95
+ BudaApi.configure do |config|
96
+ config.debug_mode = true # Enable debug logging
97
+ config.timeout = 30 # Request timeout in seconds
98
+ config.retries = 3 # Number of retry attempts
99
+ config.logger_level = :info # Logging level
100
+ config.base_url = "https://www.buda.com/api/v2/" # API base URL
101
+ end
102
+ ```
103
+
104
+ ## API Reference
105
+
106
+ ### Public API Methods
107
+
108
+ #### Markets
109
+
110
+ ```ruby
111
+ # Get all available markets
112
+ markets = client.markets
113
+ # Returns: Array<BudaApi::Models::Market>
114
+
115
+ # Get specific market details
116
+ market = client.market_details("BTC-CLP")
117
+ # Returns: BudaApi::Models::Market
118
+ ```
119
+
120
+ #### Market Data
121
+
122
+ ```ruby
123
+ # Get ticker information
124
+ ticker = client.ticker("BTC-CLP")
125
+ # Returns: BudaApi::Models::Ticker
126
+
127
+ # Get order book
128
+ order_book = client.order_book("BTC-CLP")
129
+ # Returns: BudaApi::Models::OrderBook
130
+
131
+ # Get recent trades
132
+ trades = client.trades("BTC-CLP", limit: 50)
133
+ # Returns: BudaApi::Models::Trades
134
+ ```
135
+
136
+ #### Quotations
137
+
138
+ ```ruby
139
+ # Get price quotation for buying 0.1 BTC at market price
140
+ quote = client.quotation("BTC-CLP", "bid_given_size", 0.1)
141
+ # Returns: BudaApi::Models::Quotation
142
+
143
+ # Get price quotation with limit price
144
+ quote = client.quotation_limit("BTC-CLP", "ask_given_size", 0.1, 60000000)
145
+ # Returns: BudaApi::Models::Quotation
146
+ ```
147
+
148
+ #### Reports
149
+
150
+ ```ruby
151
+ # Get average price report
152
+ start_time = Time.now - 86400 # 24 hours ago
153
+ avg_prices = client.average_prices_report("BTC-CLP", start_at: start_time)
154
+ # Returns: Array<BudaApi::Models::AveragePrice>
155
+
156
+ # Get candlestick data
157
+ candles = client.candlestick_report("BTC-CLP", start_at: start_time)
158
+ # Returns: Array<BudaApi::Models::Candlestick>
159
+ ```
160
+
161
+ ### Authenticated API Methods
162
+
163
+ #### Account Information
164
+
165
+ ```ruby
166
+ # Get balance for specific currency
167
+ balance = client.balance("BTC")
168
+ # Returns: BudaApi::Models::Balance
169
+
170
+ # Get balance events with filtering
171
+ events = client.balance_events(
172
+ currencies: ["BTC", "CLP"],
173
+ event_names: ["deposit_confirm", "withdrawal_confirm"],
174
+ page: 1,
175
+ per_page: 50
176
+ )
177
+ # Returns: Hash with :events and :total_count
178
+ ```
179
+
180
+ #### Trading
181
+
182
+ ```ruby
183
+ # Place orders
184
+ buy_order = client.place_order("BTC-CLP", "Bid", "limit", 0.001, 50000000)
185
+ sell_order = client.place_order("BTC-CLP", "Ask", "market", 0.001)
186
+
187
+ # Get order history
188
+ orders = client.orders("BTC-CLP", page: 1, per_page: 100, state: "traded")
189
+ # Returns: BudaApi::Models::OrderPages
190
+
191
+ # Get specific order details
192
+ order = client.order_details(12345)
193
+ # Returns: BudaApi::Models::Order
194
+
195
+ # Cancel order
196
+ cancelled = client.cancel_order(12345)
197
+ # Returns: BudaApi::Models::Order
198
+
199
+ # Batch operations (cancel multiple, place multiple)
200
+ result = client.batch_orders(
201
+ cancel_orders: [123, 456],
202
+ place_orders: [
203
+ { type: "Bid", price_type: "limit", amount: "0.001", limit: "50000" }
204
+ ]
205
+ )
206
+ ```
207
+
208
+ #### Transfers
209
+
210
+ ```ruby
211
+ # Get withdrawals
212
+ withdrawals = client.withdrawals("BTC", page: 1, per_page: 20)
213
+ # Returns: Hash with :withdrawals and :meta
214
+
215
+ # Get deposits
216
+ deposits = client.deposits("BTC", page: 1, per_page: 20)
217
+ # Returns: Hash with :deposits and :meta
218
+
219
+ # Simulate withdrawal (calculate fees without executing)
220
+ simulation = client.simulate_withdrawal("BTC", 0.01)
221
+ # Returns: BudaApi::Models::Withdrawal
222
+
223
+ # Execute withdrawal
224
+ withdrawal = client.withdrawal("BTC", 0.01, "destination_address")
225
+ # Returns: BudaApi::Models::Withdrawal
226
+ ```
227
+
228
+ ## Error Handling
229
+
230
+ The SDK provides comprehensive error handling with specific exception classes:
231
+
232
+ ```ruby
233
+ begin
234
+ ticker = client.ticker("INVALID-MARKET")
235
+ rescue BudaApi::ValidationError => e
236
+ puts "Validation failed: #{e.message}"
237
+ rescue BudaApi::NotFoundError => e
238
+ puts "Resource not found: #{e.message}"
239
+ rescue BudaApi::AuthenticationError => e
240
+ puts "Authentication failed: #{e.message}"
241
+ rescue BudaApi::RateLimitError => e
242
+ puts "Rate limit exceeded: #{e.message}"
243
+ rescue BudaApi::ServerError => e
244
+ puts "Server error: #{e.message}"
245
+ rescue BudaApi::ConnectionError => e
246
+ puts "Connection failed: #{e.message}"
247
+ rescue BudaApi::ApiError => e
248
+ puts "API error: #{e.message}"
249
+ puts "Status: #{e.status_code}"
250
+ puts "Response: #{e.response_body}"
251
+ end
252
+ ```
253
+
254
+ ### Exception Hierarchy
255
+
256
+ ```
257
+ BudaApi::ApiError (base class)
258
+ โ”œโ”€โ”€ BudaApi::AuthenticationError # 401 errors
259
+ โ”œโ”€โ”€ BudaApi::AuthorizationError # 403 errors
260
+ โ”œโ”€โ”€ BudaApi::BadRequestError # 400 errors
261
+ โ”œโ”€โ”€ BudaApi::NotFoundError # 404 errors
262
+ โ”œโ”€โ”€ BudaApi::RateLimitError # 429 errors
263
+ โ”œโ”€โ”€ BudaApi::ServerError # 5xx errors
264
+ โ”œโ”€โ”€ BudaApi::ConnectionError # Network issues
265
+ โ”œโ”€โ”€ BudaApi::TimeoutError # Request timeouts
266
+ โ””โ”€โ”€ BudaApi::InvalidResponseError # Invalid response format
267
+
268
+ BudaApi::ValidationError # Parameter validation
269
+ BudaApi::ConfigurationError # SDK configuration issues
270
+ ```
271
+
272
+ ## Debugging
273
+
274
+ Enable debug mode to see detailed HTTP request/response logs:
275
+
276
+ ```ruby
277
+ BudaApi.configure do |config|
278
+ config.debug_mode = true
279
+ config.logger_level = :debug
280
+ end
281
+
282
+ # All requests will now show detailed logs:
283
+ # โ†’ GET https://www.buda.com/api/v2/markets/BTC-CLP/ticker
284
+ # โ†’ Headers: {"User-Agent"=>"BudaApi Ruby SDK 1.0.0"}
285
+ # โ† 200
286
+ # โ† Headers: {"content-type"=>"application/json"}
287
+ # โ† Body: {"ticker": {...}}
288
+ # โ† Duration: 150ms
289
+ ```
290
+
291
+ ## Data Models
292
+
293
+ All API responses are wrapped in rich data model objects with helper methods:
294
+
295
+ ### Market Model
296
+
297
+ ```ruby
298
+ market = client.market_details("BTC-CLP")
299
+
300
+ market.id # => "BTC-CLP"
301
+ market.name # => "Bitcoin/Chilean Peso"
302
+ market.base_currency # => "BTC"
303
+ market.quote_currency # => "CLP"
304
+ market.minimum_order_amount # => #<BudaApi::Models::Amount>
305
+ ```
306
+
307
+ ### Ticker Model
308
+
309
+ ```ruby
310
+ ticker = client.ticker("BTC-CLP")
311
+
312
+ ticker.last_price # => #<BudaApi::Models::Amount>
313
+ ticker.min_ask # => #<BudaApi::Models::Amount>
314
+ ticker.max_bid # => #<BudaApi::Models::Amount>
315
+ ticker.volume # => #<BudaApi::Models::Amount>
316
+ ticker.price_variation_24h # => -2.5 (percentage)
317
+ ticker.price_variation_7d # => 10.3 (percentage)
318
+ ```
319
+
320
+ ### OrderBook Model
321
+
322
+ ```ruby
323
+ order_book = client.order_book("BTC-CLP")
324
+
325
+ order_book.asks # => Array<BudaApi::Models::OrderBookEntry>
326
+ order_book.bids # => Array<BudaApi::Models::OrderBookEntry>
327
+ order_book.best_ask # => #<BudaApi::Models::OrderBookEntry>
328
+ order_book.best_bid # => #<BudaApi::Models::OrderBookEntry>
329
+ order_book.spread # => 50000.0 (price difference)
330
+ order_book.spread_percentage # => 0.12 (percentage)
331
+ ```
332
+
333
+ ### Order Model
334
+
335
+ ```ruby
336
+ order = client.order_details(12345)
337
+
338
+ order.id # => 12345
339
+ order.state # => "traded"
340
+ order.type # => "Bid"
341
+ order.amount # => #<BudaApi::Models::Amount>
342
+ order.limit # => #<BudaApi::Models::Amount>
343
+ order.traded_amount # => #<BudaApi::Models::Amount>
344
+ order.filled_percentage # => 100.0
345
+ order.is_filled? # => true
346
+ order.is_active? # => false
347
+ order.is_cancelled? # => false
348
+ ```
349
+
350
+ ### Balance Model
351
+
352
+ ```ruby
353
+ balance = client.balance("BTC")
354
+
355
+ balance.currency # => "BTC"
356
+ balance.amount # => #<BudaApi::Models::Amount> (total)
357
+ balance.available_amount # => #<BudaApi::Models::Amount>
358
+ balance.frozen_amount # => #<BudaApi::Models::Amount>
359
+ balance.pending_withdraw_amount # => #<BudaApi::Models::Amount>
360
+ ```
361
+
362
+ ## Examples
363
+
364
+ The SDK includes comprehensive examples in the `examples/` directory:
365
+
366
+ ### Basic Examples
367
+
368
+ - [`public_api_example.rb`](examples/public_api_example.rb) - Public API usage
369
+ - [`authenticated_api_example.rb`](examples/authenticated_api_example.rb) - Authenticated API usage
370
+ - [`error_handling_example.rb`](examples/error_handling_example.rb) - Error handling and debugging
371
+
372
+ ### Advanced Examples
373
+
374
+ - [`trading_bot_example.rb`](examples/trading_bot_example.rb) - Simple trading bot with price monitoring
375
+
376
+ ### Running Examples
377
+
378
+ 1. Copy the environment file:
379
+ ```bash
380
+ cp examples/.env.example examples/.env
381
+ ```
382
+
383
+ 2. Edit `.env` and add your API credentials:
384
+ ```bash
385
+ BUDA_API_KEY=your_api_key_here
386
+ BUDA_API_SECRET=your_api_secret_here
387
+ ```
388
+
389
+ 3. Run the examples:
390
+ ```bash
391
+ # Public API example (no credentials needed)
392
+ ruby examples/public_api_example.rb
393
+
394
+ # Authenticated API example (requires credentials)
395
+ ruby examples/authenticated_api_example.rb
396
+
397
+ # Error handling example
398
+ ruby examples/error_handling_example.rb
399
+
400
+ # Trading bot example (requires credentials)
401
+ ruby examples/trading_bot_example.rb BTC-CLP
402
+ ```
403
+
404
+ ## Constants
405
+
406
+ The SDK provides convenient constants for all supported values:
407
+
408
+ ```ruby
409
+ # Currencies
410
+ BudaApi::Constants::Currency::BTC # => "BTC"
411
+ BudaApi::Constants::Currency::ALL # => ["BTC", "ETH", "CLP", ...]
412
+
413
+ # Markets
414
+ BudaApi::Constants::Market::BTC_CLP # => "BTC-CLP"
415
+ BudaApi::Constants::Market::ALL # => ["BTC-CLP", "ETH-CLP", ...]
416
+
417
+ # Order types
418
+ BudaApi::Constants::OrderType::BID # => "Bid" (buy)
419
+ BudaApi::Constants::OrderType::ASK # => "Ask" (sell)
420
+
421
+ # Price types
422
+ BudaApi::Constants::PriceType::MARKET # => "market"
423
+ BudaApi::Constants::PriceType::LIMIT # => "limit"
424
+
425
+ # Order states
426
+ BudaApi::Constants::OrderState::PENDING # => "pending"
427
+ BudaApi::Constants::OrderState::TRADED # => "traded"
428
+ BudaApi::Constants::OrderState::CANCELED # => "canceled"
429
+ ```
430
+
431
+ ## Rate Limiting
432
+
433
+ The SDK automatically handles rate limiting with exponential backoff retry logic. When rate limits are hit:
434
+
435
+ 1. The request is automatically retried after a delay
436
+ 2. The delay increases exponentially for subsequent retries
437
+ 3. After maximum retries, a `RateLimitError` is raised
438
+
439
+ You can configure retry behavior:
440
+
441
+ ```ruby
442
+ BudaApi.configure do |config|
443
+ config.retries = 5 # Maximum retry attempts
444
+ config.timeout = 60 # Request timeout
445
+ end
446
+ ```
447
+
448
+ ## Security
449
+
450
+ ### API Key Security
451
+
452
+ - Never commit API keys to version control
453
+ - Use environment variables or secure configuration management
454
+ - Rotate API keys regularly
455
+ - Use API keys with minimal required permissions
456
+
457
+ ### HMAC Authentication
458
+
459
+ The SDK automatically handles HMAC-SHA384 signature generation:
460
+
461
+ 1. Generates a unique nonce for each request
462
+ 2. Creates signature using HTTP method, path, body, and nonce
463
+ 3. Includes proper headers: `X-SBTC-APIKEY`, `X-SBTC-NONCE`, `X-SBTC-SIGNATURE`
464
+
465
+ ## Contributing
466
+
467
+ 1. Fork it (https://github.com/yourusername/buda-api-ruby/fork)
468
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
469
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
470
+ 4. Push to the branch (`git push origin my-new-feature`)
471
+ 5. Create a new Pull Request
472
+
473
+ ### Development Setup
474
+
475
+ ```bash
476
+ git clone https://github.com/yourusername/buda-api-ruby.git
477
+ cd buda-api-ruby
478
+ bundle install
479
+ bundle exec rspec
480
+ ```
481
+
482
+ ### Running Tests
483
+
484
+ ```bash
485
+ # Run all tests
486
+ bundle exec rspec
487
+
488
+ # Run with coverage
489
+ bundle exec rspec --format documentation
490
+
491
+ # Run specific test file
492
+ bundle exec rspec spec/client_spec.rb
493
+ ```
494
+
495
+ ## Changelog
496
+
497
+ ### Version 1.0.0
498
+
499
+ - Initial release
500
+ - Complete public and authenticated API coverage
501
+ - Comprehensive error handling
502
+ - Debug logging and monitoring
503
+ - Rich data models with helper methods
504
+ - Automatic retries and rate limit handling
505
+ - Extensive documentation and examples
506
+
507
+ ## License
508
+
509
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
510
+
511
+ ## Disclaimer
512
+
513
+ This SDK is provided "as is" without warranty. Trading cryptocurrencies involves substantial risk of loss. Always test thoroughly in a staging environment before using in production. Never risk more than you can afford to lose.
514
+
515
+ The authors and contributors are not responsible for any financial losses incurred through the use of this SDK.
516
+
517
+ ## Support
518
+
519
+ - ๐Ÿ“– [API Documentation](https://api.buda.com)
520
+ - ๐Ÿ› [Issue Tracker](https://github.com/yourusername/buda-api-ruby/issues)
521
+ - ๐Ÿ’ฌ [Discussions](https://github.com/yourusername/buda-api-ruby/discussions)
522
+
523
+ ## Related Projects
524
+
525
+ - [Buda Python SDK](https://github.com/delta575/trading-api-wrappers) - Official Python wrapper
526
+ - [Buda API Documentation](https://api.buda.com) - Official API docs
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
7
+
8
+ desc "Run RuboCop"
9
+ task :rubocop do
10
+ sh "rubocop"
11
+ end
12
+
13
+ desc "Generate documentation"
14
+ task :yard do
15
+ sh "yard doc"
16
+ end
17
+
18
+ desc "Run all checks"
19
+ task :check => [:rubocop, :spec]
20
+
21
+ desc "Run examples (public API only)"
22
+ task :examples do
23
+ sh "ruby examples/public_api_example.rb"
24
+ sh "ruby examples/error_handling_example.rb"
25
+ end
26
+
27
+ desc "Install gem locally"
28
+ task :install do
29
+ sh "gem build buda_api.gemspec"
30
+ sh "gem install buda_api-*.gem"
31
+ end
32
+
33
+ desc "Clean build artifacts"
34
+ task :clean do
35
+ sh "rm -f buda_api-*.gem"
36
+ sh "rm -rf doc/"
37
+ end
data/buda_api.gemspec ADDED
@@ -0,0 +1,38 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "buda_api"
3
+ spec.version = "1.0.0"
4
+ spec.authors = ["Buda API Ruby SDK"]
5
+ spec.email = ["pablob0798@gmail.com"]
6
+
7
+ spec.summary = "Ruby SDK for Buda.com trading API"
8
+ spec.description = "A comprehensive Ruby SDK for interacting with Buda.com cryptocurrency exchange API with debugging, error handling, and comprehensive examples"
9
+ spec.homepage = "https://github.com/PabloB07/buda-api-ruby"
10
+ spec.license = "MIT"
11
+ spec.required_ruby_version = ">= 2.7.0"
12
+
13
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
14
+ spec.metadata["homepage_uri"] = spec.homepage
15
+ spec.metadata["source_code_uri"] = "https://github.com/PabloB07/buda-api-ruby"
16
+ spec.metadata["changelog_uri"] = "https://github.com/PabloB07/buda-api-ruby/blob/main/CHANGELOG.md"
17
+
18
+ # Specify which files should be added to the gem when it is released.
19
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ # Dependencies
27
+ spec.add_dependency "faraday", "~> 2.0"
28
+ spec.add_dependency "faraday-retry", "~> 2.0"
29
+ spec.add_dependency "logger", "~> 1.5"
30
+ spec.add_dependency "json", "~> 2.6"
31
+
32
+ # Development dependencies
33
+ spec.add_development_dependency "rspec", "~> 3.0"
34
+ spec.add_development_dependency "webmock", "~> 3.0"
35
+ spec.add_development_dependency "vcr", "~> 6.0"
36
+ spec.add_development_dependency "rubocop", "~> 1.0"
37
+ spec.add_development_dependency "yard", "~> 0.9"
38
+ end
@@ -0,0 +1,11 @@
1
+ # Example environment variables file
2
+ # Copy this file to .env and fill in your actual API credentials
3
+
4
+ # Buda API Credentials
5
+ # Get these from your Buda account settings -> API Keys
6
+ BUDA_API_KEY=your_api_key_here
7
+ BUDA_API_SECRET=your_api_secret_here
8
+
9
+ # Logging configuration
10
+ BUDA_DEBUG_MODE=true
11
+ BUDA_LOG_LEVEL=debug