Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ tmp
mkmf.log
.env
todo
*.sw?
.ruby-version
1 change: 1 addition & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require spec_helper
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
1.1.0
- Bump dependencies for ruby 3.x
- Replace faraday_adapter_socks with custom class

1.0.11
- Fixes nonce issue to be compatible with other libraries

Expand Down
8 changes: 3 additions & 5 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ source 'https://rubygems.org'

gemspec

gem 'faraday_adapter_socks'
gem 'dotenv'
gem 'emittr'
gem 'zlib'

group :test do
group :development, :test do
gem 'rspec'
gem 'simplecov'
gem 'webmock', '~> 1.22.6'
gem 'simplecov', require: false
gem 'webmock', '~> 3.14.0'
end

23 changes: 12 additions & 11 deletions bitfinex-rb.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)

Gem::Specification.new do |spec|
spec.name = 'bitfinex-rb'
spec.version = '1.0.11'
spec.version = '1.1.0'
spec.authors = ['Bitfinex']
spec.email = ['developers@bitfinex.com']
spec.summary = %q{Bitfinex API Wrapper}
Expand All @@ -15,14 +15,15 @@ Gem::Specification.new do |spec|
spec.files = Dir['lib/**/*']
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ['lib']
spec.add_runtime_dependency 'faraday', '~> 0.15.3', '>= 0.15.3'
spec.add_runtime_dependency 'eventmachine', '~> 1.2.7', '>= 1.2.7'
spec.add_runtime_dependency 'faraday-detailed_logger', '~> 2.1.2', '>= 2.1.2'
spec.add_runtime_dependency 'faye-websocket', '~> 0.10.7'
spec.add_runtime_dependency 'json', '~> 2.2.0','>= 2.2.0'
spec.add_runtime_dependency 'faraday_middleware', '~> 0.12.2', '>= 0.12.2'
spec.add_runtime_dependency 'emittr', '~> 0.1.0', '>= 0.1.0'
spec.add_runtime_dependency 'dotenv', '~> 2.5.0', '>= 2.5.0'
spec.add_runtime_dependency 'faraday_adapter_socks', '~> 0.1.1', '>= 0.1.1'
spec.add_runtime_dependency 'zlib', '~> 1.0.0', '>= 1.0.0'

spec.add_runtime_dependency 'faraday', '~> 1.10.3'
spec.add_runtime_dependency 'eventmachine', '~> 1.2.7'
spec.add_runtime_dependency 'faraday-detailed_logger', '~> 2.5.0'
spec.add_runtime_dependency 'faye-websocket', '~> 0.11.3'
spec.add_runtime_dependency 'json', '~> 2.0', '>= 2.2.0'
spec.add_runtime_dependency 'faraday_middleware', '~> 1.2.0'
spec.add_runtime_dependency 'emittr', '~> 0.1.0'
spec.add_runtime_dependency 'dotenv', '~> 2.7.6'
spec.add_runtime_dependency 'socksify', '~> 1.7.1'
spec.add_runtime_dependency 'zlib', '~> 1.0.0'
end
3 changes: 3 additions & 0 deletions lib/bitfinex.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
require 'base64'
require 'openssl'
require 'faraday'
require 'socksify'
require 'socksify/http'
require 'json'
require 'faraday_middleware'
require 'dotenv/load'
Expand All @@ -11,6 +13,7 @@
require_relative './rest/v2'
require_relative './ws/ws2'

require_relative './faraday/adapter/net_http_socks'
require_relative './models/alert'
require_relative './models/balance_info'
require_relative './models/candle'
Expand Down
21 changes: 21 additions & 0 deletions lib/faraday/adapter/net_http_socks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class NetHttpSocks < Faraday::Adapter::NetHttp
SOCKS_SCHEMES = ['socks', 'socks4', 'socks5']

def net_http_connection(env)
proxy = env[:request][:proxy]

net_http_class = if proxy
if SOCKS_SCHEMES.include?(proxy[:uri].scheme)
Net::HTTP::SOCKSProxy(proxy[:uri].host, proxy[:uri].port)
else
Net::HTTP::Proxy(proxy[:uri].host, proxy[:uri].port, proxy[:user], proxy[:password])
end
else
Net::HTTP
end

net_http_class.new(env[:url].host, env[:url].port)
end
end

Faraday::Adapter.register_middleware(net_http_socks: NetHttpSocks)
2 changes: 0 additions & 2 deletions lib/rest/rest_client.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
require 'faraday_adapter_socks'

module Bitfinex
module RESTClient
def check_params(params, allowed_params)
Expand Down
86 changes: 86 additions & 0 deletions spec/integration/v1_account_info_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
require 'spec_helper'
require 'webmock/rspec'
require 'hashdiff'
require_relative '../../lib/bitfinex'

RSpec.describe 'Bitfinex::RESTv1 Integration' do
before do
# Stub the account info request
stub_request(:post, "https://api.bitfinex.com/v1/account_infos")
.with(body: '{}')
.to_return(
status: 200,
body: '[
{
"leo_fee_disc_c2c":"0.0",
"leo_fee_disc_c2s":"0.0",
"leo_fee_disc_c2f":"0.0",
"leo_fee_disc_c2d":"0.0",
"leo_fee_disc_abs_c2c":"0.0",
"leo_fee_disc_abs_c2s":"0.0",
"leo_fee_disc_abs_c2f":"0.0",
"leo_fee_disc_abs_c2d":"0.0",
"leo_fee_maker_disc_abs_c2d":"0.0",
"maker_fees":"0.1",
"taker_fees":"0.2",
"fees":[
{"pairs":"BTC", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"ETH", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"IOT", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"XRP", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"REP", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"GRG", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"ZRX", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"MLN", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"SAN", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"AMP", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"DUSK", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"LNX", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"EOS", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"TESTBTC", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"TESTUSDT", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"TESTUSD", "maker_fees":"0.1", "taker_fees":"0.2"},
{"pairs":"ETH2P", "maker_fees":"0.1", "taker_fees":"0.2"}
]
}
]',
headers: { 'Content-Type' => 'application/json' }
)

# Stub the account fees request
stub_request(:post, "https://api.bitfinex.com/v1/account_fees")
.with(body: '{}')
.to_return(
status: 200,
body: '{"withdraw":{"BTC":"0.000001","ETH":"0.0","IOT":"0.0","XRP":"0.0","GRG":"0.025367","ZRX":"0.00000249","MLN":"0.00036065","SAN":"33.819","AMP":"5.3018","DUSK":"0.08371","LNX":"0.000001","EOS":"0.0","TESTBTC":"0.0","TESTUSDT":"0.0","TESTUSD":"0.0","EXO":"0.0","BMN":"0.0"}}',
headers: { 'Content-Type' => 'application/json' }
)
end

let(:client) do
Bitfinex::RESTv1.new({
api_key: 'dummy_api_key',
api_secret: 'dummy_api_secret',
url: 'https://api.bitfinex.com',
})
end

it 'fetches account info' do
response = client.account_info
expect(response).not_to be_nil
expect(response).to be_a(Array)
expect(response.first['maker_fees']).to eq('0.1')
expect(response.first['taker_fees']).to eq('0.2')
expect(response.first['fees']).to be_a(Array)
expect(response.first['fees'].first['pairs']).to eq('BTC')
end

it 'fetches fees' do
response = client.fees
expect(response).not_to be_nil
expect(response).to be_a(Hash)
expect(response['withdraw']['BTC']).to eq('0.000001')
expect(response['withdraw']['ETH']).to eq('0.0')
expect(response['withdraw']['GRG']).to eq('0.025367')
end
end
36 changes: 36 additions & 0 deletions spec/integration/v1_proxy_account_info.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'spec_helper'
require 'webmock/rspec'
require_relative '../../lib/bitfinex'

RSpec.describe 'Bitfinex::RESTv1 Proxy Integration' do
before do
stub_request(:post, "https://api.bitfinex.com/v1/account_infos")
.with(body: '{}')
.to_return(
status: 200,
body: '[{"maker_fees":"0.1","taker_fees":"0.2"}]',
headers: { 'Content-Type' => 'application/json' }
)
end

let(:client) do
Bitfinex::RESTv1.new({
api_key: 'dummy_api_key',
api_secret: 'dummy_api_secret',
url: 'https://api.bitfinex.com',
proxy: 'http://proxy.example.com:8080'
})
end

it 'fetches account info through proxy' do
response = client.account_info
expect(response).not_to be_nil
expect(response).to be_a(Array)
expect(response.first['maker_fees']).to eq('0.1')
expect(response.first['taker_fees']).to eq('0.2')

# Verify that the request was made through the proxy
expect(WebMock).to have_requested(:post, "https://api.bitfinex.com/v1/account_infos")
.with(headers: { 'Proxy-Authorization' => 'Basic ' + Base64.encode64('proxy_user:proxy_pass').strip })
end
end
31 changes: 31 additions & 0 deletions spec/integration/v2_orders_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require 'spec_helper'
require 'webmock/rspec'
require_relative '../../lib/bitfinex'

RSpec.describe 'Bitfinex::RESTv2 Integration' do
before do
stub_request(:post, "https://api.bitfinex.com/v2/auth/r/orders")
.with(body: '{}')
.to_return(
status: 200,
body: '[{"id":12345,"symbol":"tBTCUSD","amount":"1.0"}]',
headers: { 'Content-Type' => 'application/json' }
)
end

let(:client) do
Bitfinex::RESTv2.new({
api_key: 'dummy_api_key',
api_secret: 'dummy_api_secret',
url: 'https://api.bitfinex.com',
})
end

it 'fetches orders' do
response = client.orders
expect(response).not_to be_nil
expect(response).to be_a(Array)
expect(response.first['id']).to eq(12345)
expect(response.first['symbol']).to eq('tBTCUSD')
end
end
81 changes: 81 additions & 0 deletions spec/integration/ws_connect_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
require 'spec_helper'
require 'webmock/rspec'
require 'faye/websocket'
require 'eventmachine'
require_relative '../../lib/bitfinex'

RSpec.describe 'Bitfinex::WSv2 Integration' do
let(:client) do
Bitfinex::WSv2.new({
url: 'ws://localhost:8080/ws/2',
})
end

before do
stub_request(:any, 'ws://localhost:8080/ws/2').to_return(body: '', status: 200)
end

it 'connects to WebSocket' do
EM.run {
mock_server = EM.start_server('0.0.0.0', 8080) do |conn|
conn.instance_eval do
def post_init
@ws = Faye::WebSocket::Server.new(self)
@ws.on :open do |event|
@ws.send('{"event":"info","version":2,"serverId":"60916660-db0f-4519-b4cd-be8d4c745b24","platform":{"status":1}}')
end
@ws.on :message do |event|
@ws.send('{"event":"subscribed","channel":"ticker","pair":"tBTCUSD"}')
end
@ws.on :close do |event|
close_connection
EM.stop
end
end

def receive_data(data)
@ws.receive(data)
end
end
end

expect { client.open! }.not_to raise_error
EM.stop_server(mock_server)
EM.stop
}
end

it 'subscribes to a channel' do
EM.run {
mock_server = EM.start_server('0.0.0.0', 8080) do |conn|
conn.instance_eval do
def post_init
@ws = Faye::WebSocket::Server.new(self)
@ws.on :open do |event|
@ws.send('{"event":"info","version":2,"serverId":"60916660-db0f-4519-b4cd-be8d4c745b24","platform":{"status":1}}')
end
@ws.on :message do |event|
@ws.send('{"event":"subscribed","channel":"ticker","pair":"tBTCUSD"}')
end
@ws.on :close do |event|
close_connection
EM.stop
end
end

def receive_data(data)
@ws.receive(data)
end
end
end

client.on(:open) do
client.subscribe_order_book('tBTCUSD', 'R0', '25')
end

expect { client.open! }.not_to raise_error
EM.stop_server(mock_server)
EM.stop
}
end
end
Loading