honeymaker 0.9.2 → 0.9.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac4aba6f18266cfffed7dfe3939a60198cb6bdb7361818db8f25f435e19d92f9
4
- data.tar.gz: e0e398092c55d7483ac386a94846fd5eff4abf115feb9dffd59a85c59462da37
3
+ metadata.gz: 8751e8712e47b27bf82073fa2b7de4ec7d7404e9b6195a6cbcd06a2a48749acd
4
+ data.tar.gz: 414e8fd8e266d7d8cd7acc3abd4b39f18d450fb5ba08ebf0b9121c599fc7ff9f
5
5
  SHA512:
6
- metadata.gz: aabbbc8fdd2c884c85770fc21a5862fe05c014860775f44e362e59c7db7c841cf92e74494af5028abdf10f4af70d88dc5fe13cc4fdc1838e359dc44f6f5c6dd5
7
- data.tar.gz: a6cb39b92b07b6a5d04bb9b5d3adc14f11f7ea045b628c3b7dc09dd7501ddc0b9268bd3b477d8f2aac5072cfd379afe527738899c706b3d60ace82edd91073ad
6
+ metadata.gz: ccf214595dccd90388f8a77dffca7cb0618047c025531c219c1030d2af821d96b682f67f991ff701de013f847cea045b5c7a9b4f5f1a6a96f19490549c18a6ef
7
+ data.tar.gz: e724a084bfc8bd6bca47bd6bced65a12eb75818e58b05f31022d549d246bb8fa1920763bbc27179b1d0339938b899309ee8b8be0f8718a96163834b9f8107a8d
@@ -7,6 +7,11 @@ module Honeymaker
7
7
  ACCESS_WINDOW = "10000"
8
8
  RATE_LIMITS = { default: 100, orders: 100 }.freeze
9
9
 
10
+ # Bitvavo requires a mandatory operatorId on every order create/cancel
11
+ # (errorCode 203). It's a positive int64 the caller sets themselves to
12
+ # attribute an order to a trader/bot for audit; the value is cosmetic.
13
+ DEFAULT_OPERATOR_ID = 1
14
+
10
15
  def get_assets
11
16
  get_public("/v2/assets")
12
17
  end
@@ -51,11 +56,12 @@ module Honeymaker
51
56
  end
52
57
 
53
58
  def place_order(market:, side:, order_type:, amount: nil, amount_quote: nil, price: nil,
54
- time_in_force: nil, client_order_id: nil)
59
+ time_in_force: nil, client_order_id: nil, operator_id: nil)
55
60
  result = post_signed("/v2/order", {
56
61
  market: market, side: side, orderType: order_type,
57
62
  amount: amount, amountQuote: amount_quote, price: price,
58
- timeInForce: time_in_force, clientOrderId: client_order_id
63
+ timeInForce: time_in_force, clientOrderId: client_order_id,
64
+ operatorId: operator_id || DEFAULT_OPERATOR_ID
59
65
  })
60
66
  return result if result.failure?
61
67
 
@@ -71,8 +77,10 @@ module Honeymaker
71
77
  Result::Success.new(normalize_order("#{raw['market']}-#{raw['orderId']}", raw))
72
78
  end
73
79
 
74
- def cancel_order(market:, order_id:)
75
- delete_signed("/v2/order", { market: market, orderId: order_id })
80
+ def cancel_order(market:, order_id:, operator_id: nil)
81
+ delete_signed("/v2/order", {
82
+ market: market, orderId: order_id, operatorId: operator_id || DEFAULT_OPERATOR_ID
83
+ })
76
84
  end
77
85
 
78
86
  def get_trades(market:, limit: nil, start_time: nil, end_time: nil, trade_id_from: nil, trade_id_to: nil)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Honeymaker
4
- VERSION = "0.9.2"
4
+ VERSION = "0.9.3"
5
5
  end
@@ -47,6 +47,36 @@ class Honeymaker::Clients::BitvavoTest < Minitest::Test
47
47
  assert result.success?
48
48
  end
49
49
 
50
+ # Bitvavo requires a mandatory integer operatorId on every order create/cancel
51
+ # (errorCode 203). These tests yield the real Faraday request block so we assert
52
+ # what the client actually sends, not just the stubbed response.
53
+
54
+ def test_place_order_sends_default_operator_id
55
+ req = capture_request(:post, { "orderId" => "123" })
56
+ @client.place_order(market: "BTC-EUR", side: "buy", order_type: "market", amount_quote: "100")
57
+ assert_equal @client.class::DEFAULT_OPERATOR_ID, req.body[:operatorId]
58
+ assert_kind_of Integer, req.body[:operatorId]
59
+ end
60
+
61
+ def test_place_order_operator_id_override
62
+ req = capture_request(:post, { "orderId" => "123" })
63
+ @client.place_order(market: "BTC-EUR", side: "buy", order_type: "market", amount_quote: "100", operator_id: 42)
64
+ assert_equal 42, req.body[:operatorId]
65
+ end
66
+
67
+ def test_cancel_order_sends_default_operator_id
68
+ req = capture_request(:delete, { "orderId" => "123" })
69
+ @client.cancel_order(market: "BTC-EUR", order_id: "123")
70
+ assert_equal @client.class::DEFAULT_OPERATOR_ID, req.params[:operatorId]
71
+ assert_kind_of Integer, req.params[:operatorId]
72
+ end
73
+
74
+ def test_cancel_order_operator_id_override
75
+ req = capture_request(:delete, { "orderId" => "123" })
76
+ @client.cancel_order(market: "BTC-EUR", order_id: "123", operator_id: 42)
77
+ assert_equal 42, req.params[:operatorId]
78
+ end
79
+
50
80
  def test_withdraw
51
81
  stub_connection(:post, { "success" => true })
52
82
  result = @client.withdraw(symbol: "BTC", amount: "0.1", address: "addr")
@@ -102,4 +132,25 @@ class Honeymaker::Clients::BitvavoTest < Minitest::Test
102
132
  connection.stubs(method).returns(response)
103
133
  @client.instance_variable_set(:@connection, connection)
104
134
  end
135
+
136
+ # Records what the client sets on the Faraday request. Unlike stub_connection,
137
+ # this yields the request block (connection.post { |req| ... }) so the real
138
+ # body/params-building code in post_signed/delete_signed actually executes.
139
+ class RequestRecorder
140
+ attr_accessor :headers, :body, :params
141
+ attr_reader :requested_url
142
+
143
+ def url(path)
144
+ @requested_url = path
145
+ end
146
+ end
147
+
148
+ def capture_request(method, body)
149
+ response = stub(body: body)
150
+ recorder = RequestRecorder.new
151
+ connection = stub
152
+ connection.stubs(method).yields(recorder).returns(response)
153
+ @client.instance_variable_set(:@connection, connection)
154
+ recorder
155
+ end
105
156
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeymaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Deltabadger