From ff2feb0274d69258164685bc056fcbe01ede09df Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 4 Jan 2026 16:12:49 -0600 Subject: [PATCH 1/6] test: first working test run --- Rakefile | 10 +++++++--- lib/kalshi.rb | 2 +- test/helper.rb | 39 +++++++++++++++++++++++++++++++++++++++ test/kalshi/test_rb.rb | 6 +----- test/test_helper.rb | 6 ------ 5 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 test/helper.rb delete mode 100644 test/test_helper.rb diff --git a/Rakefile b/Rakefile index ea495fe..4564da1 100644 --- a/Rakefile +++ b/Rakefile @@ -1,12 +1,16 @@ # frozen_string_literal: true require 'bundler/gem_tasks' -require 'minitest/test_task' +require 'rake/testtask' -Minitest::TestTask.create +Rake::TestTask.new do |t| + t.libs << 'test' + t.test_files = FileList['test/**/*_test.rb'] + t.ruby_opts = %w[-rhelper] +end require 'rubocop/rake_task' RuboCop::RakeTask.new -task default: %i[test rubocop] +task default: %i[rubocop test] diff --git a/lib/kalshi.rb b/lib/kalshi.rb index 3c7a44c..12d6385 100644 --- a/lib/kalshi.rb +++ b/lib/kalshi.rb @@ -3,7 +3,7 @@ require 'semantic_logger' require 'zeitwerk' require 'dry-configurable' -require_relative 'domeapi/version' +require_relative 'kalshi/version' module Rubyists # Kalshi module diff --git a/test/helper.rb b/test/helper.rb new file mode 100644 index 0000000..f8ad81e --- /dev/null +++ b/test/helper.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +if ENV['COVERAGE'] + require 'simplecov' + require 'simplecov-json' + SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new( + [ + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::JSONFormatter + ] + ) + SimpleCov.start do + enable_coverage :branch + add_filter '/test/' + add_filter '/vendor/' + end +end + +require_relative '../lib/kalshi' + +require 'minitest/autorun' +require 'minitest/spec' +require 'shoulda/context' +require 'webmock/minitest' +require 'httpx' +require 'httpx/adapters/webmock' +WebMock::HttpLibAdapters::HttpxAdapter.enable! + +WebMock.disable_net_connect!(allow_localhost: true) + +module Minitest + class Spec + before do + Rubyists::Kalshi.configure do |config| + config.api_key = 'test_api_key' + end + end + end +end diff --git a/test/kalshi/test_rb.rb b/test/kalshi/test_rb.rb index 4160510..bd82f14 100644 --- a/test/kalshi/test_rb.rb +++ b/test/kalshi/test_rb.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require 'test_helper' +require 'helper' module Kalshi class TestRb < Minitest::Test def test_that_it_has_a_version_number refute_nil ::Kalshi::Rb::VERSION end - - def test_it_does_something_useful - assert false - end end end diff --git a/test/test_helper.rb b/test/test_helper.rb deleted file mode 100644 index 39cab6c..0000000 --- a/test/test_helper.rb +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true - -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) -require 'kalshi/rb' - -require 'minitest/autorun' From c8e38cd5c2e3608769b6dbda4507c68555b12e49 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 4 Jan 2026 16:15:57 -0600 Subject: [PATCH 2/6] fix: adds missing semantic_logger dependency --- kalshi.gemspec | 1 + 1 file changed, 1 insertion(+) diff --git a/kalshi.gemspec b/kalshi.gemspec index 502fa29..cb03fe3 100644 --- a/kalshi.gemspec +++ b/kalshi.gemspec @@ -33,6 +33,7 @@ Gem::Specification.new do |spec| # Uncomment to register a new dependency of your gem spec.add_dependency 'faye-websocket' spec.add_dependency 'httpx' + spec.add_dependency 'semantic_logger' spec.add_dependency 'trailblazer', '~> 2' # For more information and examples about making a new gem, check out our From be86d0a4a4319c9277afb90003966249a1dacfc3 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 4 Jan 2026 16:19:29 -0600 Subject: [PATCH 3/6] chore: removes boilerplate workflow --- .github/workflows/main.yml | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index c437098..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Ruby - -on: - push: - branches: - - main - - pull_request: - -jobs: - build: - runs-on: ubuntu-latest - name: Ruby ${{ matrix.ruby }} - strategy: - matrix: - ruby: - - '3.4.7' - - steps: - - uses: actions/checkout@v4 - with: - persist-credentials: false - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ matrix.ruby }} - bundler-cache: true - - name: Run the default task - run: bundle exec rake From 25de7075cfb514db4507ad5ef1a52584297075bd Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 4 Jan 2026 16:21:25 -0600 Subject: [PATCH 4/6] chore: adds required dependencies --- Gemfile.lock | 100 +++++++++++++++++++++++++++++++++++++++++-------- kalshi.gemspec | 10 ++++- 2 files changed, 92 insertions(+), 18 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index da14d9a..9de2ae2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,25 +2,73 @@ PATH remote: . specs: kalshi (0.0.1) - faye-websocket + dry-cli + dry-configurable + dry-container + dry-validation httpx - trailblazer (~> 2) + reform + semantic_logger + trailblazer + webmock + zeitwerk GEM remote: https://rubygems.org/ specs: + addressable (2.8.8) + public_suffix (>= 2.0.2, < 8.0) ast (2.4.3) - base64 (0.3.0) + bigdecimal (3.3.1) coderay (1.1.3) + concurrent-ruby (1.3.6) + crack (1.0.1) + bigdecimal + rexml declarative (0.0.20) disposable (0.6.3) declarative (>= 0.0.9, < 1.0.0) representable (>= 3.1.1, < 4) docile (1.4.1) - eventmachine (1.2.7) - faye-websocket (0.12.0) - eventmachine (>= 0.12.0) - websocket-driver (>= 0.8.0) + dry-cli (1.3.0) + dry-configurable (1.3.0) + dry-core (~> 1.1) + zeitwerk (~> 2.6) + dry-container (0.11.0) + concurrent-ruby (~> 1.0) + dry-core (1.2.0) + concurrent-ruby (~> 1.0) + logger + zeitwerk (~> 2.6) + dry-inflector (1.2.0) + dry-initializer (3.2.0) + dry-logic (1.6.0) + bigdecimal + concurrent-ruby (~> 1.0) + dry-core (~> 1.1) + zeitwerk (~> 2.6) + dry-schema (1.14.1) + concurrent-ruby (~> 1.0) + dry-configurable (~> 1.0, >= 1.0.1) + dry-core (~> 1.1) + dry-initializer (~> 3.2) + dry-logic (~> 1.5) + dry-types (~> 1.8) + zeitwerk (~> 2.6) + dry-types (1.8.3) + bigdecimal (~> 3.0) + concurrent-ruby (~> 1.0) + dry-core (~> 1.0) + dry-inflector (~> 1.0) + dry-logic (~> 1.4) + zeitwerk (~> 2.6) + dry-validation (1.11.1) + concurrent-ruby (~> 1.0) + dry-core (~> 1.1) + dry-initializer (~> 3.2) + dry-schema (~> 1.14) + zeitwerk (~> 2.6) + hashdiff (1.2.1) hashie (5.1.0) logger hirb (0.7.3) @@ -45,6 +93,7 @@ GEM coderay (~> 1.1) method_source (~> 1.0) reline (>= 0.6.0) + public_suffix (7.0.2) racc (1.8.1) rainbow (3.1.1) rake (13.3.1) @@ -59,6 +108,7 @@ GEM declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) + rexml (3.4.4) rubocop (1.82.1) json (~> 2.3) language_server-protocol (~> 3.17.0.2) @@ -85,6 +135,8 @@ GEM lint_roller (~> 1.1) rubocop (>= 1.72.1) ruby-progressbar (1.13.0) + semantic_logger (4.17.0) + concurrent-ruby (~> 1.0) shoulda-context (2.0.0) simplecov (0.22.0) docile (~> 1.1) @@ -127,10 +179,11 @@ GEM unicode-display_width (3.2.0) unicode-emoji (~> 4.1) unicode-emoji (4.2.0) - websocket-driver (0.8.0) - base64 - websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.5) + webmock (3.26.1) + addressable (>= 2.8.0) + crack (>= 0.3.2) + hashdiff (>= 0.4.0, < 2.0.0) + zeitwerk (2.7.4) PLATFORMS ruby @@ -151,14 +204,26 @@ DEPENDENCIES simplecov-json CHECKSUMS + addressable (2.8.8) sha256=7c13b8f9536cf6364c03b9d417c19986019e28f7c00ac8132da4eb0fe393b057 ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 - base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + bigdecimal (3.3.1) sha256=eaa01e228be54c4f9f53bf3cc34fe3d5e845c31963e7fcc5bedb05a4e7d52218 coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b + concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab + crack (1.0.1) sha256=ff4a10390cd31d66440b7524eb1841874db86201d5b70032028553130b6d4c7e declarative (0.0.20) sha256=8021dd6cb17ab2b61233c56903d3f5a259c5cf43c80ff332d447d395b17d9ff9 disposable (0.6.3) sha256=7f2a3fb251bff6cd83f25b164043d4ec3531209b51b066ed476a9df9c2d384cc docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e - eventmachine (1.2.7) sha256=994016e42aa041477ba9cff45cbe50de2047f25dd418eba003e84f0d16560972 - faye-websocket (0.12.0) sha256=ad9f7dfcd0306d0a13baeee450729657661129af15bb5f38716c242484ab42e1 + dry-cli (1.3.0) sha256=984a715f9d7f8d9bf87b6530acdd4321dcf747636bfeb3ea7fd1b81bc0226e84 + dry-configurable (1.3.0) sha256=882d862858567fc1210d2549d4c090f34370fc1bb7c5c1933de3fe792e18afa8 + dry-container (0.11.0) sha256=23be9381644d47343f3bf13b082b4255994ada0bfd88e0737eaaadc99d035229 + dry-core (1.2.0) sha256=0cc5a7da88df397f153947eeeae42e876e999c1e30900f3c536fb173854e96a1 + dry-inflector (1.2.0) sha256=22f5d0b50fd57074ae57e2ca17e3b300e57564c218269dcf82ff3e42d3f38f2e + dry-initializer (3.2.0) sha256=37d59798f912dc0a1efe14a4db4a9306989007b302dcd5f25d0a2a20c166c4e3 + dry-logic (1.6.0) sha256=da6fedbc0f90fc41f9b0cc7e6f05f5d529d1efaef6c8dcc8e0733f685745cea2 + dry-schema (1.14.1) sha256=2fcd7539a7099cacae6a22f6a3a2c1846fe5afeb1c841cde432c89c6cb9b9ff1 + dry-types (1.8.3) sha256=b5d97a45e0ed273131c0c3d5bc9f5633c2d1242e092ee47401ce7d5eab65c1bc + dry-validation (1.11.1) sha256=70900bb5a2d911c8aab566d3e360c6bff389b8bf92ea8e04885ce51c41ff8085 + hashdiff (1.2.1) sha256=9c079dbc513dfc8833ab59c0c2d8f230fa28499cc5efb4b8dd276cf931457cd1 hashie (5.1.0) sha256=c266471896f323c446ea8207f8ffac985d2718df0a0ba98651a3057096ca3870 hirb (0.7.3) sha256=5132733ca44b1f41f36c624693a3201284368a349dfe37f543ae6e2ad880ec57 http-2 (1.1.1) sha256=1141a5a03c2f4e6b8d2fa62394de581e1ff6387711cd7ed577212e9d95562bba @@ -176,6 +241,7 @@ CHECKSUMS parser (3.3.10.0) sha256=ce3587fa5cc55a88c4ba5b2b37621b3329aadf5728f9eafa36bbd121462aabd6 prism (1.7.0) sha256=10062f734bf7985c8424c44fac382ac04a58124ea3d220ec3ba9fe4f2da65103 pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e + public_suffix (7.0.2) sha256=9114090c8e4e7135c1fd0e7acfea33afaab38101884320c65aaa0ffb8e26a857 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c @@ -183,12 +249,14 @@ CHECKSUMS regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4 reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 representable (3.2.0) sha256=cc29bf7eebc31653586849371a43ffe36c60b54b0a6365b5f7d95ec34d1ebace + rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 rubocop (1.82.1) sha256=09f1a6a654a960eda767aebea33e47603080f8e9c9a3f019bf9b94c9cab5e273 rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd rubocop-minitest (0.38.2) sha256=5a9dfb5a538973d0601aa51e59637d3998bb8df81233edf1ff421504c6280068 rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834 rubocop-rake (0.7.1) sha256=3797f2b6810c3e9df7376c26d5f44f3475eda59eb1adc38e6f62ecf027cbae4d ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 + semantic_logger (4.17.0) sha256=c54b60d8596abe2e22bd4f20648d4f6c46e4287fba357779c7932335c8d130e9 shoulda-context (2.0.0) sha256=7adf45342cd800f507d2a053658cb1cce2884b616b26004d39684b912ea32c34 simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246 @@ -207,8 +275,8 @@ CHECKSUMS uber (0.1.0) sha256=5beeb407ff807b5db994f82fa9ee07cfceaa561dad8af20be880bc67eba935dc unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f - websocket-driver (0.8.0) sha256=ed0dba4b943c22f17f9a734817e808bc84cdce6a7e22045f5315aa57676d4962 - websocket-extensions (0.1.5) sha256=1c6ba63092cda343eb53fc657110c71c754c56484aad42578495227d717a8241 + webmock (3.26.1) sha256=4f696fb57c90a827c20aadb2d4f9058bbff10f7f043bd0d4c3f58791143b1cd7 + zeitwerk (2.7.4) sha256=2bef90f356bdafe9a6c2bd32bcd804f83a4f9b8bc27f3600fff051eb3edcec8b BUNDLED WITH 4.0.3 diff --git a/kalshi.gemspec b/kalshi.gemspec index cb03fe3..d2b2c38 100644 --- a/kalshi.gemspec +++ b/kalshi.gemspec @@ -31,10 +31,16 @@ Gem::Specification.new do |spec| spec.require_paths = ['lib'] # Uncomment to register a new dependency of your gem - spec.add_dependency 'faye-websocket' + spec.add_dependency 'dry-cli' + spec.add_dependency 'dry-configurable' + spec.add_dependency 'dry-container' + spec.add_dependency 'dry-validation' spec.add_dependency 'httpx' + spec.add_dependency 'reform' spec.add_dependency 'semantic_logger' - spec.add_dependency 'trailblazer', '~> 2' + spec.add_dependency 'trailblazer' + spec.add_dependency 'webmock' + spec.add_dependency 'zeitwerk' # For more information and examples about making a new gem, check out our # guide at: https://bundler.io/guides/creating_gem.html From f347901c10bd696b44539c6cb1b0260eb4bd35a1 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 4 Jan 2026 16:41:51 -0600 Subject: [PATCH 5/6] test: renames kalshi test to match test spec --- test/helper.rb | 1 + test/kalshi/test_rb.rb | 11 ----------- test/kalshi_test.rb | 26 ++++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 11 deletions(-) delete mode 100644 test/kalshi/test_rb.rb create mode 100644 test/kalshi_test.rb diff --git a/test/helper.rb b/test/helper.rb index f8ad81e..7a25f86 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -29,6 +29,7 @@ WebMock.disable_net_connect!(allow_localhost: true) module Minitest + # Base class for all tests class Spec before do Rubyists::Kalshi.configure do |config| diff --git a/test/kalshi/test_rb.rb b/test/kalshi/test_rb.rb deleted file mode 100644 index bd82f14..0000000 --- a/test/kalshi/test_rb.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -require 'helper' - -module Kalshi - class TestRb < Minitest::Test - def test_that_it_has_a_version_number - refute_nil ::Kalshi::Rb::VERSION - end - end -end diff --git a/test/kalshi_test.rb b/test/kalshi_test.rb new file mode 100644 index 0000000..5135bd3 --- /dev/null +++ b/test/kalshi_test.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'helper' + +module Rubyists + # Tests for Kalshi module + class KalshiTest < Minitest::Spec + describe 'Kalshi' do + subject { ::Rubyists::Kalshi } + + it 'has a version number' do + refute_nil subject::VERSION + end + + describe 'VERSION' do + subject { ::Rubyists::Kalshi::VERSION } + + it 'is a valid semantic version' do + semver_regex = /\A\d+\.\d+\.\d+(-[0-9A-Za-z\-.]+)?(\+[0-9A-Za-z\-.]+)?\z/ + + assert_match(semver_regex, subject) + end + end + end + end +end From d2ef3e99ed23a44a7698d2a9997c6939f4e072a4 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sun, 4 Jan 2026 16:58:54 -0600 Subject: [PATCH 6/6] ci: adds release please configuration --- .gitignore | 1 + .release-please-config.json | 28 ++++++++++++++++++++++++++++ .release-please-manifest.json | 3 +++ bin/wss-raw | 5 +++++ 4 files changed, 37 insertions(+) create mode 100644 .release-please-config.json create mode 100644 .release-please-manifest.json diff --git a/.gitignore b/.gitignore index 9106b2a..f88ce79 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /pkg/ /spec/reports/ /tmp/ +*.swp diff --git a/.release-please-config.json b/.release-please-config.json new file mode 100644 index 0000000..6b68b9a --- /dev/null +++ b/.release-please-config.json @@ -0,0 +1,28 @@ +{ + "packages": { + ".": { + "changelog-path": "CHANGELOG.md", + "release-type": "simple", + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "draft": false, + "prerelease": false, + "version-file": ".version.txt", + "extra-files": [ + { + "type": "generic", + "path": "lib/kalshi/version.rb" + } + ], + "exclude-paths": [ + ".release-please-manifest.json", + ".version.txt", + "lib/kalshi/version.rb", + ".rubocop.yml", + ".overcommit.yml", + "coverage/coverage.json" + ] + } + }, + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json" +} diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..b985ff6 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.0.1" +} diff --git a/bin/wss-raw b/bin/wss-raw index abcfe49..9dc0831 100755 --- a/bin/wss-raw +++ b/bin/wss-raw @@ -2,6 +2,11 @@ # frozen_string_literal: true +# Simple Kalshi WebSocket client with RSA-PSS authentication in Ruby. +# This script connects to Kalshi's WebSocket API using RSA-PSS signatures for authentication. +# It retrieves the API key and PEM private key from `pass` password manager. +# On successful connection, it subscribes to the 'ticker' channel and prints all incoming messages. + require 'faye/websocket' require 'eventmachine' require 'openssl'