Class: Ordinals::Api

Inherits:
Object
  • Object
show all
Defined in:
lib/ordinals/api.rb

Overview

change/rename Api to Client - why? why not?

Defined Under Namespace

Classes: Content

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base, inscription: 'inscription') ⇒ Api



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/ordinals/api.rb', line 31

def initialize( base, inscription: 'inscription' )
  @base          = base
  @inscription   = inscription

  ## e.g. inscriptions or shibescriptions (dogecoin)

  @inscriptions  = "#{@inscription}s"
 
  @requests      = 0  ## count requests (for delay_in_s sleeping/throttling)

  @pages = {}   ## (0-)99, (100-)199, (200-)299 etc.  


  @inscribe_id_rx = %r{
    (#{@inscription})/(?<id>[a-fi0-9]+)
   }ix
end

Class Method Details

.bitcoinObject



13
14
15
16
# File 'lib/ordinals/api.rb', line 13

def self.bitcoin
  @bitcoin ||= new( 'https://ordinals.com' )
  @bitcoin
end

.dogecoinObject

todo: add ltc and btc alias - why? why not?



19
20
21
22
23
24
25
26
# File 'lib/ordinals/api.rb', line 19

def self.dogecoin
  ## note: "doginals" call inscriptions

  ##                     shibescriptions

  ##

  ##  note: https://doginals.com no longer in operation / working

  @dogecoin ||= new( 'https://wonky-ord.dogeord.io', inscription: 'shibescription' )
  @dogecoin
end

.litecoinObject



7
8
9
10
11
# File 'lib/ordinals/api.rb', line 7

def self.litecoin
  ## @litecoin ||= new( 'https://litecoin.earlyordies.com' )

  @litecoin ||= new( 'https://ordinalslite.com' )
  @litecoin
end

Instance Method Details

#_batch_inscription_ids(batch) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/ordinals/api.rb', line 102

def _batch_inscription_ids( batch )
  ids = []
  limit  = 100

  batch.times do |i|   
    offset = 99 + limit*i

    puts "==> #{i} - @ #{offset}..."
    ## auto-add to page cache - why? why not?

    ids += (@pages[ offset ] ||= inscription_ids( offset: offset ))      
  end
  puts "   #{ids.size} inscribe id(s) - total"
  ids
end

#_num_to_id(num) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/ordinals/api.rb', line 125

def _num_to_id( num )
 limit = 100
 page, i =  num.divmod( limit )
 offset = 99+limit*page
 ## e.g.   100.divmod( 100 ) => [1,0]

 ##        100.divmod( 100 ) => [0,0]

 ##        99.divmod( 100 ) =>  [0,99]

 ## etc.

  
 ## auto-add to page cache

 ids =  @pages[ offset ] ||= inscription_ids( offset: offset )      
 ids[i] 
end

#_parse_inscription(html) ⇒ Object



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/ordinals/api.rb', line 242

def _parse_inscription( html )
  doc = Nokogiri::HTML( html )

  items = []

  title = doc.css( 'head title' )
  items << ['title', title.text]


  dls = doc.css( 'body dl' )
  dls[0].css( 'dt,dd' ).each do |el|
     if el.name == 'dt'
          items << [el.text]
     elsif el.name == 'dd'
          items[-1] << el.text
     else
       puts "!! ERROR - unexpected tag; expected dd|dl; got: #{el.name}"
       exit 1
     end
  end
  items

  ## convert to hash

  ##   and check for duplicate

  data = {}
  items.each do |k,v|
      k = k.strip
      v = v.strip
      if data.has_key?( k )
         puts "!! ERROR - duplicate key >#{k}< in:"
         pp items
         exit 1
      end
      data[ k ] = v
  end
  data


 ## post process to convert to headers format

 ##   e.g. replace space with -

 ##   and remove/exclude content & preview

 h = {}
 data.each do |k,v|
    next if ['preview', 'content'].include?( k )
    h[ k.gsub( ' ', '-') ] = v
 end
 h
end

#configObject

convenience shortcut helper



29
# File 'lib/ordinals/api.rb', line 29

def config() Ordinals.config; end

#content(num_or_id) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ordinals/api.rb', line 63

def content( num_or_id )
   id =  num_or_id.is_a?( Integer ) ? _num_to_id( num_or_id ) : num_or_id 

   src = "#{@base}/content/#{id}"
   res = get( src )

   content_type   = res.content_type
   content_length = res.content_length

   ## note - content_length -- returns an integer (number)

   ## puts "content_length:"

   ## print content_length.inspect

   ## print " - #{content_length.class.name}\n"


   content = Content.new(
                  res.blob,
                  content_type,
                  content_length )
   content
end

#get(src) ⇒ Object



292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# File 'lib/ordinals/api.rb', line 292

def get( src )
  @requests += 1

  if @requests > 1 && config.delay_in_s
    puts "request no. #{@requests}@#{@base}; sleeping #{config.delay_in_s} sec(s)..."
    sleep( config.delay_in_s )
  end

  res = Webclient.get( src )
 
  if res.status.ok?
    res
  else
    ## todo/fix: raise exception here!!!!

    puts "!! ERROR - HTTP #{res.status.code} #{res.status.message} - failed web request >#{src}<; sorry"
    exit 1
  end
end

#inscription(num_or_id) ⇒ Object

<dl>

<dt>id</dt>
<dd class=monospace>d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2i0</dd>
<dt>address</dt>
<dd class=monospace>bc1pqapcyswesvccgqsmuncd96ylghs9juthqeshdr8smmh9w7azn8zsghjjar</dd>
<dt>output value</dt>
<dd>10000</dd>
<dt>sat</dt>
<dd><a href=/sat/1320953397332258>1320953397332258</a></dd>
<dt>preview</dt>
<dd><a href=/preview/d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2i0>link</a></dd>
<dt>content</dt>
<dd><a href=/content/d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2i0>link</a></dd>
<dt>content length</dt>
<dd>71997 bytes</dd>
<dt>content type</dt>
<dd>text/plain;charset=utf-8</dd>
<dt>timestamp</dt>
<dd><time>2023-02-11 21:39:00 UTC</time></dd>
<dt>genesis height</dt>
<dd><a href=/block/776090>776090</a></dd>
<dt>genesis fee</dt>
<dd>273630</dd>
<dt>genesis transaction</dt>
<dd><a class=monospace href=/tx/d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2>d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2</a></dd>
<dt>location</dt>
<dd class=monospace>d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2:0:0</dd>
<dt>output</dt>
<dd><a class=monospace href=/output/d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2:0>d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2:0</a></dd>
<dt>offset</dt>
<dd>0</dd>

</dl>

<dl>

<dt>id</dt>
<dd class=monospace>acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37i0</dd>
<dt>address</dt>
<dd class=monospace>bc1qx3scwushtwenxtxlnjet4x2w5vg35etdtse5u0</dd>
<dt>output value</dt>
<dd>8020</dd>
<dt>sat</dt>
<dd><a href=/sat/1883186433806857>1883186433806857</a></dd>
<dt>preview</dt>
<dd><a href=/preview/acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37i0>link</a></dd>
<dt>content</dt>
<dd><a href=/content/acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37i0>link</a></dd>
<dt>content length</dt>
<dd>529 bytes</dd>
<dt>content type</dt>
<dd>image/png</dd>
<dt>timestamp</dt>
<dd><time>2023-01-31 19:34:47 UTC</time></dd>
<dt>genesis height</dt>
<dd><a href=/block/774489>774489</a></dd>
<dt>genesis fee</dt>
<dd>5340</dd>
<dt>genesis transaction</dt>
<dd><a class=monospace href=/tx/acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37>acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37</a></dd>
<dt>location</dt>
<dd class=monospace>6630ff2153985504b180fc16721d559a4cecdc66f4be6acf33509ec2100c0aa5:0:0</dd>
<dt>output</dt>
<dd><a class=monospace href=/output/6630ff2153985504b180fc16721d559a4cecdc66f4be6acf33509ec2100c0aa5:0>6630ff2153985504b180fc16721d559a4cecdc66f4be6acf33509ec2100c0aa5:0</a></dd>
<dt>offset</dt>
<dd>0</dd>

</dl>

<title>Inscription 407</title>

id =

genesis transaction + offset ???

genesis transaction: acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37 id: acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37i0 address: bc1qx3scwushtwenxtxlnjet4x2w5vg35etdtse5u0 output value: 8020 sat: 1883186433806857 content length: 529 bytes content type: image/png timestamp: 2023-01-31 19:34:47 UTC genesis height: 774489 genesis fee: 5340 genesis transaction: acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37>acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37 location: 6630ff2153985504b180fc16721d559a4cecdc66f4be6acf33509ec2100c0aa5:0:0 output: 6630ff2153985504b180fc16721d559a4cecdc66f4be6acf33509ec2100c0aa5:0 offset: 0



231
232
233
234
235
236
237
238
239
# File 'lib/ordinals/api.rb', line 231

def inscription( num_or_id )
  id =  num_or_id.is_a?( Integer ) ? _num_to_id( num_or_id ) : num_or_id 

  src = "#{@base}/#{@inscription}/#{id}"
  res = get( src )

  data = _parse_inscription( res.text )
  data
end

#inscription_ids(offset:) ⇒ Object

note: page size is for now fixed 100



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ordinals/api.rb', line 86

def inscription_ids( offset: )  ## note: page size is for now fixed 100

  ids = []

  src = "#{@base}/#{@inscriptions}/#{offset}"
  res = get( src )

  page = res.text  ### assumes utf-8 for now

  page.scan( @inscribe_id_rx ) do |_|
    m = Regexp.last_match
    ids << m[:id]
  end       
  puts "   #{ids.size} inscribe id(s)"
  ids = ids.reverse  ## assume latest inscribe id is on top (reverse)

  ids
end

#sub10k_idsObject



121
# File 'lib/ordinals/api.rb', line 121

def sub10k_ids()  _batch_inscription_ids( 100 ); end

#sub1k_idsObject

convenience sub1k & frens clubs / helpers



118
# File 'lib/ordinals/api.rb', line 118

def sub1k_ids()   _batch_inscription_ids( 10 ); end

#sub20k_idsObject



122
# File 'lib/ordinals/api.rb', line 122

def sub20k_ids()  _batch_inscription_ids( 200 ); end

#sub2k_idsObject



119
# File 'lib/ordinals/api.rb', line 119

def sub2k_ids()   _batch_inscription_ids( 20 ); end

#sub5k_idsObject



120
# File 'lib/ordinals/api.rb', line 120

def sub5k_ids()   _batch_inscription_ids( 50 ); end