mooncats-graphql 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: da57d2e625ff09695d4678abe4b42267b31a951f538bccba41f692973b932585
4
+ data.tar.gz: f829e8e7042bfa6269eb844c69f8dffc9c0da8d8c8be0b282a939f3096ae49a2
5
+ SHA512:
6
+ metadata.gz: ba9445031e9252911b3b16d9f28a3bf7b566deeab239602ed467b74ad2d4e798f686116a7ef0153d9d1bad5da3fe7863e412f44e62143e74a3beaaa073d5cea0
7
+ data.tar.gz: 264bafe762848cdf7627735bfe44735b3b8384003da0a2aa43668e25db1163714ddd6e230c2f83dd98c351ffea1e2a39f8945f629211de34578334251f8700aa
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ### 0.0.1 / 2021-03-31
2
+
3
+ * Everything is new. First release
data/Manifest.txt ADDED
@@ -0,0 +1,9 @@
1
+ CHANGELOG.md
2
+ Manifest.txt
3
+ README.md
4
+ Rakefile
5
+ lib/mooncats-graphql.rb
6
+ lib/mooncats/graphql.rb
7
+ lib/mooncats/graphql/client.rb
8
+ lib/mooncats/graphql/query.rb
9
+ lib/mooncats/graphql/version.rb
data/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # Mooncats GraphQL
2
+
3
+
4
+ mooncats-graphql - web client (helpers) for using MoonCats (HTTP JSON) GraphQL APIs
5
+
6
+
7
+ * home :: [github.com/cryptocopycats/mooncats](https://github.com/cryptocopycats/mooncats)
8
+ * bugs :: [github.com/cryptocopycats/mooncats/issues](https://github.com/cryptocopycats/mooncats/issues)
9
+ * gem :: [rubygems.org/gems/mooncats-graphql](https://rubygems.org/gems/mooncats-graphql)
10
+ * rdoc :: [rubydoc.info/gems/mooncats-graphql](http://rubydoc.info/gems/mooncats-graphql)
11
+
12
+
13
+
14
+
15
+ ## Usage
16
+
17
+ A lite web client wrapper for the Moon Cats Rescue open graph api
18
+ powered by the Graph.
19
+ See [**thegraph.com/explorer/subgraph/merklejerk/moon-cats-rescue »**](https://thegraph.com/explorer/subgraph/merklejerk/moon-cats-rescue).
20
+
21
+
22
+ ``` ruby
23
+ require 'mooncats/graphql'
24
+
25
+ c = Mooncats::GraphQL::Client.new
26
+
27
+ data = c.query_bestsellers( first: 12 )
28
+ ```
29
+
30
+ resulting in:
31
+
32
+ ``` ruby
33
+ [{"id" => "0xff52000ca7",
34
+ "isGenesis" => true,
35
+ "maxAdoptionPrice" => "55500000000000000000",
36
+ "name" => nil,
37
+ "rescueBlock" => 4363303,
38
+ "rescueIndex" => 2878,
39
+ "rescueTime" => 1507932258},
40
+ {"id" => "0xff50000ca7",
41
+ "isGenesis" => true,
42
+ "maxAdoptionPrice" => "55500000000000000000",
43
+ "name" => nil,
44
+ "rescueBlock" => 4363303,
45
+ "rescueIndex" => 2876,
46
+ "rescueTime" => 1507932258},
47
+ #...
48
+ ]
49
+ ```
50
+
51
+ Note: Depending on the query either a data array (zero, one or more records)
52
+ e.g. `query_bestsellers`
53
+ or a hash table or nil (one or no record) e.g. `query_cat_by_id`
54
+ gets returned. Use like:
55
+
56
+
57
+ ``` ruby
58
+ data.each_with_index do |rec,i|
59
+ print '%2d. ' % (i+1)
60
+ print '%3d ETH' % (rec['maxAdoptionPrice'].to_i / 1000000000000000000)
61
+ print ' - '
62
+ print rec['id']
63
+ print "\n"
64
+ end
65
+ ```
66
+
67
+ printing:
68
+
69
+ ```
70
+ 1. 55 ETH - 0xff52000ca7
71
+ 2. 55 ETH - 0xff50000ca7
72
+ 3. 49 ETH - 0x00816eb855
73
+ 4. 32 ETH - 0x00ac2b3f23
74
+ 5. 13 ETH - 0x00f28bec4f
75
+ 6. 12 ETH - 0x00304c8e29
76
+ 7. 12 ETH - 0x002179a08d
77
+ 8. 10 ETH - 0xff0b000ca7
78
+ 9. 10 ETH - 0x0080ea1503
79
+ 10. 8 ETH - 0x00e38e784c
80
+ 11. 8 ETH - 0x00c1832514
81
+ 12. 8 ETH - 0x0002b77279
82
+ ```
83
+
84
+
85
+ More pre-configured / built-in queries include:
86
+
87
+
88
+ ``` ruby
89
+ query_cats
90
+ query_mint_2017( first: 10 )
91
+ query_cat_by_id( id: '0xff52000ca7' )
92
+ query_cat_by_wrapper_id( id: 0 )
93
+ query_cheap_mints_2017
94
+ query_latest_adoptions
95
+ query_latest_donations
96
+ query_top_collectors
97
+ query_wrapped
98
+ ```
99
+
100
+ See the [query source](lib/mooncats/graphql/query.rb) for more.
101
+
102
+
103
+
104
+ ### Pagination - 1000 Records Max. Limit / Request
105
+
106
+ Note: The open graph api has a 1000 records limit per request.
107
+ The recommended way for pagination is to use
108
+ a greater than last record id in the where clause in the query
109
+ to get the next page / batch.
110
+ Example - `query_cats`:
111
+
112
+ ``` graphql
113
+ {
114
+ cats(first: 1000,
115
+ where: { id_gt: $last_id }) {
116
+ id
117
+ # ...
118
+ }
119
+ }
120
+ ```
121
+
122
+ Get all 25 440 MoonCat blockchain data
123
+ in 26 batches / requests of a thousand each:
124
+
125
+ ``` ruby
126
+ # ~26 000 mooncats - download in 26 batches of 1000 each
127
+ last_id = '0x0000000000'
128
+ 26.times do |i|
129
+ puts "downloading batch #{i}..."
130
+ data = c.query_cats( last_id: last_id )
131
+ puts " #{data.size} records(s)"
132
+
133
+ ## process data here
134
+
135
+ last_id = data[-1]['id'] ## get id from last record using index -1
136
+ puts " last_id: #{last_id}"
137
+ sleep( 1 )
138
+ end
139
+ ```
140
+
141
+ resulting in:
142
+
143
+ ```
144
+ downloading batch 0...
145
+ 1000 record(s)
146
+ last_id: 0x000a05b9ac
147
+ downloading batch 1...
148
+ 1000 record(s)
149
+ last_id: 0x0013b68a2f
150
+ ...
151
+ ```
152
+
153
+ That's it.
154
+
155
+
156
+
157
+ ## New to MoonCats?
158
+
159
+ See the
160
+ [**Programming MoonCats & MarsCats Step-by-Step Booklet / Guide »**](https://github.com/cryptocopycats/programming-mooncats)
161
+
162
+
163
+
164
+
165
+ ## Install
166
+
167
+ Just install the gem:
168
+
169
+ $ gem install mooncats-graphql
170
+
171
+
172
+ ## License
173
+
174
+ The scripts are dedicated to the public domain.
175
+ Use it as you please with no restrictions whatsoever.
176
+
177
+
178
+ ## Questions? Comments?
179
+
180
+ Post them on the [mooncatrescue reddit](https://www.reddit.com/r/mooncatrescue). Thanks.
181
+
182
+
183
+
184
+
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ require 'hoe'
2
+ require './lib/mooncats/graphql/version.rb'
3
+
4
+ Hoe.spec 'mooncats-graphql' do
5
+
6
+ self.version = MooncatsClient::VERSION
7
+
8
+ self.summary = "mooncats-graphql - (lite) mooncats (http json) graphql api / client"
9
+ self.description = summary
10
+
11
+ self.urls = { home: 'https://github.com/cryptocopycats/mooncats' }
12
+
13
+ self.author = 'Gerald Bauer'
14
+ self.email = 'wwwmake@googlegroups.com'
15
+
16
+ # switch extension to .markdown for gihub formatting
17
+ self.readme_file = 'README.md'
18
+ self.history_file = 'CHANGELOG.md'
19
+
20
+ self.extra_deps = [
21
+ ]
22
+
23
+ self.licenses = ['Public Domain']
24
+
25
+ self.spec_extras = {
26
+ required_ruby_version: '>= 2.3'
27
+ }
28
+
29
+ end
@@ -0,0 +1,7 @@
1
+ ###
2
+ ## convenience helper enables / allows alternate require path
3
+ # require 'mooncats-graphql'
4
+
5
+ require_relative 'mooncats/graphql'
6
+
7
+
@@ -0,0 +1,22 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+ require 'json'
5
+ require 'yaml'
6
+ require 'date'
7
+ require 'time'
8
+ require 'fileutils'
9
+ require 'pp'
10
+
11
+
12
+
13
+ ## our own code
14
+ require 'mooncats/graphql/version' # note: let version always go first
15
+ require 'mooncats/graphql/client'
16
+ require 'mooncats/graphql/query'
17
+
18
+
19
+
20
+
21
+ # say hello
22
+ puts MooncatsClient.banner
@@ -0,0 +1,43 @@
1
+
2
+ module Mooncats
3
+ class Client
4
+
5
+
6
+ def initialize( base_uri: )
7
+ @base_uri = base_uri
8
+ end
9
+
10
+ def post( **params )
11
+
12
+ uri = URI.parse( @base_uri )
13
+ res = Net::HTTP.start( uri.host, uri.port,
14
+ use_ssl: true) do |http|
15
+ req = Net::HTTP::Post.new( uri )
16
+ req['Content-Type'] = 'application/json'
17
+
18
+ # note: the body needs to be a JSON string
19
+ req.body = JSON.generate( params )
20
+
21
+ # puts
22
+ # puts "graphql post:"
23
+ # puts req.body
24
+ # puts "---"
25
+
26
+ http.request( req )
27
+ end
28
+
29
+ if res.code.to_i != 200
30
+ puts "!! ERROR: HTTP #{res.code} #{res.message}:"
31
+ pp res
32
+ exit 1
33
+ end
34
+
35
+ body = res.body.to_s
36
+ ## note: assumes ascii-8bit/binary encoding (by default)
37
+ ## change to utf-8 (as always required by json )
38
+ body = body.force_encoding( Encoding::UTF_8 )
39
+
40
+ data = JSON.parse( body )
41
+ end
42
+ end # class Client
43
+ end # module Mooncats
@@ -0,0 +1,293 @@
1
+
2
+ module Mooncats
3
+ module GraphQL
4
+
5
+ class Client < ::Mooncats::Client
6
+ def initialize
7
+ super( base_uri: 'https://api.thegraph.com/subgraphs/name/merklejerk/moon-cats-rescue' )
8
+ end
9
+
10
+
11
+ def query_bestsellers( first: 100,
12
+ includes: [] )
13
+ query = <<GRAPHQL
14
+ {
15
+ cats(first: $first, orderBy: maxAdoptionPrice, orderDirection: desc) {
16
+ id
17
+ rescueIndex
18
+ rescueBlock
19
+ rescueTime
20
+ name
21
+ isGenesis
22
+ maxAdoptionPrice
23
+ # @INCLUDES - lets you add more fields e.g. maxAdoptionPrice etc.
24
+ }
25
+ }
26
+ GRAPHQL
27
+ query = query.gsub( '$first', first.to_s )
28
+
29
+ data = query( query, includes: includes )
30
+ data['data']['cats'] ## return nested data
31
+ end
32
+
33
+ def query_cheap_mints_2017( first: 100,
34
+ includes: [] )
35
+ query = <<GRAPHQL
36
+ {
37
+ cats(first: $first, orderBy: askPrice,
38
+ where: {rescueTime_lt: 1514764800, askPrice_gt: 0}) {
39
+ id
40
+ name
41
+ rescueIndex
42
+ rescueTime
43
+ askPrice
44
+ # @INCLUDES - lets you add more fields e.g. maxAdoptionPrice etc.
45
+ }
46
+ }
47
+ GRAPHQL
48
+ query = query.gsub( '$first', first.to_s )
49
+
50
+ data = query( query, includes: includes )
51
+ data['data']['cats'] ## return nested data
52
+ end
53
+
54
+
55
+ def query_mint_2017( first: 100,
56
+ last_rescue_index: -1,
57
+ includes: [] )
58
+ query = <<GRAPHQL
59
+ {
60
+ cats(first: $first, ## note: max is 1000
61
+ orderBy: rescueIndex,
62
+ where:
63
+ { rescueTime_lt: 1514764800,
64
+ rescueIndex_gt: $last_rescue_index ## for paging in batches of 1000
65
+ }) {
66
+ id
67
+ rescueIndex
68
+ rescueBlock
69
+ rescueTime
70
+ name
71
+ # @INCLUDES - lets you add more fields e.g. maxAdoptionPrice, askPrice, etc.
72
+ }
73
+ }
74
+ GRAPHQL
75
+ query = query.gsub( '$first', first.to_s )
76
+ query = query.gsub( '$last_rescue_index', last_rescue_index.to_s )
77
+
78
+ data = query( query, includes: includes )
79
+ data['data']['cats']
80
+ end
81
+
82
+
83
+ def query_cats( first: 1000,
84
+ last_id: '0x00',
85
+ includes: [] )
86
+ query = <<GRAPHQL
87
+ {
88
+ cats(first: $first, ## note: max is 1000
89
+ where: { id_gt: $last_id }) {
90
+ id
91
+ rescueIndex
92
+ rescueBlock
93
+ rescueTime
94
+ name
95
+ # @INCLUDES - lets you add more fields e.g. maxAdoptionPrice, askPrice, etc.
96
+ }
97
+ }
98
+ GRAPHQL
99
+ query = query.gsub( '$first', first.to_s )
100
+ query = query.gsub( '$last_id', %Q<"#{last_id}"> )
101
+
102
+ data = query( query, includes: includes )
103
+ data['data']['cats']
104
+ end
105
+
106
+
107
+ def query_cat_by_id( id:,
108
+ includes: [] )
109
+ query = <<GRAPHQL
110
+ {
111
+ cat(id: $id) {
112
+ id
113
+ rescueIndex
114
+ rescueTime
115
+ name
116
+ isGenesis
117
+ maxAdoptionPrice
118
+ wrapperTokenId
119
+ owner {
120
+ id
121
+ }
122
+ bid {
123
+ price
124
+ }
125
+ ask {
126
+ price
127
+ }
128
+ # @INCLUDES - lets you add more fields e.g. maxAdoptionPrice, askPrice, etc.
129
+ }
130
+ }
131
+ GRAPHQL
132
+ query = query.gsub( '$id', %Q<"#{id}"> )
133
+
134
+ data = query( query, includes: includes )
135
+ data['data']['cat'] ## note: returns single (one-only) cat record
136
+ end
137
+
138
+
139
+ def query_cat_by_wrapper_id( id:,
140
+ includes: [] )
141
+ query = <<GRAPHQL
142
+ {
143
+ cats(where: {wrapperTokenId: $wrapper_token_id}) {
144
+ id
145
+ rescueIndex
146
+ rescueTime
147
+ name
148
+ isGenesis
149
+ maxAdoptionPrice
150
+ wrapperTokenId
151
+ owner {
152
+ id
153
+ }
154
+ bid {
155
+ price
156
+ }
157
+ ask {
158
+ price
159
+ }
160
+ # @INCLUDES - lets you add more fields e.g. maxAdoptionPrice, askPrice, etc.
161
+ }
162
+ }
163
+ GRAPHQL
164
+ query = query.gsub( '$wrapper_token_id', id.to_s )
165
+
166
+ data = query( query, includes: includes )
167
+ data['data']['cats'][0] # note: try to get first record only (by default) - why? why not?
168
+ end
169
+
170
+ def query_latest_adoptions( first: 100,
171
+ includes: [] )
172
+ query = <<GRAPHQL
173
+ {
174
+ adoptions(first: $first, orderBy: time, orderDirection: desc,
175
+ where: {price_gt: 0}) {
176
+ cat {
177
+ id
178
+ rescueIndex
179
+ isGenesis
180
+ }
181
+ time
182
+ price
183
+ to {
184
+ id
185
+ }
186
+ # @INCLUDES - lets you add more fields e.g. maxAdoptionPrice, askPrice, etc.
187
+ }
188
+ }
189
+ GRAPHQL
190
+ query = query.gsub( '$first', first.to_s )
191
+
192
+ data = query( query, includes: includes )
193
+ data['data']['adoptions']
194
+ end
195
+ alias_method :query_recent_adoptions, :query_latest_adoptions
196
+
197
+
198
+ def query_latest_donations( first: 100,
199
+ includes: [] )
200
+ query = <<GRAPHQL
201
+ {
202
+ adoptions(first: $first, orderBy: time, orderDirection: desc,
203
+ where: {price: 0, isWrapping: false}) {
204
+ cat {
205
+ id
206
+ rescueIndex
207
+ isGenesis
208
+ }
209
+ time
210
+ to {
211
+ id
212
+ }
213
+ # @INCLUDES - lets you add more fields e.g. maxAdoptionPrice, askPrice, etc.
214
+ }
215
+ }
216
+ GRAPHQL
217
+ query = query.gsub( '$first', first.to_s )
218
+
219
+ data = query( query, includes: includes )
220
+ data['data']['adoptions']
221
+ end
222
+ alias_method :query_recent_donations, :query_latest_donations
223
+
224
+
225
+ def query_top_collectors( first: 10,
226
+ includes: [] )
227
+ query = <<GRAPHQL
228
+ {
229
+ owners(first: $first, orderBy: catCount, orderDirection: desc,
230
+ where: {isWrapper: false}) {
231
+ id
232
+ catCount
233
+ }
234
+ }
235
+ GRAPHQL
236
+ query = query.gsub( '$first', first.to_s )
237
+
238
+ data = query( query, includes: includes )
239
+ data['data']['owners']
240
+ end
241
+
242
+
243
+ def query_wrapped( first: 100,
244
+ last_rescue_index: -1,
245
+ includes: [] )
246
+ query = <<GRAPHQL
247
+ {
248
+ cats(first: $first, orderBy: rescueIndex,
249
+ where:
250
+ { wrapperTokenId_not: null,
251
+ rescueIndex_gt: $last_rescue_index ## for paging in batches of 1000
252
+ }) {
253
+ id
254
+ rescueIndex
255
+ isGenesis
256
+ name
257
+ wrapperTokenId
258
+ wrapperOwner {
259
+ id
260
+ }
261
+ # @INCLUDES - lets you add more fields e.g. maxAdoptionPrice, askPrice, etc.
262
+ }
263
+ }
264
+ GRAPHQL
265
+ query = query.gsub( '$first', first.to_s )
266
+ query = query.gsub( '$last_rescue_index', last_rescue_index.to_s )
267
+
268
+ data = query( query, includes: includes )
269
+ data['data']['cats']
270
+ end
271
+
272
+
273
+
274
+
275
+
276
+ #####
277
+ # generic query via HTTP POST
278
+ def query( query, includes: [] )
279
+ if includes.size > 0
280
+ ## check for end-of-line comments with @INCLUDES marker
281
+ query = query.gsub( /[#]+[ ]+@INCLUDES[^\n\r]+/,
282
+ includes.join( ' ' ) )
283
+ end
284
+
285
+ post( query: query )
286
+ end
287
+
288
+
289
+ end # class Client
290
+ end # module GraphQL
291
+ end # module Mooncats
292
+
293
+
@@ -0,0 +1,22 @@
1
+
2
+ module MooncatsClient
3
+
4
+ MAJOR = 0
5
+ MINOR = 1
6
+ PATCH = 0
7
+ VERSION = [MAJOR,MINOR,PATCH].join('.')
8
+
9
+ def self.version
10
+ VERSION
11
+ end
12
+
13
+ def self.banner
14
+ "mooncats-graphql/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in #{root}"
15
+ end
16
+
17
+ def self.root
18
+ File.expand_path( File.dirname(File.dirname(File.dirname(File.dirname(__FILE__)))) )
19
+ end
20
+
21
+ end # module MooncatsClient
22
+
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mooncats-graphql
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Gerald Bauer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-03-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rdoc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '7'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '4.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '7'
33
+ - !ruby/object:Gem::Dependency
34
+ name: hoe
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.22'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.22'
47
+ description: mooncats-graphql - (lite) mooncats (http json) graphql api / client
48
+ email: wwwmake@googlegroups.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files:
52
+ - CHANGELOG.md
53
+ - Manifest.txt
54
+ - README.md
55
+ files:
56
+ - CHANGELOG.md
57
+ - Manifest.txt
58
+ - README.md
59
+ - Rakefile
60
+ - lib/mooncats-graphql.rb
61
+ - lib/mooncats/graphql.rb
62
+ - lib/mooncats/graphql/client.rb
63
+ - lib/mooncats/graphql/query.rb
64
+ - lib/mooncats/graphql/version.rb
65
+ homepage: https://github.com/cryptocopycats/mooncats
66
+ licenses:
67
+ - Public Domain
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options:
71
+ - "--main"
72
+ - README.md
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '2.3'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubygems_version: 3.1.4
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: mooncats-graphql - (lite) mooncats (http json) graphql api / client
90
+ test_files: []