mooncats-graphql 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []