domeapi 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0bb3f5617684761d7e6fb686bcca3b1a0c9939f61a1733cae6c376b96a58b804
4
+ data.tar.gz: 4326df296496387d1d583b314359e1b606b8aee5b8da39220e4500fa526c98ad
5
+ SHA512:
6
+ metadata.gz: 3e4c20f7d94cc986c42fc3e145b34420d5838b72d00a17f5c78f54122767a3cdbb717b1da303f1e4408e8f4dc652552e39672e6a3a9748392396094f0ac9aa2b
7
+ data.tar.gz: a9e4c2d25576d31dcc36c813d404be8b9d87de1e940c1d9b05c3759da787030c495e3a3f2794b3a79dc81962b8c950e6d562370a260c3fc81b121d7b2dd9df39
@@ -0,0 +1,28 @@
1
+ {
2
+ "packages": {
3
+ ".": {
4
+ "changelog-path": "CHANGELOG.md",
5
+ "release-type": "simple",
6
+ "bump-minor-pre-major": true,
7
+ "bump-patch-for-minor-pre-major": true,
8
+ "draft": false,
9
+ "prerelease": false,
10
+ "version-file": ".version.txt",
11
+ "extra-files": [
12
+ {
13
+ "type": "generic",
14
+ "path": "lib/domeapi/version.rb"
15
+ }
16
+ ],
17
+ "exclude-paths": [
18
+ ".release-please-manifest.json",
19
+ ".version.txt",
20
+ "lib/domeapi/version.rb",
21
+ ".rubocop.yml",
22
+ ".overcommit.yml",
23
+ "coverage/coverage.json"
24
+ ]
25
+ }
26
+ },
27
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
28
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.0.1"
3
+ }
data/AGENTS.md ADDED
@@ -0,0 +1,99 @@
1
+ # Coding Standards for Agents
2
+
3
+ ---
4
+ This file describes the desired coding standards and for the domeapi ruby project.
5
+
6
+ ## Project Context
7
+
8
+ **Language:** Ruby ~> 4
9
+ **Framework:** [trailblazer](https://trailblazer.to/)
10
+ **Testing:** [minitest](https://docs.seattlerb.org/minitest/) following [BetterSpecs](https://evenbetterspecs.github.io/) guidelines
11
+
12
+ ---
13
+
14
+ ## Purpose & Scope
15
+
16
+ Focused guidance for Ruby style, tests, performance, and tone.
17
+
18
+ ---
19
+
20
+ ## 1. Style Guides
21
+
22
+ > ⚠️ **Be constructive:** Frame style feedback as suggestions (e.g., “Consider using…”).
23
+
24
+ All standard rules follow the [Shopify Ruby Style Guide](https://ruby-style-guide.shopify.dev/), with the following specific emphases:
25
+ - Indentation and line length enforced by RuboCop.
26
+ - Use guard clauses, and explicit receivers.
27
+ - Prefer Railway Oriented Programming (ROP) for error handling and flow. The trailblazer framework encourages this style.
28
+ - Keep methods short. 1 line is fine. 5 is a lot. At 7, you should consider extracting a method.
29
+
30
+ ---
31
+
32
+ ## 2. Tone and Delivery (For code reviews)
33
+
34
+ > 🤝 **Be collaborative:** Lead with positives and offer improvements respectfully.
35
+
36
+ - Open with a brief positive comment on well‑written code.
37
+ - Use phrasing like “Consider extracting…” or “You might simplify…” rather than absolutes.
38
+ - Keep comments concise—2–3 sentences max.
39
+ - Focus on actionable suggestions.
40
+ - Avoid overwhelming with too many minor issues; prioritize key improvements.
41
+
42
+ ---
43
+
44
+ ## 3. Conventions & Readability
45
+
46
+ > ✨ **Keep it clear:** Propose naming and structure that clarify intent.
47
+
48
+ - **SOLID principles:** Single responsibility; inject dependencies via initializers.
49
+ - **Descriptive names:** Recommend clear class, method, and variable names.
50
+ - **DRY:** Suggest extracting duplicate logic into modules or service objects.
51
+ - Encourage use of Trailblazer operations for business logic encapsulation.
52
+ - Promote use of Cells for view components to enhance reusability and maintainability.
53
+ - Encourage use of Contracts for validation to keep models clean and focused.
54
+ - Utilize Dry Container for dependency management to improve testability and modularity.
55
+ - **Method size:** Keep them short, in reviews suggest extractions when exceeding ~7 lines.
56
+ - Structs are our friend for grouping related data without behavior.
57
+ - Favor composition over inheritance; prefer modules and mixins.
58
+ - Ensure files have EOF newline.
59
+ - No trailing white space in code and comments.
60
+
61
+ ---
62
+
63
+ ## 4. Testing and Coverage
64
+
65
+ > 🧪 **Be thorough:** Highlight gaps in meaningful test coverage.
66
+
67
+ - Flag or fix missing or outdated specs for changed behaviors (unit, integration, request).
68
+ - Suggest tests for edge cases: error conditions, invalid inputs, boundary values, and potential `nil` handling or pointer exceptions. Follow best practices from the [BetterSpecs style guide](https://evenbetterspecs.github.io/).
69
+ - Encourage descriptive `context` blocks and example names per [BetterSpecs](https://evenbetterspecs.github.io/).
70
+ - Flag missing specs when logic is updated but no tests were added or modified
71
+ - No less than 100% branch coverage. Full stop.
72
+ ---
73
+
74
+ ## 5. Performance and Security
75
+
76
+ > 🚀 **Guard quality:** Call out patterns that may hurt performance or security.
77
+
78
+ - Detect potential N+1 queries; suggest `includes` or batching.
79
+ - Attempt to identify O(n^2) or O(n log n) algorithms; recommend more efficient alternatives.
80
+ - Flag raw SQL, unsanitized interpolation, or other patterns that could introduce potential SQL injection vulnerabilities; recommend parameter binding and Sequel-based alternatives. Build these into a model, avoid raw SQL unless absolutely necessary.
81
+ - Identify unescaped user input in any i/o context (cli, api, file writes, logs); suggest proper escaping or sanitization.
82
+
83
+ ---
84
+
85
+ ## 6. Documentation and Comments
86
+
87
+ > 📚 **Clarify intent:** Advocate for clear, concise documentation.
88
+
89
+ - All methods should have yarddoc annotations in the format:
90
+ ```ruby
91
+ # Short description of the method.
92
+ #
93
+ # @param [Type] param_name Description of the parameter.
94
+ #
95
+ # @return [Type] Description of the return value.
96
+ ```
97
+ - Explain the "why" behind code choices, not the "what."
98
+ - Add comments only for complex logic or non-obvious decisions.
99
+ - Comments become tech-debt if they are not maintained; use them judiciously.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'minitest/test_task'
5
+
6
+ Minitest::TestTask.create
7
+
8
+ require 'rubocop/rake_task'
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[rubocop test]
data/Readme.adoc ADDED
@@ -0,0 +1,107 @@
1
+ = Domeapi
2
+ :toc: macro
3
+
4
+ Ruby client for the Domeapi API.
5
+
6
+ == Installation
7
+
8
+ Install the gem and add to the application's Gemfile by executing:
9
+
10
+ [source,bash]
11
+ ----
12
+ bundle add domeapi
13
+ ----
14
+
15
+ If bundler is not being used to manage dependencies, install the gem by executing:
16
+
17
+ [source,bash]
18
+ ----
19
+ gem install domeapi
20
+ ----
21
+
22
+ == Usage
23
+
24
+ === Configuration
25
+
26
+ Configure the gem with your API key. You can set it via the `DOMEAPI_API_KEY` environment variable or configure it explicitly:
27
+
28
+ [source,ruby]
29
+ ----
30
+ Rubyists::Domeapi.configure do |config|
31
+ config.api_key = 'your_api_key'
32
+ end
33
+ ----
34
+
35
+ === Client
36
+
37
+ Initialize the client:
38
+
39
+ [source,ruby]
40
+ ----
41
+ client = Rubyists::Domeapi.client
42
+ ----
43
+
44
+ === Polymarket
45
+
46
+ Access Polymarket endpoints via the `polymarket` namespace.
47
+
48
+ ==== Markets
49
+
50
+ List markets with optional filtering:
51
+
52
+ [source,ruby]
53
+ ----
54
+ # List markets with default filter
55
+ markets = client.polymarket.markets.list
56
+
57
+ # List markets with custom filter
58
+ filter = Rubyists::Domeapi::Polymarket::MarketFilter.new(
59
+ Rubyists::Domeapi::Polymarket::MarketFilter::Properties.new(
60
+ limit: 10,
61
+ offset: 0,
62
+ status: 'open'
63
+ )
64
+ )
65
+ markets = client.polymarket.markets.list(filter)
66
+ ----
67
+
68
+ Get market price:
69
+
70
+ [source,ruby]
71
+ ----
72
+ price = client.polymarket.markets.price(token_id: 'token_id')
73
+ ----
74
+
75
+ Get candlesticks:
76
+
77
+ [source,ruby]
78
+ ----
79
+ candlesticks = client.polymarket.markets.candlesticks(
80
+ condition_id: 'condition_id',
81
+ start_time: 1625097600,
82
+ end_time: 1625184000,
83
+ interval: 60
84
+ )
85
+ ----
86
+
87
+ ==== Orders
88
+
89
+ List orders:
90
+
91
+ [source,ruby]
92
+ ----
93
+ orders = client.polymarket.orders.list(
94
+ market_slug: 'market_slug',
95
+ limit: 10
96
+ )
97
+ ----
98
+
99
+ == Development
100
+
101
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
102
+
103
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
104
+
105
+ == Contributing
106
+
107
+ Bug reports and pull requests are welcome on GitHub at https://github.com/rubyists/domeapi.
data/ci/build_image.sh ADDED
@@ -0,0 +1,248 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if readlink -f . >/dev/null 2>&1 # {{{ makes readlink work on mac
4
+ then
5
+ readlink=readlink
6
+ else
7
+ if greadlink -f . >/dev/null 2>&1
8
+ then
9
+ readlink=greadlink
10
+ else
11
+ printf "You must install greadlink to use this (brew install coreutils)\n" >&2
12
+ fi
13
+ fi # }}}
14
+
15
+ # Set here to the full path to this script
16
+ me=${BASH_SOURCE[0]}
17
+ [ -L "$me" ] && me=$($readlink -f "$me")
18
+ here=$(cd "$(dirname "$me")" && pwd)
19
+ just_me=$(basename "$me")
20
+
21
+ repo_top=$(git rev-parse --show-toplevel)
22
+ cd "$repo_top" || {
23
+ printf "Could not cd to %s\n" "$repo_top" >&2
24
+ exit 1
25
+ }
26
+
27
+ base_dir=$(basename "$(pwd)")
28
+ : "${BUILD_CONTEXT:=$(pwd)}"
29
+ : "${IMAGE_NAME:=$base_dir}"
30
+ : "${LICENSE:=MIT}"
31
+ : "${APP_VERSION:=$(< "$here"/../.version.txt)}"
32
+ : "${REGISTRY:=ghcr.io}"
33
+ : "${REGISTRY_TOKEN:=$GITHUB_TOKEN}"
34
+
35
+ usage() { # {{{
36
+ cat <<-EOT
37
+ Build an image, optionally pushing it to the registry
38
+
39
+ Usage: $0 <options> <image_tag>
40
+ Options:
41
+ -c CONTAINERFILE Path to the containerfile (default: ./oci/Containerfile)
42
+ -C CONTEXT Build context (default: $BUILD_CONTEXT)
43
+ -i NAME Name of the image (default: $IMAGE_NAME)
44
+ -l LICENSE License of the image (default: $LICENSE)
45
+ -r REGISTRY Registry to push the image to when -p is given (default: $REGISTRY)
46
+ -p Push the image to the registry
47
+ -h Show help / usage
48
+ EOT
49
+ } # }}}
50
+
51
+ die() { # {{{
52
+ local -i code
53
+ code=$1
54
+ shift
55
+ error "$*"
56
+ printf "\n" >&2
57
+ usage >&2
58
+ # shellcheck disable=SC2086
59
+ exit $code
60
+ } # }}}
61
+
62
+ ## Logging functions # {{{
63
+ log() { # {{{
64
+ printf "%s [%s] <%s> %s\n" "$(date '+%Y-%m-%d %H:%M:%S.%6N')" "$$" "${just_me:-$0}" "$*"
65
+ } # }}}
66
+
67
+ debug() { # {{{
68
+ [ $verbose -lt 2 ] && return 0
69
+ # shellcheck disable=SC2059
70
+ log_line=$(printf "$@")
71
+ log "[DEBUG] $log_line" >&2
72
+ } # }}}
73
+
74
+ warn() { # {{{
75
+ # shellcheck disable=SC2059
76
+ log_line=$(printf "$@")
77
+ log "[WARN] $log_line" >&2
78
+ } # }}}
79
+
80
+ error() { # {{{
81
+ # shellcheck disable=SC2059
82
+ log_line=$(printf "$@")
83
+ log "[ERROR] $log_line" >&2
84
+ } # }}}
85
+
86
+ info() { # {{{
87
+ [ $verbose -lt 1 ] && return 0
88
+ # shellcheck disable=SC2059
89
+ log_line=$(printf "$@")
90
+ log "[INFO] $log_line" >&2
91
+ } # }}}
92
+ # }}}
93
+
94
+ push=0
95
+ verbose=0
96
+ while getopts :hpvc:C:i:l:r: opt # {{{
97
+ do
98
+ case $opt in
99
+ c)
100
+ CONTAINERFILE=$OPTARG
101
+ ;;
102
+ C)
103
+ BUILD_CONTEXT=$OPTARG
104
+ ;;
105
+ i)
106
+ IMAGE_NAME=$OPTARG
107
+ ;;
108
+ l)
109
+ LICENSE=$OPTARG
110
+ ;;
111
+ r)
112
+ REGISTRY=$OPTARG
113
+ ;;
114
+ p)
115
+ push=1
116
+ ;;
117
+ v)
118
+ verbose=$((verbose + 1))
119
+ ;;
120
+ h)
121
+ usage
122
+ exit
123
+ ;;
124
+ :)
125
+ printf "Option %s requires an argument\n" "$OPTARG" >&2
126
+ usage >&2
127
+ exit 28
128
+ ;;
129
+ ?)
130
+ printf "Invalid option '%s'\n" "$OPTARG" >&2
131
+ usage >&2
132
+ exit 27
133
+ ;;
134
+ esac
135
+ done # }}}
136
+ shift $((OPTIND-1))
137
+
138
+ tag=$1
139
+ [ -z "$tag" ] && die 1 "Missing image tag"
140
+ shift
141
+
142
+ # Check for extra argument
143
+ if [ $# -gt 0 ]; then
144
+ # If we have the special argument '--' we shift it away, otherwise we die
145
+ [ "$1" != '--' ] && die 2 "Too many arguments"
146
+ # Once this is shifted away, the rest of the arguments are passed to the build command, below
147
+ shift
148
+ fi
149
+
150
+ if [ -z "$CONTAINERFILE" ]; then
151
+ printf "No containerfile specified, looking for default locations\n"
152
+ for containerfile in Containerfile Dockerfile
153
+ do
154
+ if [ -f ./oci/"$containerfile" ]; then
155
+ debug "Found ./oci/%s\n" "$containerfile"
156
+ containerfile=./oci/"$containerfile"
157
+ break
158
+ fi
159
+ if [ -f "$containerfile" ]; then
160
+ debug "Found %s\n" "$containerfile"
161
+ break
162
+ fi
163
+ done
164
+ else
165
+ [ -f "$CONTAINERFILE" ] || die 3 "Containerfile '$CONTAINERFILE' not found"
166
+ debug "Using containerfile %s\n" "$CONTAINERFILE"
167
+ containerfile=$CONTAINERFILE
168
+ fi
169
+
170
+ [ -f "$containerfile" ] || die 4 "No containerfile found"
171
+
172
+ [ -d "$BUILD_CONTEXT" ] || die 5 "Build context '$BUILD_CONTEXT' not found"
173
+
174
+ debug 'Building image from %s in in %s\n' "$containerfile" "$here"
175
+ # Build the image
176
+ if command -v podman 2>/dev/null
177
+ then
178
+ runtime=podman
179
+ elif command -v docker 2>/dev/null
180
+ then
181
+ runtime=docker
182
+ else
183
+ die 6 "No container runtime found"
184
+ fi
185
+
186
+ revision=$(git rev-parse HEAD)
187
+ shortref=$(git rev-parse --short "$revision")
188
+ repo_url=$(git remote get-url origin)
189
+ if [ -z "$repo_url" ]
190
+ then
191
+ die 7 "No remote found"
192
+ fi
193
+ if [[ $repo_url == *github.com/* ]]
194
+ then
195
+ owner_and_repo=${repo_url#*github.com/}
196
+ else
197
+ owner_and_repo=${repo_url##*:}
198
+ fi
199
+ # Get rid of the trailing .git
200
+ service=$(basename "$owner_and_repo" .git)
201
+ owner=$(dirname "$owner_and_repo")
202
+
203
+ full_tag=$IMAGE_NAME:$tag
204
+ created=$(date --utc --iso-8601=seconds 2>/dev/null || gdate --utc --iso-8601=seconds)
205
+ # Pass any extra arguments to the build command ("$@" contains the rest of the arguments)
206
+ $runtime build --tag "$full_tag" "$@" \
207
+ --label org.opencontainers.image.created="$created" \
208
+ --label org.opencontainers.image.description="Image for $service" \
209
+ --label org.opencontainers.image.licenses="$LICENSE" \
210
+ --label org.opencontainers.image.revision="$revision" \
211
+ --label org.opencontainers.image.url="$repo_url" \
212
+ --label org.opencontainers.image.title="$IMAGE_NAME" \
213
+ --label org.opencontainers.image.source="Generated by ruby-automation's build_image.sh ($USER@$HOSTNAME)" \
214
+ --label org.opencontainers.image.version="$full_tag" \
215
+ --label shortref="$shortref" \
216
+ --build-arg APP_VERSION="$APP_VERSION" \
217
+ -f "$containerfile" "$BUILD_CONTEXT" || die 8 "Failed to build image"
218
+
219
+ [ $push -eq 1 ] || exit 0
220
+ if ! $runtime login --get-login "$REGISTRY" >/dev/null 2>/dev/null
221
+ then
222
+ printf "Not logged in to '%s', trying to login\n" "$REGISTRY" >&2
223
+ [ -z "$REGISTRY_TOKEN" ] && die 9 "No REGISTRY_TOKEN (nor GITHUB_TOKEN) set, cannot login"
224
+ printf "%s" "$REGISTRY_TOKEN" | $runtime login -u "$REGISTRY_TOKEN" --password-stdin "$REGISTRY" || die 10 "Failed to login to $REGISTRY"
225
+ fi
226
+
227
+ # Split 1.2.3 into 1.2.3, 1.2, 1. We want to tag our image with all 3 of these
228
+ mapfile -t tags < <(echo "$tag" | awk -F'.' 'NF==3{print; print $1"."$2; print $1; next} NF==2{print; print $1; next} {print}')
229
+ for t in "${tags[@]}"
230
+ do
231
+ new_tag=$IMAGE_NAME:$t
232
+ registry_image_name="$REGISTRY/$owner/$new_tag"
233
+ if [ "$runtime" = "podman" ]
234
+ then
235
+ if [ "$full_tag" != "$new_tag" ]
236
+ then
237
+ debug "Tagging %s as %s\n" "$full_tag" "$new_tag"
238
+ podman tag "$full_tag" "$new_tag" || die 11 "Failed to tag image $full_tag as $new_tag"
239
+ fi
240
+ podman push "$new_tag" "$registry_image_name" || die 12 "Failed to push image $new_tag to $registry_image_name"
241
+ else
242
+ debug "Tagging %s as %s\n" "$full_tag" "$registry_image_name"
243
+ docker tag "$full_tag" "$registry_image_name" || die 13 "Failed to tag image $full_tag as $registry_image_name"
244
+ docker push "$registry_image_name" || die 14 "Failed to push image $new_tag to $registry_image_name"
245
+ fi
246
+ done
247
+
248
+ # vim: set foldmethod=marker et ts=4 sts=4 sw=4 ft=bash :
data/ci/publish-gem.sh ADDED
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if readlink -f . >/dev/null 2>&1 # {{{ makes readlink work on mac
4
+ then
5
+ readlink=readlink
6
+ else
7
+ if greadlink -f . >/dev/null 2>&1
8
+ then
9
+ readlink=greadlink
10
+ else
11
+ printf "You must install greadlink to use this (brew install coreutils)\n" >&2
12
+ fi
13
+ fi # }}}
14
+
15
+ # Set here to the full path to this script
16
+ me=${BASH_SOURCE[0]}
17
+ [ -L "$me" ] && me=$($readlink -f "$me")
18
+ here=$(cd "$(dirname "$me")" && pwd)
19
+ root=$(cd "$here/.." && pwd)
20
+ just_me=$(basename "$me")
21
+
22
+ : "${GEM_NAME:=domeapi}"
23
+ : "${GIT_ORG:=rubyists}"
24
+
25
+ GEM_HOST=$1
26
+ : "${GEM_HOST:=rubygems}"
27
+
28
+ case "$GEM_HOST" in
29
+ rubygems)
30
+ gem_key='rubygems'
31
+ gem_host='https://rubygems.org'
32
+ ;;
33
+ github)
34
+ gem_key='github'
35
+ gem_host="https://rubygems.pkg.github.com/$GIT_ORG"
36
+ # Replace the gem host in the gemspec, so it allows pushing to the GitHub package registry
37
+ sed --in-place=.bak -e "s|https://rubygems.org|https://rubygems.pkg.github.com/$GIT_ORG|" "$here/../$GEM_NAME".gemspec
38
+ # Restore the original gemspec after the script finishes
39
+ trap 'mv -v "$here/../$GEM_NAME".gemspec.bak "$here/../$GEM_NAME".gemspec' EXIT
40
+ ;;
41
+ *)
42
+ printf 'Unknown GEM_HOST: %s\n' "$GEM_HOST" >&2
43
+ exit 1
44
+ ;;
45
+ esac
46
+
47
+ # We only want this part running in CI, with no ~/.gem dir
48
+ # For local testing, you should have a ~/.gem/credentials file with
49
+ # the keys you need to push to rubygems or github
50
+ if [ ! -d ~/.gem ]
51
+ then
52
+ if [ -z "$GEM_TOKEN" ]
53
+ then
54
+ printf 'No GEM_TOKEN provided, cannot publish\n' >&2
55
+ exit 1
56
+ fi
57
+ mkdir -p ~/.gem
58
+ printf '%s\n:%s: %s\n' '---' "$gem_key" "$GEM_TOKEN" > ~/.gem/credentials
59
+ chmod 600 ~/.gem/credentials
60
+ fi
61
+
62
+ bundle exec gem build
63
+
64
+ if [ -f "$here"/../.version.txt ]
65
+ then
66
+ version=$(<"$here"/../.version.txt)
67
+ else
68
+ version=$(git describe --tags --abbrev=0 | sed -e 's/^v//')
69
+ fi
70
+
71
+ if [ -z "$version" ]
72
+ then
73
+ gem="$(ls "$root"/"$GEM_NAME"-*.gem | tail -1)"
74
+ else
75
+ gem="$(printf '%s/%s-%s.gem' "$root" "$GEM_NAME" "$version")"
76
+ fi
77
+
78
+ if [ ! -f "$gem" ]
79
+ then
80
+ printf 'No gem file found: %s\n' "$gem" >&2
81
+ exit 1
82
+ fi
83
+
84
+ if [[ "${TRACE:-false}" == true || "${ACTIONS_STEP_DEBUG:-false}" == true ]]
85
+ then
86
+ printf "DEBUG: [%s] Building And Publishing %s to %s\n" "$just_me" "$gem" "$gem_host" >&2
87
+ fi
88
+
89
+ bundle exec gem push -k "$gem_key" --host "$gem_host" "$(basename "$gem")"
90
+
91
+ # vim: set foldmethod=marker et ts=4 sts=4 sw=4 ft=bash :
data/exe/domeapi ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'domeapi'
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'httpx'
4
+ require 'json'
5
+
6
+ module Rubyists
7
+ module Domeapi
8
+ # HTTP Client for Domeapi API
9
+ class Client
10
+ include SemanticLogger::Loggable
11
+
12
+ attr_reader :http, :base_url
13
+ attr_accessor :prefix
14
+
15
+ def initialize(api_key: Domeapi.config.api_key, base_url: Domeapi.config.base_url)
16
+ @base_url = base_url
17
+ @http = HTTPX.plugin(:persistent)
18
+ .plugin(:rate_limiter)
19
+ .with(origin: base_url, headers: { 'Authorization' => "Bearer #{api_key}" })
20
+ end
21
+
22
+ def get(path, params: {})
23
+ response = @http.get(full_url(path), params:)
24
+ handle_response(response)
25
+ end
26
+
27
+ def polymarket
28
+ @polymarket ||= Polymarket::Client.new(self)
29
+ end
30
+
31
+ private
32
+
33
+ def full_url(path)
34
+ File.join(*[base_url, prefix, path].compact)
35
+ end
36
+
37
+ def handle_response(response)
38
+ response.raise_for_status
39
+ JSON.parse(response.body.to_s, symbolize_names: true)
40
+ rescue HTTPX::HTTPError => e
41
+ logger.error('API Error', e)
42
+ raise Error, "API Error: #{e.response.status} - #{e.response.body}"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'reform'
4
+ require 'reform/form/dry'
5
+
6
+ module Rubyists
7
+ module Domeapi
8
+ # Base Contract class for Trailblazer/Reform forms
9
+ class Contract < Reform::Form
10
+ feature Reform::Form::Dry
11
+
12
+ def self.custom_definitions = instance_variable_get(:@definitions)&.keys&.map(&:to_sym) || []
13
+
14
+ def to_h
15
+ to_nested_hash.compact
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubyists
4
+ module Domeapi
5
+ module Polymarket
6
+ # Polymarket API Client
7
+ class Client
8
+ attr_reader :client
9
+
10
+ def initialize(client = Rubyists::Domeapi::Client.new)
11
+ @client = client
12
+ client.prefix = 'polymarket'
13
+ end
14
+
15
+ def get(...)
16
+ client.get(...)
17
+ end
18
+
19
+ def markets
20
+ @markets ||= Markets.new(client)
21
+ end
22
+
23
+ def orders
24
+ @orders ||= Orders.new(client)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubyists
4
+ module Domeapi
5
+ module Polymarket
6
+ # Filter for Polymarket markets
7
+ class MarketFilter < Contract
8
+ Properties = Struct.new(
9
+ *custom_definitions,
10
+ :market_slug,
11
+ :event_slug,
12
+ :condition_id,
13
+ :tags,
14
+ :status,
15
+ :min_volume,
16
+ :limit,
17
+ :offset,
18
+ :start_time,
19
+ :end_time,
20
+ keyword_init: true
21
+ )
22
+
23
+ # Define properties with custom populator to skip optional params with nil values
24
+ (Properties.members - custom_definitions).each do |member|
25
+ property member, populator: ->(value:, **) { value || skip! }
26
+ end
27
+
28
+ validation do
29
+ params do
30
+ optional(:status).maybe(:string, included_in?: %w[open closed])
31
+ optional(:offset).maybe(:integer, gteq?: 0, lteq?: 100)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubyists
4
+ module Domeapi
5
+ module Polymarket
6
+ # Markets API endpoints
7
+ class Markets
8
+ attr_reader :client
9
+
10
+ class << self
11
+ # @see #list
12
+ def list(...)
13
+ new.list(...)
14
+ end
15
+ end
16
+
17
+ # @param client [Rubyists::Domeapi::Polymarket::Client]
18
+ #
19
+ # @return [void]
20
+ def initialize(client = Rubyists::Domeapi::Polymarket::Client.new)
21
+ @client = client
22
+ end
23
+
24
+ # List markets
25
+ # @param filter [MarketFilter] Filter options
26
+ #
27
+ # @return [Array<Polymarket::Market>] list of markets
28
+ def list(filter = MarketFilter.new(MarketFilter::Properties.new))
29
+ raise ArgumentError, filter.errors.full_messages.join(', ') unless filter.validate({})
30
+
31
+ client.get('markets', params: filter.to_h)
32
+ end
33
+
34
+ # Fetch current or historical price for a market
35
+ #
36
+ # @param token_id [String]
37
+ # @param at_time [Integer] optional timestamp
38
+ #
39
+ # @return [Hash] market price data
40
+ def price(token_id:, at_time: nil)
41
+ params = { token_id: token_id }
42
+ params[:at_time] = at_time if at_time
43
+ client.get('markets/get_market_price', params: params)
44
+ end
45
+
46
+ # Get OHLC candlesticks
47
+ #
48
+ # @param condition_id [String]
49
+ # @param start_time [Integer]
50
+ # @param end_time [Integer]
51
+ # @param interval [Integer]
52
+ #
53
+ # @return [Hash] candlestick data
54
+ def candlesticks(condition_id:, start_time:, end_time:, interval:)
55
+ params = {
56
+ condition_id: condition_id,
57
+ start_time: start_time,
58
+ end_time: end_time,
59
+ interval: interval
60
+ }
61
+ client.get('markets/get_candlesticks', params: params)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubyists
4
+ module Domeapi
5
+ module Polymarket
6
+ # Orders API endpoints
7
+ class Orders
8
+ attr_reader :client
9
+
10
+ def initialize(client)
11
+ @client = client
12
+ end
13
+
14
+ # Query orders with filtering options
15
+ # @param market_slug [String]
16
+ # @param start_time [Integer]
17
+ # @param end_time [Integer]
18
+ # @param limit [Integer]
19
+ def list(market_slug: nil, start_time: nil, end_time: nil, limit: nil)
20
+ params = {
21
+ market_slug:,
22
+ start_time:,
23
+ end_time:,
24
+ limit:
25
+ }.compact
26
+
27
+ client.get('orders/get_orders', params: params)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubyists
4
+ module Domeapi
5
+ # Namespace for Polymarket-related functionality
6
+ module Polymarket
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubyists
4
+ # Domeapi module
5
+ module Domeapi
6
+ # x-release-please-start-version
7
+ VERSION = '0.0.1'
8
+ # x-release-please-end
9
+ end
10
+ end
data/lib/domeapi.rb ADDED
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'semantic_logger'
4
+ require 'zeitwerk'
5
+ require 'dry-configurable'
6
+ require_relative 'domeapi/version'
7
+
8
+ module Rubyists
9
+ # Domeapi module
10
+ module Domeapi
11
+ extend Dry::Configurable
12
+
13
+ setting :api_key, default: ENV.fetch('DOMEAPI_API_KEY', nil)
14
+ setting :base_url, default: 'https://api.domeapi.io/v1'
15
+
16
+ include SemanticLogger::Loggable
17
+
18
+ class Error < StandardError; end
19
+
20
+ # Operation submodule, for Trailblazer operations
21
+ module Operation; end
22
+
23
+ def self.client
24
+ @client ||= Client.new
25
+ end
26
+ end
27
+ end
28
+
29
+ loader = Zeitwerk::Loader.new
30
+ loader.tag = 'rubyists-domeapi'
31
+ loader.push_dir("#{__dir__}/domeapi", namespace: Rubyists::Domeapi)
32
+ loader.push_dir("#{__dir__}/domeapi/operations", namespace: Rubyists::Domeapi::Operation)
33
+ loader.ignore("#{__dir__}/domeapi/version.rb")
34
+ loader.setup
data/mise.toml ADDED
@@ -0,0 +1,2 @@
1
+ [tools]
2
+ ruby = "4"
data/sig/domeapi.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Domeapi
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,202 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: domeapi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tj (bougyman) Vanderpoel
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: dry-cli
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: dry-configurable
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: dry-container
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: dry-validation
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: httpx
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: reform
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: semantic_logger
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: trailblazer
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ type: :runtime
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ - !ruby/object:Gem::Dependency
125
+ name: webmock
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ type: :runtime
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ - !ruby/object:Gem::Dependency
139
+ name: zeitwerk
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ type: :runtime
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ email:
153
+ - bougyman@users.noreply.github.com
154
+ executables:
155
+ - domeapi
156
+ extensions: []
157
+ extra_rdoc_files: []
158
+ files:
159
+ - ".release-please-config.json"
160
+ - ".release-please-manifest.json"
161
+ - AGENTS.md
162
+ - Rakefile
163
+ - Readme.adoc
164
+ - ci/build_image.sh
165
+ - ci/publish-gem.sh
166
+ - exe/domeapi
167
+ - lib/domeapi.rb
168
+ - lib/domeapi/client.rb
169
+ - lib/domeapi/contract.rb
170
+ - lib/domeapi/polymarket.rb
171
+ - lib/domeapi/polymarket/client.rb
172
+ - lib/domeapi/polymarket/market_filter.rb
173
+ - lib/domeapi/polymarket/markets.rb
174
+ - lib/domeapi/polymarket/orders.rb
175
+ - lib/domeapi/version.rb
176
+ - mise.toml
177
+ - sig/domeapi.rbs
178
+ homepage: https://github.com/rubyists/domeapi
179
+ licenses: []
180
+ metadata:
181
+ allowed_push_host: https://rubygems.org
182
+ homepage_uri: https://github.com/rubyists/domeapi
183
+ source_code_uri: https://github.com/rubyists/domeapi
184
+ rubygems_mfa_required: 'true'
185
+ rdoc_options: []
186
+ require_paths:
187
+ - lib
188
+ required_ruby_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '4.0'
193
+ required_rubygems_version: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ requirements: []
199
+ rubygems_version: 4.0.3
200
+ specification_version: 4
201
+ summary: Ruby SDK for domeapi.io (unofficial).
202
+ test_files: []