Class: MixinBot::CLI

Inherits:
Thor
  • Object
show all
Includes:
CLIHelpers, CLIOutput
Defined in:
lib/mixin_bot/cli.rb,
lib/mixin_bot/cli.rb,
lib/mixin_bot/cli/api.rb,
lib/mixin_bot/cli/call.rb,
lib/mixin_bot/cli/utils.rb,
lib/mixin_bot/cli/schema_command.rb

Constant Summary collapse

UI =
::CLI::UI

Constants included from CLIOutput

MixinBot::CLIOutput::OUTPUT_FORMATS

Constants included from CLIHelpers

MixinBot::CLIHelpers::API_EXCLUDED_METHODS, MixinBot::CLIHelpers::INTERACTIVE_API_METHODS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CLIOutput

#abort_with_error, #cli_options, #current_command_name, #emit_info, #emit_list, #emit_success, #log, #output_format, #paginate_items, #print_result, #select_fields, #structured_output?, #with_command_name

Methods included from CLIHelpers

api_callable_methods, api_method_callable?, api_method_owner, grouped_api_methods, utils_callable_methods

Instance Attribute Details

#api_instanceObject (readonly)

Returns the value of attribute api_instance.



27
28
29
# File 'lib/mixin_bot/cli.rb', line 27

def api_instance
  @api_instance
end

#keystoreObject (readonly)

Returns the value of attribute keystore.



27
28
29
# File 'lib/mixin_bot/cli.rb', line 27

def keystore
  @keystore
end

Class Method Details

.exit_on_failure?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/mixin_bot/cli.rb', line 36

def self.exit_on_failure?
  true
end

Instance Method Details

#api(path) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/mixin_bot/cli/api.rb', line 27

def api(path)
  with_command_name('api') do
    setup_api_instance!
    verb = options[:method].to_s.upcase
    abort_with_error("unsupported HTTP method #{verb} (use GET or POST)", kind: :unsupported) unless %w[GET POST].include?(verb)

    path_with_query = path
    path_with_query = "#{path}?#{URI.encode_www_form(options[:params])}" if options[:params].present?

    payload = parse_api_body(options[:data])
    res = with_spinner("#{verb} #{path_with_query}") do
      case verb
      when 'GET'
        api_instance.client.get(
          path_with_query,
          access_token: options[:accesstoken]
        )
      when 'POST'
        post_via_client(path, payload, access_token: options[:accesstoken])
      end
    end

    print_result(res, data_only: options[:data_only], command: 'api')
  end
rescue MixinBot::Error => e
  abort_with_error(e.message, exception: e)
end

#authcodeObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/mixin_bot/cli/api.rb', line 59

def authcode
  with_command_name('authcode') do
    setup_api_instance!
    res = with_spinner('POST /oauth/authorize') do
      api_instance.authorize_code(
        user_id: options[:app_id],
        scope: options[:scope],
        pin: keystore['pin']
      )
    end
    print_result(res, data_only: true, command: 'authcode')
  end
rescue MixinBot::Error => e
  abort_with_error(e.message, exception: e)
end

#call(method_name, *positional) ⇒ Object



19
20
21
22
23
24
25
26
# File 'lib/mixin_bot/cli/call.rb', line 19

def call(method_name, *positional)
  with_command_name('call') do
    setup_api_instance!
    kwargs = parse_json_data(options[:data])
    result = invoke_api(method_name, kwargs:, positional:)
    print_result(result, data_only: options[:data_only], command: 'call')
  end
end

#decodetx(transaction) ⇒ Object



108
109
110
111
112
# File 'lib/mixin_bot/cli/utils.rb', line 108

def decodetx(transaction)
  with_command_name('decodetx') do
    emit_success(MixinBot.utils.decode_raw_transaction(transaction), command: 'decodetx')
  end
end

#ed25519Object



135
136
137
138
139
# File 'lib/mixin_bot/cli/utils.rb', line 135

def ed25519
  with_command_name('ed25519') do
    emit_success(MixinBot.utils.generate_ed25519_key, command: 'ed25519')
  end
end

#encrypt(pin) ⇒ Object



82
83
84
85
86
87
# File 'lib/mixin_bot/cli/utils.rb', line 82

def encrypt(pin)
  with_command_name('encrypt') do
    setup_api_instance!
    emit_success(api_instance.encrypt_pin(pin.to_s, iterator: options[:iterator]), command: 'encrypt')
  end
end

#generatetrace(hash) ⇒ Object



98
99
100
101
102
103
104
105
# File 'lib/mixin_bot/cli/utils.rb', line 98

def generatetrace(hash)
  with_command_name('generatetrace') do
    emit_success(
      MixinBot.utils.generate_trace_from_hash(hash, options[:index]),
      command: 'generatetrace'
    )
  end
end

#legacy_transfer(user_id) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/mixin_bot/cli/api.rb', line 133

def legacy_transfer(user_id)
  with_command_name('legacy-transfer') do
    setup_api_instance!
    warn_deprecated('legacy-transfer uses deprecated POST /transfers; use `transfer` (Safe API) instead')
    res = with_spinner("Legacy transfer #{options[:amount]} #{options[:asset]} to #{user_id}") do
      api_instance.create_transfer(
        keystore['pin'],
        asset_id: options[:asset],
        opponent_id: user_id,
        amount: options[:amount],
        memo: options[:memo]
      )
    end

    emit_transfer_result(res)
  end
rescue MixinBot::Error => e
  abort_with_error(e.message, exception: e)
end

#list(filter = nil) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/mixin_bot/cli/call.rb', line 32

def list(filter = nil)
  with_command_name('list') do
    methods = CLIHelpers.api_callable_methods
    if filter.present?
      needle = filter.downcase
      methods = methods.select { |m| m.to_s.downcase.include?(needle) }
    end

    items = methods.map do |name|
      { 'name' => name.to_s, 'owner' => CLIHelpers.api_method_owner(name) }
    end
    items = items.sort_by { |item| [item['owner'], item['name']] }

    page, total, limit, offset = paginate_items(items, limit: options[:limit], offset: options[:offset])
    page = select_fields(page, options[:fields])

    if structured_output?
      emit_list(items: page, total:, limit:, offset:, command: 'list')
    else
      print_pretty_list(page, total, limit, offset)
    end
  end
end

#nftmemoObject



118
119
120
121
122
123
124
125
# File 'lib/mixin_bot/cli/utils.rb', line 118

def nftmemo
  with_command_name('nftmemo') do
    emit_success(
      MixinBot.utils.nft_memo(options[:collection], options[:token], options[:hash]),
      command: 'nftmemo'
    )
  end
end

#payObject



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/mixin_bot/cli/api.rb', line 186

def pay
  with_command_name('pay') do
    setup_api_instance!
    url = api_instance.safe_pay_url(
      members: options[:members],
      threshold: options[:threshold],
      asset_id: options[:asset],
      amount: options[:amount],
      trace_id: options[:trace],
      memo: options[:memo]
    )

    emit_success({ 'url' => url }, command: 'pay')
  end
rescue MixinBot::Error => e
  abort_with_error(e.message, exception: e)
end

#rsaObject



128
129
130
131
132
# File 'lib/mixin_bot/cli/utils.rb', line 128

def rsa
  with_command_name('rsa') do
    emit_success(MixinBot.utils.generate_rsa_key, command: 'rsa')
  end
end

#saferegisterObject



169
170
171
172
173
174
175
176
177
# File 'lib/mixin_bot/cli/api.rb', line 169

def saferegister
  with_command_name('saferegister') do
    setup_api_instance!
    res = api_instance.safe_register options[:spend_key]
    print_result(res, command: 'saferegister')
  end
rescue MixinBot::Error => e
  abort_with_error(e.message, exception: e)
end

#safetransfer(user_id) ⇒ Object



161
162
163
164
# File 'lib/mixin_bot/cli/api.rb', line 161

def safetransfer(user_id)
  warn_deprecated('safetransfer is deprecated; use `transfer` instead')
  transfer(user_id)
end

#schemaObject



15
16
17
18
19
# File 'lib/mixin_bot/cli/schema_command.rb', line 15

def schema
  with_command_name('schema') do
    emit_success(CLISchema.build, command: 'schema')
  end
end

#transfer(user_id) ⇒ Object



121
122
123
124
125
126
# File 'lib/mixin_bot/cli/api.rb', line 121

def transfer(user_id)
  with_command_name('transfer') do
    setup_api_instance!
    perform_safe_transfer(user_id)
  end
end

#unique(*uuids) ⇒ Object



90
91
92
93
94
# File 'lib/mixin_bot/cli/utils.rb', line 90

def unique(*uuids)
  with_command_name('unique') do
    emit_success(MixinBot.utils.unique_uuid(*uuids), command: 'unique')
  end
end

#updatetip(pin) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/mixin_bot/cli/api.rb', line 77

def updatetip(pin)
  with_command_name('updatetip') do
    setup_api_instance!
    profile = api_instance.me
    emit_info("#{profile['full_name']}, TIP counter: #{profile['tip_counter']}")

    counter = profile['tip_counter']
    key = api_instance.prepare_tip_key counter
    emit_info("Generated key: #{key[:private_key]}")

    res = api_instance.update_tip_pin(pin.to_s, key[:public_key])

    emit_success(
      {
        'pin' => key[:private_key],
        'tip_key_base64' => res['tip_key_base64']
      },
      command: 'updatetip'
    )
  end
rescue MixinBot::Error => e
  abort_with_error(e.message, exception: e)
end

#verifypin(pin) ⇒ Object



103
104
105
106
107
108
109
110
111
# File 'lib/mixin_bot/cli/api.rb', line 103

def verifypin(pin)
  with_command_name('verifypin') do
    setup_api_instance!
    res = api_instance.verify_pin pin.to_s
    print_result(res, command: 'verifypin')
  end
rescue MixinBot::Error => e
  abort_with_error(e.message, exception: e)
end

#versionObject



30
31
32
33
34
# File 'lib/mixin_bot/cli.rb', line 30

def version
  with_command_name('version') do
    emit_success({ 'version' => MixinBot::VERSION }, command: 'version')
  end
end