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

Constant Summary collapse

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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

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



29
30
31
32
33
34
# File 'lib/ordinals/api.rb', line 29

def initialize( base, inscription: 'inscription' )
  @base          = base
  @inscription   = inscription
  @requests      = 0  ## count requests (for delay_in_s sleeping/throttling)

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

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
# File 'lib/ordinals/api.rb', line 19

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

  ##                     shibescriptions

  @dogecoin ||= new( 'https://doginals.com', 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

#_num_to_id(num) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/ordinals/api.rb', line 110

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



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
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
# File 'lib/ordinals/api.rb', line 227

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



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

def config() Ordinals.config; end

#content(num_or_id) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/ordinals/api.rb', line 53

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



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/ordinals/api.rb', line 277

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



216
217
218
219
220
221
222
223
224
# File 'lib/ordinals/api.rb', line 216

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



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/ordinals/api.rb', line 80

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



96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/ordinals/api.rb', line 96

def sub10k_ids
  ids = []
  limit  = 100

  100.times do |i|   ## fetch first hundred (100*100=10000) inscribe ids

    offset = 99 + limit*i
    puts "==> #{i} - @ #{offset}..."
    ids += inscription_ids( offset: offset )
  end
  puts "   #{ids.size} inscribe id(s) - total"
  ids
end