honeymaker 0.12.4-aarch64-linux
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 +7 -0
- data/.github/workflows/native-gems.yml +100 -0
- data/.github/workflows/release.yml +36 -0
- data/.github/workflows/test.yml +33 -0
- data/LICENSE +21 -0
- data/README.md +219 -0
- data/Rakefile +78 -0
- data/crates/honeymaker/tests/vectors/decimal.json +146 -0
- data/crates/honeymaker/tests/vectors/kraken_add_order_wire.json +74 -0
- data/crates/honeymaker/tests/vectors/kraken_signing.json +3314 -0
- data/crates/honeymaker/tests/vectors/kraken_trades_pager.json +1583 -0
- data/lib/honeymaker/3.4/honeymaker_native.so +0 -0
- data/lib/honeymaker/4.0/honeymaker_native.so +0 -0
- data/lib/honeymaker/client.rb +139 -0
- data/lib/honeymaker/clients/binance.rb +687 -0
- data/lib/honeymaker/clients/binance_us.rb +42 -0
- data/lib/honeymaker/clients/bingx.rb +242 -0
- data/lib/honeymaker/clients/bitget.rb +318 -0
- data/lib/honeymaker/clients/bitrue.rb +245 -0
- data/lib/honeymaker/clients/bitvavo.rb +244 -0
- data/lib/honeymaker/clients/bybit.rb +308 -0
- data/lib/honeymaker/clients/coinbase.rb +326 -0
- data/lib/honeymaker/clients/gemini.rb +189 -0
- data/lib/honeymaker/clients/hyperliquid.rb +232 -0
- data/lib/honeymaker/clients/kraken.rb +379 -0
- data/lib/honeymaker/clients/kraken_futures.rb +78 -0
- data/lib/honeymaker/clients/kucoin.rb +310 -0
- data/lib/honeymaker/clients/mexc.rb +249 -0
- data/lib/honeymaker/exchange.rb +129 -0
- data/lib/honeymaker/exchanges/binance.rb +55 -0
- data/lib/honeymaker/exchanges/binance_us.rb +9 -0
- data/lib/honeymaker/exchanges/bingx.rb +56 -0
- data/lib/honeymaker/exchanges/bitget.rb +52 -0
- data/lib/honeymaker/exchanges/bitrue.rb +53 -0
- data/lib/honeymaker/exchanges/bitvavo.rb +65 -0
- data/lib/honeymaker/exchanges/bybit.rb +57 -0
- data/lib/honeymaker/exchanges/coinbase.rb +69 -0
- data/lib/honeymaker/exchanges/gemini.rb +134 -0
- data/lib/honeymaker/exchanges/hyperliquid.rb +67 -0
- data/lib/honeymaker/exchanges/kraken.rb +122 -0
- data/lib/honeymaker/exchanges/kucoin.rb +52 -0
- data/lib/honeymaker/exchanges/mexc.rb +56 -0
- data/lib/honeymaker/native/kraken.rb +263 -0
- data/lib/honeymaker/native.rb +42 -0
- data/lib/honeymaker/result.rb +46 -0
- data/lib/honeymaker/utils.rb +39 -0
- data/lib/honeymaker/version.rb +5 -0
- data/lib/honeymaker.rb +97 -0
- data/script/parity/kraken_client_live.rb +191 -0
- data/script/parity/kraken_live.rb +70 -0
- data/script/parity/kraken_transport.rb +604 -0
- data/script/parity/resolve.c +49 -0
- data/script/release/push_gems.sh +28 -0
- data/script/vectors/kraken.rb +50 -0
- data/script/vectors/kraken_stage2.rb +146 -0
- data/sig/honeymaker.rbs +4 -0
- data/test/fixtures/binance_book_ticker.json +7 -0
- data/test/fixtures/binance_exchange_info.json +30 -0
- data/test/fixtures/bingx_symbols.json +26 -0
- data/test/fixtures/bingx_ticker.json +12 -0
- data/test/fixtures/bitget_symbols.json +28 -0
- data/test/fixtures/bitget_tickers.json +14 -0
- data/test/fixtures/bitmart_symbols.json +26 -0
- data/test/fixtures/bitmart_ticker.json +12 -0
- data/test/fixtures/bitrue_book_ticker.json +7 -0
- data/test/fixtures/bitrue_exchange_info.json +34 -0
- data/test/fixtures/bitvavo_book_ticker.json +7 -0
- data/test/fixtures/bitvavo_markets.json +30 -0
- data/test/fixtures/bybit_instruments.json +23 -0
- data/test/fixtures/bybit_tickers.json +19 -0
- data/test/fixtures/coinbase_product.json +7 -0
- data/test/fixtures/coinbase_products.json +24 -0
- data/test/fixtures/gemini_pubticker.json +10 -0
- data/test/fixtures/gemini_symbol_detail.json +10 -0
- data/test/fixtures/gemini_symbols.json +1 -0
- data/test/fixtures/hyperliquid_all_mids.json +5 -0
- data/test/fixtures/hyperliquid_spot_meta.json +12 -0
- data/test/fixtures/kraken_asset_pairs.json +43 -0
- data/test/fixtures/kraken_ticker.json +16 -0
- data/test/fixtures/kucoin_orderbook_level1.json +10 -0
- data/test/fixtures/kucoin_symbols.json +17 -0
- data/test/fixtures/mexc_book_ticker.json +7 -0
- data/test/fixtures/mexc_exchange_info.json +64 -0
- data/test/honeymaker/client_test.rb +90 -0
- data/test/honeymaker/clients/binance_client_test.rb +151 -0
- data/test/honeymaker/clients/binance_us_client_test.rb +25 -0
- data/test/honeymaker/clients/bingx_client_test.rb +106 -0
- data/test/honeymaker/clients/bitget_client_test.rb +146 -0
- data/test/honeymaker/clients/bitrue_client_test.rb +69 -0
- data/test/honeymaker/clients/bitvavo_client_test.rb +156 -0
- data/test/honeymaker/clients/bybit_client_test.rb +137 -0
- data/test/honeymaker/clients/coinbase_client_test.rb +153 -0
- data/test/honeymaker/clients/gemini_client_test.rb +100 -0
- data/test/honeymaker/clients/honeymaker_client_registry_test.rb +39 -0
- data/test/honeymaker/clients/hyperliquid_client_test.rb +292 -0
- data/test/honeymaker/clients/kraken_client_test.rb +255 -0
- data/test/honeymaker/clients/kraken_futures_client_test.rb +54 -0
- data/test/honeymaker/clients/kucoin_client_test.rb +149 -0
- data/test/honeymaker/clients/mexc_client_test.rb +98 -0
- data/test/honeymaker/clients/validation_test.rb +167 -0
- data/test/honeymaker/error_chain_test.rb +133 -0
- data/test/honeymaker/exchange_test.rb +138 -0
- data/test/honeymaker/exchanges/binance_test.rb +83 -0
- data/test/honeymaker/exchanges/binance_us_test.rb +53 -0
- data/test/honeymaker/exchanges/bingx_test.rb +65 -0
- data/test/honeymaker/exchanges/bitget_test.rb +65 -0
- data/test/honeymaker/exchanges/bitrue_test.rb +65 -0
- data/test/honeymaker/exchanges/bitvavo_test.rb +65 -0
- data/test/honeymaker/exchanges/bybit_test.rb +55 -0
- data/test/honeymaker/exchanges/coinbase_test.rb +106 -0
- data/test/honeymaker/exchanges/gemini_catalogue_test.rb +118 -0
- data/test/honeymaker/exchanges/gemini_test.rb +184 -0
- data/test/honeymaker/exchanges/hyperliquid_test.rb +64 -0
- data/test/honeymaker/exchanges/kraken_test.rb +191 -0
- data/test/honeymaker/exchanges/kucoin_test.rb +55 -0
- data/test/honeymaker/exchanges/mexc_test.rb +97 -0
- data/test/honeymaker/honeymaker_test.rb +27 -0
- data/test/honeymaker/result_test.rb +42 -0
- data/test/honeymaker/utils_test.rb +64 -0
- data/test/native/backend_switch_test.rb +53 -0
- data/test/native/convert_test.rb +137 -0
- data/test/native/gem_isolation_test.rb +17 -0
- data/test/native/loader_test.rb +29 -0
- data/test/native/lockstep_test.rb +23 -0
- data/test/native/signing_smoke_test.rb +28 -0
- data/test/parity/kraken_client_parity_test.rb +398 -0
- data/test/parity/kraken_exchange_parity_test.rb +172 -0
- data/test/release/branch_hardening_test.rb +34 -0
- data/test/release/push_gems_test.rb +79 -0
- data/test/smoke.rb +24 -0
- data/test/support/fixture_helper.rb +13 -0
- data/test/support/kraken_signing_smoke.rb +21 -0
- data/test/support/parity_helper.rb +62 -0
- data/test/support/venue_double.rb +100 -0
- data/test/test_helper.rb +9 -0
- metadata +254 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ce03d589763a1ce403d35622db819a32dfa54b6ac86c3fd19941ecb3083a82ff
|
|
4
|
+
data.tar.gz: 2eef626eca2a9c2ff52e74c3f9b8695f6af426f62d6122331c77241319123f5c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a3b24b61eaa393c7e7db0a4e30b20d34bafad08aca60961e04480c8efb016b27800555f862a0078857eb69a2cd61e4e69119a372d13480eca34dcba2dff431a0
|
|
7
|
+
data.tar.gz: a843783dd90df321366ed0c4b35232f66f4a0b44dd0dddb7fb46eababd92eb678219ad57f8814dea50b6f3df7e44aa6f430dd49fea1fca2a62c8c5214a817105
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
name: Native gems
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
paths: ["crates/**", "ext/**", "Cargo.*", "rust-toolchain.toml", "honeymaker.gemspec", "Rakefile",
|
|
6
|
+
"lib/honeymaker/native.rb", "test/smoke.rb", ".github/workflows/native-gems.yml"]
|
|
7
|
+
workflow_call:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
cross:
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
platform: [x86_64-linux, aarch64-linux, x86_64-darwin, arm64-darwin, x64-mingw-ucrt]
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
22
|
+
- uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0
|
|
23
|
+
with:
|
|
24
|
+
ruby-version: "3.4"
|
|
25
|
+
bundler-cache: true
|
|
26
|
+
- uses: oxidize-rb/actions/cross-gem@ec90b4aa48795518d79be3f5cc478d1d7ccd02a8 # v1.5.0
|
|
27
|
+
id: cross
|
|
28
|
+
with:
|
|
29
|
+
platform: ${{ matrix.platform }}
|
|
30
|
+
ruby-versions: "3.4,4.0"
|
|
31
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
32
|
+
with:
|
|
33
|
+
name: gem-${{ matrix.platform }}
|
|
34
|
+
path: ${{ steps.cross.outputs.gem-path }}
|
|
35
|
+
|
|
36
|
+
source:
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
40
|
+
- uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0
|
|
41
|
+
with:
|
|
42
|
+
ruby-version: "3.4"
|
|
43
|
+
bundler-cache: true
|
|
44
|
+
- run: bundle exec rake build
|
|
45
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
46
|
+
with:
|
|
47
|
+
name: gem-ruby
|
|
48
|
+
path: pkg/honeymaker-*.gem
|
|
49
|
+
|
|
50
|
+
source-install:
|
|
51
|
+
needs: source
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
55
|
+
- uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0
|
|
56
|
+
with:
|
|
57
|
+
ruby-version: "4.0"
|
|
58
|
+
- run: rustup toolchain install 1.94.0 --profile minimal
|
|
59
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
60
|
+
with:
|
|
61
|
+
name: gem-ruby
|
|
62
|
+
path: gems
|
|
63
|
+
- run: gem install --no-document --platform ruby gems/*.gem
|
|
64
|
+
env:
|
|
65
|
+
RUSTUP_TOOLCHAIN: "1.94.0"
|
|
66
|
+
- run: ruby test/smoke.rb
|
|
67
|
+
env:
|
|
68
|
+
EXPECT_PLATFORM: ruby
|
|
69
|
+
|
|
70
|
+
smoke:
|
|
71
|
+
needs: cross
|
|
72
|
+
strategy:
|
|
73
|
+
fail-fast: false
|
|
74
|
+
matrix:
|
|
75
|
+
include:
|
|
76
|
+
- { os: ubuntu-latest, platform: x86_64-linux, ruby: "3.4" }
|
|
77
|
+
- { os: ubuntu-latest, platform: x86_64-linux, ruby: "4.0" }
|
|
78
|
+
- { os: ubuntu-24.04-arm, platform: aarch64-linux, ruby: "3.4" }
|
|
79
|
+
- { os: ubuntu-24.04-arm, platform: aarch64-linux, ruby: "4.0" }
|
|
80
|
+
- { os: macos-15-intel, platform: x86_64-darwin, ruby: "3.4" }
|
|
81
|
+
- { os: macos-15-intel, platform: x86_64-darwin, ruby: "4.0" }
|
|
82
|
+
- { os: macos-14, platform: arm64-darwin, ruby: "3.4" }
|
|
83
|
+
- { os: macos-14, platform: arm64-darwin, ruby: "4.0" }
|
|
84
|
+
- { os: windows-latest, platform: x64-mingw-ucrt, ruby: "3.4" }
|
|
85
|
+
- { os: windows-latest, platform: x64-mingw-ucrt, ruby: "4.0" }
|
|
86
|
+
runs-on: ${{ matrix.os }}
|
|
87
|
+
steps:
|
|
88
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
89
|
+
- uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0
|
|
90
|
+
with:
|
|
91
|
+
ruby-version: ${{ matrix.ruby }}
|
|
92
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
93
|
+
with:
|
|
94
|
+
name: gem-${{ matrix.platform }}
|
|
95
|
+
path: gems
|
|
96
|
+
- run: gem install --no-document gems/*.gem
|
|
97
|
+
shell: bash
|
|
98
|
+
- run: ruby test/smoke.rb
|
|
99
|
+
env:
|
|
100
|
+
EXPECT_PLATFORM: ${{ matrix.platform }}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
gems:
|
|
12
|
+
uses: ./.github/workflows/native-gems.yml
|
|
13
|
+
|
|
14
|
+
publish:
|
|
15
|
+
needs: gems
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
environment: rubygems # required reviewer: Jan
|
|
18
|
+
permissions:
|
|
19
|
+
id-token: write
|
|
20
|
+
contents: read
|
|
21
|
+
steps:
|
|
22
|
+
# Checkout cleans the workspace, so it must precede artifact download.
|
|
23
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
24
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
25
|
+
with:
|
|
26
|
+
pattern: gem-*
|
|
27
|
+
merge-multiple: true
|
|
28
|
+
path: gems
|
|
29
|
+
- uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0
|
|
30
|
+
with:
|
|
31
|
+
ruby-version: "3.4"
|
|
32
|
+
- uses: rubygems/configure-rubygems-credentials@bc6dd217f8a4f919d6835fcfefd470ef821f5c44 # v1.0.0
|
|
33
|
+
with:
|
|
34
|
+
trusted-publisher: true
|
|
35
|
+
- name: Push platform gems first, the source gem last (idempotent)
|
|
36
|
+
run: script/release/push_gems.sh gems "${GITHUB_REF_NAME#v}"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
strategy:
|
|
15
|
+
fail-fast: false
|
|
16
|
+
matrix:
|
|
17
|
+
os: [ubuntu-latest, macos-14]
|
|
18
|
+
ruby: ["3.4", "4.0"]
|
|
19
|
+
runs-on: ${{ matrix.os }}
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
22
|
+
- uses: oxidize-rb/actions/setup-ruby-and-rust@ec90b4aa48795518d79be3f5cc478d1d7ccd02a8 # v1.5.0
|
|
23
|
+
with:
|
|
24
|
+
ruby-version: ${{ matrix.ruby }}
|
|
25
|
+
bundler-cache: true
|
|
26
|
+
cargo-cache: true
|
|
27
|
+
- run: cargo test --locked -p honeymaker
|
|
28
|
+
- run: cargo test --locked -p honeymaker-client
|
|
29
|
+
- run: cargo clippy --locked -p honeymaker-client --all-targets -- -D warnings
|
|
30
|
+
- run: bundle exec rake compile
|
|
31
|
+
- run: bundle exec rake test
|
|
32
|
+
env:
|
|
33
|
+
HONEYMAKER_REQUIRE_NATIVE: "1"
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Deltabadger
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Honeymaker
|
|
2
|
+
|
|
3
|
+
[](https://rubygems.org/gems/honeymaker)
|
|
4
|
+
[](https://github.com/deltabadger/honeymaker/actions)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
Ruby clients for cryptocurrency exchange APIs used by [Deltabadger](https://github.com/deltabadger/deltabadger).
|
|
8
|
+
|
|
9
|
+
## Supported Exchanges
|
|
10
|
+
|
|
11
|
+
Binance, Binance US, Kraken, Kraken Futures, Coinbase, Bybit, KuCoin, Bitget, MEXC, Bitvavo, Gemini, Hyperliquid, BingX, Bitrue.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
gem "honeymaker"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Native extension
|
|
20
|
+
|
|
21
|
+
Prebuilt native gems support Ruby 3.4 and 4.0 on `x86_64-linux`, `aarch64-linux`,
|
|
22
|
+
`x86_64-darwin`, `arm64-darwin`, and `x64-mingw-ucrt`. A source gem is also published.
|
|
23
|
+
Building from source needs Rust 1.94; in a checkout, run `bundle install` followed by
|
|
24
|
+
`bundle exec rake compile`.
|
|
25
|
+
|
|
26
|
+
The Ruby backend remains the default. Set `HONEYMAKER_NATIVE=kraken` before requiring
|
|
27
|
+
`honeymaker` to enable the Rust backend for Kraken. `HONEYMAKER_NATIVE` accepts a
|
|
28
|
+
comma-separated list of exchange names; Kraken is currently the supported native backend.
|
|
29
|
+
Other exchanges continue to use Ruby. Unset the variable to return to the Ruby backend.
|
|
30
|
+
|
|
31
|
+
### Releases
|
|
32
|
+
|
|
33
|
+
Run `bundle exec rake release` for a patch release, `bundle exec rake release:minor`
|
|
34
|
+
for a minor release, or `bundle exec rake release:major` for a major release. The task
|
|
35
|
+
bumps the gem and Cargo workspace versions together, updates both lockfiles, compiles,
|
|
36
|
+
tests, commits the four version/lock files, and pushes the commit and a `v<version>` tag.
|
|
37
|
+
`bundle exec rake _tag_release` resumes the push without another version bump.
|
|
38
|
+
|
|
39
|
+
The tag triggers `.github/workflows/release.yml`, which calls the native-gem workflow
|
|
40
|
+
to build and smoke-test all five platform gems and the source gem. Configure the
|
|
41
|
+
GitHub `rubygems` environment with Jan as its required reviewer and configure RubyGems
|
|
42
|
+
trusted publishing for this repository's `release.yml` workflow and `rubygems` environment.
|
|
43
|
+
After Jan approves, CI publishes using trusted publishing, with platform gems first
|
|
44
|
+
and the source gem last.
|
|
45
|
+
|
|
46
|
+
Recovery:
|
|
47
|
+
|
|
48
|
+
- **Publish failed partway:** open Actions → the same workflow run → **Re-run failed jobs**.
|
|
49
|
+
The artifacts are retained, and the push loop skips gems already published with an
|
|
50
|
+
identical checksum. It stops on any mismatch; never override that.
|
|
51
|
+
- **Workflow cancelled or never finished building:** choose **Re-run all jobs** on the
|
|
52
|
+
tag's run. `gh workflow run` is not a substitute, because it isn't a tag-push event.
|
|
53
|
+
- **Bump commit pushed but tag push failed:** run
|
|
54
|
+
`git tag -a v<version> -m v<version> && git push origin v<version>`.
|
|
55
|
+
`_tag_release` is a no-op once the tag exists locally. If the tag already exists locally,
|
|
56
|
+
retry just `git push origin v<version>`.
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
### Market Data
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
require "honeymaker"
|
|
64
|
+
|
|
65
|
+
exchange = Honeymaker.exchange("binance")
|
|
66
|
+
result = exchange.get_tickers_info
|
|
67
|
+
|
|
68
|
+
if result.success?
|
|
69
|
+
result.data.each do |ticker|
|
|
70
|
+
puts "#{ticker[:ticker]} — min: #{ticker[:minimum_quote_size]}, decimals: #{ticker[:base_decimals]}"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Balances
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
client = Honeymaker.client("binance", api_key: "...", api_secret: "...")
|
|
79
|
+
result = client.get_balances
|
|
80
|
+
|
|
81
|
+
if result.success?
|
|
82
|
+
result.data.each do |symbol, balance|
|
|
83
|
+
puts "#{symbol}: free=#{balance[:free]}, locked=#{balance[:locked]}"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
# => { "BTC" => { free: BigDecimal("0.5"), locked: BigDecimal("0.1") }, ... }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Coinbase auto-resolves the default portfolio, or pass one explicitly:
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
client.get_balances(portfolio_uuid: "...")
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Placing Orders
|
|
96
|
+
|
|
97
|
+
Order placement returns a normalized `{ order_id:, raw: }` hash:
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
client = Honeymaker.client("binance", api_key: "...", api_secret: "...")
|
|
101
|
+
|
|
102
|
+
result = client.new_order(symbol: "BTCUSDT", side: "BUY", type: "MARKET", quote_order_qty: "100")
|
|
103
|
+
if result.success?
|
|
104
|
+
puts result.data[:order_id] # => "BTCUSDT-123456"
|
|
105
|
+
puts result.data[:raw] # full exchange response
|
|
106
|
+
end
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Method names vary by exchange (`new_order`, `create_order`, `add_order`, `place_order`, `submit_order`) but the return format is the same.
|
|
110
|
+
|
|
111
|
+
### Querying Orders
|
|
112
|
+
|
|
113
|
+
Order queries return a normalized hash with unified status, amounts, and the raw response:
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
result = client.query_order(symbol: "BTCUSDT", order_id: 123456)
|
|
117
|
+
if result.success?
|
|
118
|
+
order = result.data
|
|
119
|
+
order[:order_id] # => "BTCUSDT-123456"
|
|
120
|
+
order[:status] # => :open, :closed, :cancelled, :failed, :unknown
|
|
121
|
+
order[:side] # => :buy, :sell
|
|
122
|
+
order[:order_type] # => :market, :limit
|
|
123
|
+
order[:price] # => BigDecimal — avg fill price
|
|
124
|
+
order[:amount] # => BigDecimal — requested base qty (nil if quote-denominated)
|
|
125
|
+
order[:quote_amount] # => BigDecimal — requested quote qty (nil if base-denominated)
|
|
126
|
+
order[:amount_exec] # => BigDecimal — filled base qty
|
|
127
|
+
order[:quote_amount_exec] # => BigDecimal — filled quote qty
|
|
128
|
+
order[:raw] # => Hash — full exchange response
|
|
129
|
+
end
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Account History (Tax Reporting)
|
|
133
|
+
|
|
134
|
+
History endpoints for margin, futures, staking/earn, and other tax-relevant events:
|
|
135
|
+
|
|
136
|
+
```ruby
|
|
137
|
+
# Margin
|
|
138
|
+
client.margin_borrow_repay_history(type: "BORROW") # Binance
|
|
139
|
+
client.margin_interest_history # Binance, KuCoin, Bitget
|
|
140
|
+
client.margin_force_liquidation # Binance
|
|
141
|
+
|
|
142
|
+
# Futures
|
|
143
|
+
client.futures_income_history(income_type: "REALIZED_PNL") # Binance USDT-M
|
|
144
|
+
client.coin_futures_income_history # Binance Coin-M
|
|
145
|
+
client.futures_account_bills(product_type: "USDT-FUTURES") # Bitget
|
|
146
|
+
client.futures_income # BingX
|
|
147
|
+
|
|
148
|
+
# Staking / Earn
|
|
149
|
+
client.simple_earn_flexible_rewards # Binance
|
|
150
|
+
client.simple_earn_locked_subscriptions # Binance
|
|
151
|
+
client.earn_yield_history # Bybit
|
|
152
|
+
client.staking_rewards # Gemini
|
|
153
|
+
client.staking_rewards_history # Binance US
|
|
154
|
+
|
|
155
|
+
# Other
|
|
156
|
+
client.universal_transfer_history(type: "MAIN_MARGIN") # Binance
|
|
157
|
+
client.dust_log # Binance
|
|
158
|
+
client.asset_dividend # Binance
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Coverage varies by exchange. Kraken's `get_ledgers(type:)` covers margin, staking, and trades in a single endpoint. Coinbase's `list_transactions` covers 30+ event types.
|
|
162
|
+
|
|
163
|
+
### Kraken Futures
|
|
164
|
+
|
|
165
|
+
Kraken Futures uses separate API keys and a different auth scheme — it's a standalone client:
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
client = Honeymaker.client("kraken_futures", api_key: "...", api_secret: "...")
|
|
169
|
+
|
|
170
|
+
client.get_accounts # wallet balances, margin, PnL
|
|
171
|
+
client.get_fills # trade fills
|
|
172
|
+
client.get_open_positions # open positions
|
|
173
|
+
client.historical_funding_rates(symbol: "PF_XBTUSD") # funding rate history
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Credential Validation
|
|
177
|
+
|
|
178
|
+
```ruby
|
|
179
|
+
client = Honeymaker.client("binance", api_key: "...", api_secret: "...")
|
|
180
|
+
result = client.validate(:trading)
|
|
181
|
+
result.success? # => true if credentials have trading permissions
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Rate Limits
|
|
185
|
+
|
|
186
|
+
Each exchange exposes rate limit metadata (milliseconds between requests):
|
|
187
|
+
|
|
188
|
+
```ruby
|
|
189
|
+
Honeymaker::Clients::Binance.rate_limits
|
|
190
|
+
# => { default: 100, orders: 200 }
|
|
191
|
+
|
|
192
|
+
Honeymaker::Clients::Kraken.rate_limits
|
|
193
|
+
# => { default: 1000, orders: 1000 }
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Proxy Support
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
client = Honeymaker.client("binance",
|
|
200
|
+
api_key: "...", api_secret: "...",
|
|
201
|
+
proxy: "http://proxy:8100"
|
|
202
|
+
)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Result Objects
|
|
206
|
+
|
|
207
|
+
All methods return `Result::Success` or `Result::Failure`:
|
|
208
|
+
|
|
209
|
+
```ruby
|
|
210
|
+
result = client.get_balances
|
|
211
|
+
result.success? # true/false
|
|
212
|
+
result.failure? # true/false
|
|
213
|
+
result.data # response payload
|
|
214
|
+
result.errors # array of error messages (empty on success)
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
MIT
|
data/Rakefile
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rake/testtask"
|
|
4
|
+
|
|
5
|
+
if ENV["HONEYMAKER_RAKEFILE_LIB_ONLY"] != "1" && File.exist?(File.join(__dir__, "honeymaker.gemspec"))
|
|
6
|
+
require "bundler/gem_tasks"
|
|
7
|
+
require "rb_sys/extensiontask"
|
|
8
|
+
|
|
9
|
+
GEMSPEC = Gem::Specification.load(File.join(__dir__, "honeymaker.gemspec"))
|
|
10
|
+
RbSys::ExtensionTask.new("honeymaker_native", GEMSPEC) do |ext|
|
|
11
|
+
ext.lib_dir = "lib/honeymaker"
|
|
12
|
+
# Core-only edits must rebuild the extension too (the default pattern covers ext/ only).
|
|
13
|
+
ext.source_pattern = "{**/*,../../crates/honeymaker/**/*,../../Cargo}.{rs,toml,lock}"
|
|
14
|
+
ext.cross_compile = true
|
|
15
|
+
ext.cross_platform = %w[x86_64-linux aarch64-linux x86_64-darwin arm64-darwin x64-mingw-ucrt]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
Rake::TestTask.new(:test) do |t|
|
|
20
|
+
t.libs << "test"
|
|
21
|
+
t.libs << "lib"
|
|
22
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
task default: %i[compile test]
|
|
26
|
+
|
|
27
|
+
VERSION_FILE = "lib/honeymaker/version.rb"
|
|
28
|
+
|
|
29
|
+
def current_version
|
|
30
|
+
File.read(VERSION_FILE).match(/VERSION = "(.+)"/)[1]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def bump_version(segment)
|
|
34
|
+
major, minor, patch = current_version.split(".").map(&:to_i)
|
|
35
|
+
new_version = case segment
|
|
36
|
+
when :major then [major + 1, 0, 0]
|
|
37
|
+
when :minor then [major, minor + 1, 0]
|
|
38
|
+
when :patch then [major, minor, patch + 1]
|
|
39
|
+
end.join(".")
|
|
40
|
+
content = File.read(VERSION_FILE)
|
|
41
|
+
File.write(VERSION_FILE, content.sub(/VERSION = ".+"/, "VERSION = \"#{new_version}\""))
|
|
42
|
+
File.write("Cargo.toml", File.read("Cargo.toml").sub(/(\[workspace\.package\][^\[]*?^version = )"[^"]+"/m, "\\1\"#{new_version}\""))
|
|
43
|
+
puts "Bumped version to #{new_version}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
if ENV["HONEYMAKER_RAKEFILE_LIB_ONLY"] != "1" && File.exist?(File.join(__dir__, "honeymaker.gemspec"))
|
|
47
|
+
Rake::Task[:release].clear
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def do_release(segment)
|
|
51
|
+
bump_version(segment)
|
|
52
|
+
sh "bundle install"
|
|
53
|
+
sh "cargo update --workspace --offline"
|
|
54
|
+
Rake::Task[:compile].invoke
|
|
55
|
+
Rake::Task[:test].invoke
|
|
56
|
+
sh %(git add #{VERSION_FILE} Cargo.toml Cargo.lock Gemfile.lock && git commit -m "v#{current_version}")
|
|
57
|
+
sh "bundle exec rake _tag_release"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Pushes the bump commit and the v* tag; .github/workflows/release.yml builds and publishes.
|
|
61
|
+
task _tag_release: %w[release:guard_clean release:source_control_push]
|
|
62
|
+
|
|
63
|
+
desc "Bump patch, compile, test, and push a release tag for CI"
|
|
64
|
+
task :release do
|
|
65
|
+
do_release(:patch)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
namespace :release do
|
|
69
|
+
desc "Bump minor, compile, test, and push a release tag for CI"
|
|
70
|
+
task :minor do
|
|
71
|
+
do_release(:minor)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
desc "Bump major, compile, test, and push a release tag for CI"
|
|
75
|
+
task :major do
|
|
76
|
+
do_release(:major)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"input": "0.5",
|
|
4
|
+
"ok": true,
|
|
5
|
+
"finite": true,
|
|
6
|
+
"plain": "0.5",
|
|
7
|
+
"sign": 2
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"input": "1",
|
|
11
|
+
"ok": true,
|
|
12
|
+
"finite": true,
|
|
13
|
+
"plain": "1.0",
|
|
14
|
+
"sign": 2
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"input": "-0",
|
|
18
|
+
"ok": true,
|
|
19
|
+
"finite": true,
|
|
20
|
+
"plain": "-0.0",
|
|
21
|
+
"sign": -1
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"input": "-0.0000",
|
|
25
|
+
"ok": true,
|
|
26
|
+
"finite": true,
|
|
27
|
+
"plain": "-0.0",
|
|
28
|
+
"sign": -1
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"input": "0.0000000001",
|
|
32
|
+
"ok": true,
|
|
33
|
+
"finite": true,
|
|
34
|
+
"plain": "0.0000000001",
|
|
35
|
+
"sign": 2
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"input": "123456789012345678901234567890.123456789",
|
|
39
|
+
"ok": true,
|
|
40
|
+
"finite": true,
|
|
41
|
+
"plain": "123456789012345678901234567890.123456789",
|
|
42
|
+
"sign": 2
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"input": "1e-9",
|
|
46
|
+
"ok": true,
|
|
47
|
+
"finite": true,
|
|
48
|
+
"plain": "0.000000001",
|
|
49
|
+
"sign": 2
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"input": "1E5",
|
|
53
|
+
"ok": true,
|
|
54
|
+
"finite": true,
|
|
55
|
+
"plain": "100000.0",
|
|
56
|
+
"sign": 2
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"input": " 1.5 ",
|
|
60
|
+
"ok": true,
|
|
61
|
+
"finite": true,
|
|
62
|
+
"plain": "1.5",
|
|
63
|
+
"sign": 2
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"input": "1_000.5",
|
|
67
|
+
"ok": true,
|
|
68
|
+
"finite": true,
|
|
69
|
+
"plain": "1000.5",
|
|
70
|
+
"sign": 2
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"input": ".5",
|
|
74
|
+
"ok": true,
|
|
75
|
+
"finite": true,
|
|
76
|
+
"plain": "0.5",
|
|
77
|
+
"sign": 2
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"input": "5.",
|
|
81
|
+
"ok": true,
|
|
82
|
+
"finite": true,
|
|
83
|
+
"plain": "5.0",
|
|
84
|
+
"sign": 2
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"input": "+2",
|
|
88
|
+
"ok": true,
|
|
89
|
+
"finite": true,
|
|
90
|
+
"plain": "2.0",
|
|
91
|
+
"sign": 2
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"input": "",
|
|
95
|
+
"ok": false,
|
|
96
|
+
"error": "invalid value for BigDecimal(): \"\""
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"input": "abc",
|
|
100
|
+
"ok": false,
|
|
101
|
+
"error": "invalid value for BigDecimal(): \"abc\""
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"input": "1,5",
|
|
105
|
+
"ok": false,
|
|
106
|
+
"error": "invalid value for BigDecimal(): \"1,5\""
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"input": "0x10",
|
|
110
|
+
"ok": false,
|
|
111
|
+
"error": "invalid value for BigDecimal(): \"0x10\""
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"input": "NaN",
|
|
115
|
+
"ok": true,
|
|
116
|
+
"finite": false,
|
|
117
|
+
"plain": "NaN",
|
|
118
|
+
"sign": 0
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"input": "Infinity",
|
|
122
|
+
"ok": true,
|
|
123
|
+
"finite": false,
|
|
124
|
+
"plain": "Infinity",
|
|
125
|
+
"sign": 3
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"input": "-Infinity",
|
|
129
|
+
"ok": true,
|
|
130
|
+
"finite": false,
|
|
131
|
+
"plain": "-Infinity",
|
|
132
|
+
"sign": -3
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"input": "1d2",
|
|
136
|
+
"ok": true,
|
|
137
|
+
"finite": true,
|
|
138
|
+
"plain": "100.0",
|
|
139
|
+
"sign": 2
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"input": "true",
|
|
143
|
+
"ok": false,
|
|
144
|
+
"error": "invalid value for BigDecimal(): \"true\""
|
|
145
|
+
}
|
|
146
|
+
]
|