cryptologo 0.1.0

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: 75211d3891b83a244b6ae5858315bd04aff1998321e57d77051c547798649238
4
+ data.tar.gz: a2ff5b4633c8672348b7407110c3ff29aef53adec4851b9d8c16179439595b12
5
+ SHA512:
6
+ metadata.gz: 11ef2e7ac9585c1c45dda8fda18f299b22a248c83eb3345b54b99e6a4507991cd6180dc370b954e1e287698bfe0234b4b8d3c6638e9d14fa4267a4e4976470be
7
+ data.tar.gz: 80d447e1d4b3a6b2f8c02e5a89fb8d35e7e0c41c96dbee64eb5b7e379b9d2aaab9a16f3906c9a16535fbd1549b9ea08ac4420a97c6e4a8071186793456c64c79
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dobestan
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,134 @@
1
+ # cryptologo
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/cryptologo.svg)](https://rubygems.org/gems/cryptologo)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
+ [![Zero Dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)](https://rubygems.org/gems/cryptologo)
6
+
7
+ Ruby client for [crypto-logo.com](https://crypto-logo.com) — the cryptocurrency logo database with 413 coins in SVG, PNG, WebP, JPEG, and ICO formats. Zero external dependencies (stdlib `net/http` only).
8
+
9
+ Every logo is available as a scalable SVG vector and pre-generated raster derivatives in 13 standard sizes (16px to 2000px). Logos are served from Cloudflare R2 CDN with immutable cache headers.
10
+
11
+ > **Browse logos at [crypto-logo.com](https://crypto-logo.com)** — [API docs](https://crypto-logo.com/api/docs/)
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ gem install cryptologo
17
+ ```
18
+
19
+ Or in your Gemfile:
20
+
21
+ ```ruby
22
+ gem "cryptologo"
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```ruby
28
+ require "cryptologo"
29
+
30
+ client = CryptoLogo::Client.new
31
+
32
+ # List all 413 coins sorted by market cap
33
+ coins = client.list_coins
34
+ coins.first(3).each do |coin|
35
+ puts "#{coin.name} (#{coin.ticker}) — rank ##{coin.market_cap_rank}"
36
+ end
37
+
38
+ # Download Bitcoin SVG logo
39
+ client.download_logo("bitcoin-btc", "svg", "bitcoin.svg")
40
+
41
+ # Generate CDN URL for embedding
42
+ url = client.get_cdn_url("ethereum-eth", "webp", 128)
43
+ # https://cdn.crypto-logo.com/logos/ethereum-eth/128x128/transparent.webp
44
+ ```
45
+
46
+ ## What You Can Do
47
+
48
+ ### List Coins
49
+
50
+ ```ruby
51
+ coins = client.list_coins
52
+
53
+ # Filter coins with SVG logos
54
+ svg_coins = coins.select(&:has_svg)
55
+ puts "#{svg_coins.length} coins have SVG logos"
56
+
57
+ # Find by ticker
58
+ btc = coins.find { |c| c.ticker == "BTC" }
59
+ puts "#{btc.name}: rank ##{btc.market_cap_rank}"
60
+ ```
61
+
62
+ ### Fetch Logos
63
+
64
+ ```ruby
65
+ # SVG vector (no size needed)
66
+ svg = client.get_logo("bitcoin-btc", "svg")
67
+
68
+ # PNG at 256x256
69
+ png = client.get_logo("bitcoin-btc", "png", width: 256)
70
+
71
+ # OG image with white background
72
+ og = client.get_logo("bitcoin-btc", "png", width: 1200, height: 630, bg: "FFFFFF")
73
+
74
+ # Save to file
75
+ client.download_logo("ethereum-eth", "png", "eth.png", width: 512)
76
+ ```
77
+
78
+ ### CDN URLs
79
+
80
+ ```ruby
81
+ # CDN URL for fast display (recommended for HTML img tags)
82
+ url = client.get_cdn_url("bitcoin-btc", "webp", 128)
83
+ # https://cdn.crypto-logo.com/logos/bitcoin-btc/128x128/transparent.webp
84
+
85
+ # API URL for downloads
86
+ url = client.get_logo_url("bitcoin-btc", "png", width: 512)
87
+ # https://crypto-logo.com/api/logo/bitcoin-btc.png?w=512&h=512
88
+ ```
89
+
90
+ ### Variants and History
91
+
92
+ ```ruby
93
+ # Get a logo variant (alternate design)
94
+ full_logo = client.get_asset("versions/bitcoin-btc-full.svg")
95
+
96
+ # Get a historical logo
97
+ old_logo = client.get_asset("history/bitcoin-btc-2009.png")
98
+ ```
99
+
100
+ ## Cryptocurrency Logo Standards
101
+
102
+ | Use Case | Format | Size |
103
+ |----------|--------|------|
104
+ | Website UI | SVG | Scalable |
105
+ | Exchange listing | PNG | 512x512 |
106
+ | Mobile icon | PNG | 128-256px |
107
+ | Social/OG | PNG | 1200x630 |
108
+ | Favicon | ICO/SVG | 32x32 |
109
+
110
+ Pre-generated sizes: 16, 32, 48, 64, 96, 120, 128, 200, 256, 400, 512, 1024, 2000.
111
+
112
+ ## API Reference
113
+
114
+ | Method | Returns | Description |
115
+ |--------|---------|-------------|
116
+ | `list_coins` | `Array<Coin>` | All 413 coins |
117
+ | `get_logo(slug, fmt, **opts)` | `String` | Logo bytes |
118
+ | `get_logo_url(slug, fmt, **opts)` | `String` | API URL |
119
+ | `get_cdn_url(slug, fmt, width)` | `String` | CDN URL |
120
+ | `download_logo(slug, fmt, dest, **opts)` | `String` | Save to file |
121
+ | `get_asset(path)` | `String` | Variant/history |
122
+
123
+ ## Also Available
124
+
125
+ | Platform | Package | Install |
126
+ |----------|---------|---------|
127
+ | **PyPI** | [cryptologo](https://pypi.org/project/cryptologo/) | `pip install cryptologo` |
128
+ | **npm** | [cryptologo](https://www.npmjs.com/package/cryptologo) | `npm install cryptologo` |
129
+ | **Go** | [cryptologo-go](https://github.com/dobestan/cryptologo-go) | `go get github.com/dobestan/cryptologo-go` |
130
+ | **Rust** | [cryptologo](https://crates.io/crates/cryptologo) | `cargo add cryptologo` |
131
+
132
+ ## License
133
+
134
+ MIT
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "json"
5
+ require "uri"
6
+
7
+ module CryptoLogo
8
+ # Client for the crypto-logo.com API.
9
+ #
10
+ # Provides methods to list coins, fetch logos, generate logo URLs,
11
+ # and download logo files. No API key required.
12
+ #
13
+ # @example
14
+ # client = CryptoLogo::Client.new
15
+ # coins = client.list_coins
16
+ # svg = client.get_logo("bitcoin-btc", "svg")
17
+ # client.download_logo("ethereum-eth", "png", "eth.png", width: 512)
18
+ class Client
19
+ USER_AGENT = "cryptologo-rb/#{VERSION}"
20
+
21
+ # @param base_url [String] API base URL
22
+ # @param timeout [Integer] Request timeout in seconds
23
+ def initialize(base_url: DEFAULT_BASE_URL, timeout: 30)
24
+ @base_url = base_url.chomp("/")
25
+ @timeout = timeout
26
+ end
27
+
28
+ # Fetch all active coins from the API.
29
+ #
30
+ # @return [Array<Coin>] coins sorted by market cap rank
31
+ #
32
+ # @example
33
+ # coins = client.list_coins
34
+ # coins.first(3).each { |c| puts "#{c.name} (#{c.ticker})" }
35
+ def list_coins
36
+ data = get_json("/api/coins.json")
37
+ data.map { |item| Coin.from_hash(item) }
38
+ end
39
+
40
+ # Fetch logo image bytes from the API.
41
+ #
42
+ # @param slug [String] Coin slug (e.g., "bitcoin-btc")
43
+ # @param fmt [String] Image format: "svg", "png", "webp", "jpeg", "ico"
44
+ # @param width [Integer, nil] Output width in pixels
45
+ # @param height [Integer, nil] Output height in pixels
46
+ # @param bg [String, nil] Background hex color without #
47
+ # @return [String] Raw image bytes
48
+ #
49
+ # @example
50
+ # svg = client.get_logo("bitcoin-btc", "svg")
51
+ # png = client.get_logo("bitcoin-btc", "png", width: 256)
52
+ def get_logo(slug, fmt = "svg", width: nil, height: nil, bg: nil)
53
+ url = get_logo_url(slug, fmt, width: width, height: height, bg: bg)
54
+ get_bytes(url)
55
+ end
56
+
57
+ # Build the API URL for a logo.
58
+ #
59
+ # @param slug [String] Coin slug
60
+ # @param fmt [String] Image format
61
+ # @param width [Integer, nil] Width in pixels
62
+ # @param height [Integer, nil] Height in pixels
63
+ # @param bg [String, nil] Background hex color
64
+ # @return [String] Full API URL
65
+ #
66
+ # @example
67
+ # url = client.get_logo_url("bitcoin-btc", "png", width: 512)
68
+ # # "https://crypto-logo.com/api/logo/bitcoin-btc.png?w=512&h=512"
69
+ def get_logo_url(slug, fmt = "svg", width: nil, height: nil, bg: nil)
70
+ url = "#{@base_url}/api/logo/#{slug}.#{fmt}"
71
+ params = []
72
+ params << "w=#{width}" if width
73
+ h = height || width
74
+ params << "h=#{h}" if h
75
+ params << "bg=#{bg}" if bg
76
+ url += "?#{params.join("&")}" unless params.empty?
77
+ url
78
+ end
79
+
80
+ # Build a CDN URL for direct image embedding.
81
+ #
82
+ # @param slug [String] Coin slug
83
+ # @param fmt [String] Image format
84
+ # @param width [Integer] Square size in pixels
85
+ # @param cdn_domain [String] CDN hostname
86
+ # @return [String] CDN URL
87
+ #
88
+ # @example
89
+ # url = client.get_cdn_url("bitcoin-btc", "webp", 128)
90
+ # # "https://cdn.crypto-logo.com/logos/bitcoin-btc/128x128/transparent.webp"
91
+ def get_cdn_url(slug, fmt = "png", width = 128, cdn_domain: DEFAULT_CDN_DOMAIN)
92
+ if fmt == "svg"
93
+ "https://#{cdn_domain}/logos/#{slug}/vector.svg"
94
+ else
95
+ "https://#{cdn_domain}/logos/#{slug}/#{width}x#{width}/transparent.#{fmt}"
96
+ end
97
+ end
98
+
99
+ # Download a logo to a local file.
100
+ #
101
+ # @param slug [String] Coin slug
102
+ # @param fmt [String] Image format
103
+ # @param dest [String] Destination file path
104
+ # @param width [Integer, nil] Width in pixels
105
+ # @param height [Integer, nil] Height in pixels
106
+ # @param bg [String, nil] Background hex color
107
+ # @return [String] Path to downloaded file
108
+ #
109
+ # @example
110
+ # client.download_logo("bitcoin-btc", "svg", "bitcoin.svg")
111
+ # client.download_logo("ethereum-eth", "png", "eth.png", width: 512)
112
+ def download_logo(slug, fmt = "svg", dest = nil, width: nil, height: nil, bg: nil)
113
+ data = get_logo(slug, fmt, width: width, height: height, bg: bg)
114
+ dest ||= if fmt == "svg"
115
+ "#{slug}.svg"
116
+ elsif width
117
+ "#{slug}-#{width}x#{height || width}.#{fmt}"
118
+ else
119
+ "#{slug}.#{fmt}"
120
+ end
121
+ File.binwrite(dest, data)
122
+ dest
123
+ end
124
+
125
+ # Fetch a variant or historical logo file.
126
+ #
127
+ # @param file_path [String] Relative path (e.g., "versions/bitcoin-btc-full.svg")
128
+ # @return [String] Raw file bytes
129
+ def get_asset(file_path)
130
+ url = "#{@base_url}/api/asset/#{file_path}"
131
+ get_bytes(url)
132
+ end
133
+
134
+ private
135
+
136
+ def get_json(path)
137
+ url = "#{@base_url}#{path}"
138
+ uri = URI.parse(url)
139
+ http = Net::HTTP.new(uri.host, uri.port)
140
+ http.use_ssl = uri.scheme == "https"
141
+ http.open_timeout = @timeout
142
+ http.read_timeout = @timeout
143
+
144
+ request = Net::HTTP::Get.new(uri)
145
+ request["Accept"] = "application/json"
146
+ request["User-Agent"] = USER_AGENT
147
+
148
+ response = http.request(request)
149
+ handle_response(response, url)
150
+ JSON.parse(response.body)
151
+ end
152
+
153
+ def get_bytes(url)
154
+ uri = URI.parse(url.start_with?("http") ? url : "#{@base_url}#{url}")
155
+ http = Net::HTTP.new(uri.host, uri.port)
156
+ http.use_ssl = uri.scheme == "https"
157
+ http.open_timeout = @timeout
158
+ http.read_timeout = @timeout
159
+
160
+ request = Net::HTTP::Get.new(uri)
161
+ request["User-Agent"] = USER_AGENT
162
+
163
+ response = http.request(request)
164
+ handle_response(response, url)
165
+ response.body
166
+ end
167
+
168
+ def handle_response(response, url)
169
+ case response.code.to_i
170
+ when 200..299
171
+ # OK
172
+ when 404
173
+ raise NotFoundError, "Not found: #{url}"
174
+ else
175
+ raise Error, "HTTP #{response.code}: #{url}"
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CryptoLogo
4
+ # A cryptocurrency coin with logo availability metadata.
5
+ #
6
+ # @attr_reader name [String] Display name (e.g., "Bitcoin")
7
+ # @attr_reader ticker [String] Trading symbol (e.g., "BTC")
8
+ # @attr_reader slug [String] URL-safe identifier (e.g., "bitcoin-btc")
9
+ # @attr_reader has_png [Boolean] Whether a PNG logo is available
10
+ # @attr_reader has_svg [Boolean] Whether an SVG logo is available
11
+ # @attr_reader search_terms [Array<String>] Localized names for search
12
+ # @attr_reader market_cap_rank [Integer, nil] CoinGecko market cap ranking
13
+ Coin = Struct.new(:name, :ticker, :slug, :has_png, :has_svg, :search_terms, :market_cap_rank,
14
+ keyword_init: true) do
15
+ # Create a Coin from a parsed JSON hash.
16
+ # @param data [Hash] API response hash
17
+ # @return [Coin]
18
+ def self.from_hash(data)
19
+ new(
20
+ name: data["name"] || "",
21
+ ticker: data["ticker"] || "",
22
+ slug: data["slug"] || "",
23
+ has_png: data["has_png"] || false,
24
+ has_svg: data["has_svg"] || false,
25
+ search_terms: data["search_terms"] || [],
26
+ market_cap_rank: data["market_cap_rank"]
27
+ )
28
+ end
29
+ end
30
+
31
+ # Base error class for CryptoLogo client.
32
+ class Error < StandardError; end
33
+
34
+ # Raised when a resource is not found (HTTP 404).
35
+ class NotFoundError < Error; end
36
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CryptoLogo
4
+ VERSION = "0.1.0"
5
+ end
data/lib/cryptologo.rb ADDED
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "cryptologo/version"
4
+ require_relative "cryptologo/types"
5
+ require_relative "cryptologo/client"
6
+
7
+ # CryptoLogo — Ruby client for crypto-logo.com cryptocurrency logo API.
8
+ #
9
+ # Fetch, download, and generate URLs for 413+ cryptocurrency logos in SVG,
10
+ # PNG, WebP, JPEG, and ICO formats. Zero external dependencies.
11
+ #
12
+ # @example
13
+ # client = CryptoLogo::Client.new
14
+ # coins = client.list_coins
15
+ # svg = client.get_logo("bitcoin-btc", "svg")
16
+ # client.download_logo("ethereum-eth", "png", "eth.png", width: 512)
17
+ module CryptoLogo
18
+ # Standard pre-generated square sizes in pixels.
19
+ ALLOWED_SIZES = [16, 32, 48, 64, 96, 120, 128, 200, 256, 400, 512, 1024, 2000].freeze
20
+
21
+ # Valid ICO format sizes.
22
+ ICO_SIZES = [16, 32, 48, 64, 128, 256].freeze
23
+
24
+ # All supported image formats.
25
+ ALL_FORMATS = %w[svg png webp jpeg ico].freeze
26
+
27
+ # Default API base URL.
28
+ DEFAULT_BASE_URL = "https://crypto-logo.com"
29
+
30
+ # Default CDN domain.
31
+ DEFAULT_CDN_DOMAIN = "cdn.crypto-logo.com"
32
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cryptologo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - dobestan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-03-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Fetch, download, and generate URLs for 413+ cryptocurrency logos. Supports
14
+ SVG, PNG, WebP, JPEG, and ICO formats in 13 standard sizes. Zero external dependencies
15
+ (stdlib net/http only).
16
+ email:
17
+ - dobestan@gmail.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - LICENSE
23
+ - README.md
24
+ - lib/cryptologo.rb
25
+ - lib/cryptologo/client.rb
26
+ - lib/cryptologo/types.rb
27
+ - lib/cryptologo/version.rb
28
+ homepage: https://crypto-logo.com
29
+ licenses:
30
+ - MIT
31
+ metadata:
32
+ homepage_uri: https://crypto-logo.com
33
+ source_code_uri: https://github.com/dobestan/cryptologo-rb
34
+ documentation_uri: https://crypto-logo.com/api/docs/
35
+ rubygems_mfa_required: 'true'
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '3.0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubygems_version: 3.0.3.1
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Ruby client for crypto-logo.com — 413 cryptocurrency logos in SVG, PNG, WebP,
55
+ ICO
56
+ test_files: []