Class: DropZoneCommand

Inherits:
Object
  • Object
show all
Defined in:
lib/dropzone/command.rb

Overview

This is mostly intended for use by the CLI client, though it’s conceivable that others may find it useful in some contexts.

Constant Summary collapse

MAX_TABLE_WIDTH =
80
LISTING_ATTRS =
[ :latitude, :longitude, :radius, :price_currency, 
:price_in_units, :description, :expiration_in ]
PROFILE_ATTRS =
[ :alias, :description ]
INVOICE_ATTRS =
[ :amount_due, :expiration_in ]
PAYMENT_ATTRS =
[:description, :delivery_quality, :product_quality, 
:communications_quality, :invoice_txid ]
ADDRESS_TO_SELF =
lambda{|privkey, args, params|
params.merge!(receiver_addr: privkey.addr) }
RECORD_BY_FIND =
lambda{|klass, id| klass.find id }

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(is_spec = false) ⇒ DropZoneCommand

Returns a new instance of DropZoneCommand.



175
176
177
178
# File 'lib/dropzone/command.rb', line 175

def initialize(is_spec = false)
  @is_spec = is_spec
  network! Bitcoin.network_name
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



180
181
182
# File 'lib/dropzone/command.rb', line 180

def connection
  @connection
end

Class Method Details

.create_command(action, klass, label, *attributes, &block) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/dropzone/command.rb', line 67

def create_command(action, klass, label, *attributes, &block)
  define_method(action) do |args, options|
    privkey = privkey_from args

    params = parameterize options, *attributes

    block.call privkey, args, params if block_given?

    message = klass.new params

    txid = message.save! privkey.to_base58

    puts_object '%s: %s' % [label, message.receiver_addr], 'Tx: %s' % txid, attributes, 
      message
  end
end

.show_command(action, klass, label, finder, *attributes, &block) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/dropzone/command.rb', line 84

def show_command(action, klass, label, finder, *attributes, &block)
  define_method(action) do |args, options|
    id = self.send finder,  args
    
    record = (block_given?) ? block.call(klass, id) : klass.new(id)

    if record.respond_to?(:found?) and !record.found?
      puts "%s Not Found" % label
    else
      params = attributes.collect{|attr| [attr,record.send(attr)]}.to_h

      puts_object '%s: %s' % [label, id], nil, attributes, record
    end
  end
end

Instance Method Details

#balance(args, options) ⇒ Object

Raises:

  • (OptionParser::MissingArgument)


347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/dropzone/command.rb', line 347

def balance(args, options)
  addr = args.first

  raise OptionParser::MissingArgument, "addr" unless addr
   
  network! (/\A1/.match addr) ? :bitcoin : :testnet3

  raise OptionParser::InvalidArgument, "addr" unless Bitcoin.valid_address? addr

  balance = connection.bitcoin.getbalance addr

  puts_table '%s: %s' % ['Address', addr], nil, [
    ['Balance', balance ] ]
end

#communication_list(args, options) ⇒ Object



210
211
212
213
214
215
216
217
218
219
220
# File 'lib/dropzone/command.rb', line 210

def communication_list(args, options)
  network! :testnet3

  privkey = privkey_from args, :testnet3

  Dropzone::Session.all(privkey.addr).each do |session|
    puts_table '%s: %s' % ['Session', session.txid], nil, [ 
      [:sender_addr, session.sender_addr], 
      [:receiver_addr, session.receiver_addr] ]
  end
end

#communication_new(args, options) ⇒ Object

Raises:

  • (OptionParser::MissingArgument)


190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/dropzone/command.rb', line 190

def communication_new(args, options)
  network! :testnet3

  privkey = privkey_from args, :testnet3

  receiver_addr = args[1]  if args.length > 1

  raise OptionParser::MissingArgument, 'addr' unless (
    receiver_addr && Bitcoin.valid_address?(receiver_addr) )

  session = Dropzone::Session.new privkey.to_base58,
    secret_for(privkey.addr, receiver_addr),
    receiver_addr: receiver_addr 

  txid = session.authenticate!

  puts_table '%s: %s' % ['Session', txid], nil, [ 
    [:sender_addr, privkey.addr], [:receiver_addr, receiver_addr] ]
end

#communication_say(args, options) ⇒ Object

Raises:

  • (OptionParser::MissingArgument)


222
223
224
225
226
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
# File 'lib/dropzone/command.rb', line 222

def communication_say(args, options)
  network! :testnet3

  privkey = privkey_from args, :testnet3

  txid = args[1]  if args.length > 1
  message = args[2]  if args.length > 2

  raise OptionParser::MissingArgument, 'txid' unless txid
  raise OptionParser::MissingArgument, 'message' unless message

  comm_init = Dropzone::Communication.find txid

  raise "Invalid Session" unless comm_init && comm_init.is_init?

  session = session_for privkey, comm_init

  if !session.authenticated?
    if comm_init.sender_addr == privkey.addr
      raise "The receiver has not yet authenticated your request"
    else
      session.authenticate!

      # This allows us to re-query the the session communications, and 
      # retrive the auth_message we just created.
      # NOTE: We nonetheless fail (sometimes) with a 
      #  Dropzone::Session::Unauthenticated message as it takes a bit of time to 
      #  populate the authentication relay into the mempool:
      if Dropzone::BitcoinConnection.cache
        Dropzone::BitcoinConnection.cache.invalidate_listtransactions!

        puts "Waiting 10 seconds for authorization to propagate to the mempool..."
        sleep 10
      end
    end
  end

  comm_txid = session << message

  puts_table '%s: %s' % ['Communication', comm_txid], nil, [ 
    ['Session', txid], 
    [:sender_addr, privkey.addr], 
    [:message, message] ]
end

#communication_show(args, options) ⇒ Object

Raises:

  • (OptionParser::MissingArgument)


267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/dropzone/command.rb', line 267

def communication_show(args, options)
  network! :testnet3

  privkey = privkey_from args, :testnet3

  txid = args[1]  if args.length > 1

  raise OptionParser::MissingArgument, 'txid' unless txid

  comm_init = Dropzone::Communication.find txid

  raise "Invalid Session" unless comm_init && comm_init.is_init?

  session = session_for privkey, comm_init

  puts_table '%s: %s' % ['Communication', txid], nil,
   session.communications.collect{|comm|
    [comm.sender_addr, comm.contents_plain] }
end

#listing_find(args, options) ⇒ Object

Raises:

  • (OptionParser::MissingArgument)


287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/dropzone/command.rb', line 287

def listing_find(args, options)
  block_depth = args[0]  if args.length > 0

  raise OptionParser::MissingArgument, "block_depth" unless block_depth

  block_depth = block_depth.to_i

  raise OptionParser::InvalidArgument, "block_depth" unless block_depth >= 0

  location_attrs = [:latitude, :longitude, :radius]

  params = parameterize options, *location_attrs+[:start_at]

  via_location = location_attrs.collect{|k| params[k]}

  raise "missing one or more of: latitude, longitude, or radius."  if (
    via_location.any? && !via_location.all? )

  start_at = params[:start_at].to_i || connection.block_height

  finder_method = (via_location.all?) ? 
    [ :find_in_radius, start_at, block_depth, *via_location] :
    [ :find_creates_since_block, start_at, block_depth] 

  Dropzone::Item.send(*finder_method) do |item|
    puts_object '%s: %s' % ['Listing', item.txid], nil, LISTING_ATTRS, item
  end
end

#network!(network_name) ⇒ Object



182
183
184
185
186
187
188
# File 'lib/dropzone/command.rb', line 182

def network!(network_name)
  unless @is_spec
    Bitcoin.network = network_name
    @connection = Dropzone::BitcoinConnection.new network_name
    Dropzone::RecordBase.blockchain = @connection
  end
end

#send_value(args, options) ⇒ Object

Raises:

  • (OptionParser::MissingArgument)


316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/dropzone/command.rb', line 316

def send_value(args, options)
  dest_addr = args[1]  if args.length > 1

  raise OptionParser::MissingArgument, "dest_addr" unless dest_addr

  network! (/\A1/.match dest_addr) ? :bitcoin : :testnet3

  raise OptionParser::InvalidArgument, "dest_addr" unless Bitcoin.valid_address? dest_addr

  amnt_btc = args[2] if args.length > 2

  raise OptionParser::MissingArgument, "amnt_btc" unless amnt_btc

  amnt_btc = BigDecimal.new amnt_btc

  raise OptionParser::InvalidArgument, "amnt_btc" unless amnt_btc > 0

  amnt_satoshis = (amnt_btc * Dropzone::BitcoinConnection::SATOSHIS_IN_BTC).to_i

  privkey = privkey_from args, Bitcoin.network_name

  txid = connection.send_value privkey, dest_addr, amnt_satoshis, 
    Dropzone::MessageBase.default_tip

  puts_table '%s: %s' % ['Transaction', txid], nil, [
    ['From', privkey.addr ] ,
    ['To', dest_addr ] ,
    ['Amount (BTC)', amnt_btc.to_s('F').to_s ] 
  ]
end