mixin_bot 0.0.1.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MixinBot
4
+ class CLI < Thor
5
+ desc 'read_me', 'fetch mixin bot profile'
6
+ option :config, required: true, aliases: '-c'
7
+ def read_me
8
+ api_method(:read_me)
9
+ end
10
+
11
+ desc 'read_assets', 'fetch mixin bot assets'
12
+ option :config, required: true, aliases: '-c'
13
+ def read_assets
14
+ api_method(:read_assets)
15
+ end
16
+
17
+ desc 'cal_assets_as_usd', 'fetch mixin bot assets'
18
+ option :config, required: true, aliases: '-c'
19
+ def cal_assets_as_usd
20
+ assets, success = read_assets
21
+ return unless success
22
+
23
+ sum = assets['data'].map(
24
+ &lambda { |asset|
25
+ asset['balance'].to_f * asset['price_usd'].to_f
26
+ }
27
+ ).sum
28
+ UI::Frame.open('USD') do
29
+ log sum
30
+ end
31
+ end
32
+
33
+ desc 'read_asset', 'fetch specific asset of mixin bot'
34
+ option :config, required: true, aliases: '-c'
35
+ option :assetid, required: true, aliases: '-s'
36
+ def read_asset
37
+ api_method(:read_asset, options[:assetid])
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MixinBot
4
+ class CLI < Thor
5
+ desc 'get_all_multisigs', 'fetch all utxos'
6
+ option :config, required: true, aliases: '-c'
7
+ def all_multisigs
8
+ api_method(:get_all_multisigs)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+
5
+ module MixinBot
6
+ class NodeCLI < Thor
7
+ # https://github.com/Shopify/cli-ui
8
+ UI = ::CLI::UI
9
+ UI::StdoutRouter.enable
10
+
11
+ desc 'listallnodes', 'List all mixin nodes'
12
+ def listallnodes
13
+ return unless ensure_mixin_command_exist
14
+
15
+ o, e, _s = Open3.capture3('mixin -n 35.188.235.212:8239 listallnodes')
16
+ log e unless e.empty?
17
+ log o
18
+ end
19
+
20
+ desc 'mint', 'Mint from mint distributions'
21
+ option :node, required: true, aliases: '-n', desc: 'node RPC address'
22
+ option :batch, type: :numeric, required: true, aliases: '-b', desc: 'mint batch'
23
+ option :view, type: :string, required: true, aliases: '-v', desc: 'view key'
24
+ option :address, type: :string, required: true, aliases: '-d', desc: 'address'
25
+ def mint
26
+ c = (Date.today - Date.new(2019, 2, 28)).to_i + 1
27
+ distributions = []
28
+ UI::Spinner.spin('Listing mint distributions') do |spinner|
29
+ o, _e, _s = Open3.capture3(
30
+ 'mixin',
31
+ '-n',
32
+ options[:node],
33
+ 'listmintdistributions',
34
+ '-c',
35
+ c.to_s
36
+ )
37
+ distributions = eval o
38
+ spinner.update_title "#{distributions.size} mint distributions listed"
39
+ end
40
+
41
+ tx = ''
42
+ UI::Spinner.spin('Finding transaction') do |spinner|
43
+ index = distributions.index(&->(d) { d[:batch] == options[:batch] })
44
+ tx = distributions[index][:transaction]
45
+ spinner.update_title "Transaction hash found: #{tx}"
46
+ end
47
+
48
+ UI::Spinner.spin('Fetching transaction') do |spinner|
49
+ o, _e, _s = Open3.capture3(
50
+ 'mixin',
51
+ '-n',
52
+ options[:node],
53
+ 'gettransaction',
54
+ '-x',
55
+ tx
56
+ )
57
+ tx = eval o
58
+ spinner.update_title "#{tx[:outputs].size} transaction outputs found"
59
+ end
60
+
61
+ tx[:outputs].each_with_index do |output, index|
62
+ address = ''
63
+ UI::Spinner.spin("Checking output index: #{index}") do |spinner|
64
+ o, _e, _s = Open3.capture3(
65
+ 'mixin',
66
+ 'decryptghostkey',
67
+ '--key',
68
+ output[:keys].first,
69
+ '--mask',
70
+ output[:mask],
71
+ '--view',
72
+ options[:view]
73
+ )
74
+ address = o.chomp
75
+ spinner.update_title "Index #{index} Address: #{address}"
76
+ end
77
+ log "Found Utxo: #{index}" if address == options[:address]
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def ensure_mixin_command_exist
84
+ return true if command?('mixin')
85
+
86
+ log UI.fmt '{{x}} `mixin` command is not valid!'
87
+ log UI.fmt 'Please install mixin software and provide a executable `mixin` command'
88
+ end
89
+
90
+ def command?(name)
91
+ `which #{name}`
92
+ $CHILD_STATUS.success?
93
+ end
94
+
95
+ def log(obj)
96
+ if options[:pretty]
97
+ if obj.is_a? String
98
+ puts obj
99
+ else
100
+ ap obj
101
+ end
102
+ else
103
+ puts obj.inspect
104
+ end
105
+ end
106
+ end
107
+ end
@@ -1,7 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MixinBot
2
4
  class Client
3
- SERVER_SCHEME = 'https'.freeze
4
- SERVER_HOST = 'api.mixin.one'.freeze
5
+ SERVER_SCHEME = 'https'
6
+
7
+ attr_reader :host
8
+
9
+ def initialize(host = 'api.mixin.one')
10
+ @host = host
11
+ end
5
12
 
6
13
  def get(path, options = {})
7
14
  request(:get, path, options)
@@ -14,30 +21,24 @@ module MixinBot
14
21
  private
15
22
 
16
23
  def request(verb, path, options = {})
17
- uri = uri_for(path)
18
- options = options.with_indifferent_access
24
+ uri = uri_for path
19
25
 
20
- options['headers'] ||= {}
21
- if options['headers']['Content-Type'].blank?
22
- options['headers']['Content-Type'] = 'application/json'
23
- end
26
+ options[:headers] ||= {}
27
+ options[:headers]['Content-Type'] ||= 'application/json'
24
28
 
25
29
  begin
26
30
  response = HTTP.timeout(connect: 5, write: 5, read: 5).request(verb, uri, options)
27
- rescue HTTP::Error => ex
28
- Rails.logger.error format('%s (%s):', ex.class.name, ex.message)
29
- Rails.logger.error ex.backtrace.join("\n")
30
- raise Errors::HttpError, ex.message
31
+ rescue HTTP::Error => e
32
+ raise Errors::HttpError, e.message
31
33
  end
32
34
 
33
- unless response.status.success?
34
- raise Errors::APIError.new(nil, response.to_s)
35
- end
35
+ raise Errors::APIError.new(nil, response.to_s) unless response.status.success?
36
36
 
37
37
  parse_response(response) do |parse_as, result|
38
38
  case parse_as
39
39
  when :json
40
- break result if result[:errcode].blank? || result[:errcode].zero?
40
+ break result if result[:errcode].nil? || result[:errcode].zero?
41
+
41
42
  raise Errors::APIError.new(result[:errcode], result[:errmsg])
42
43
  else
43
44
  result
@@ -48,7 +49,7 @@ module MixinBot
48
49
  def uri_for(path)
49
50
  uri_options = {
50
51
  scheme: SERVER_SCHEME,
51
- host: SERVER_HOST,
52
+ host: host,
52
53
  path: path
53
54
  }
54
55
  Addressable::URI.new(uri_options)
@@ -57,35 +58,33 @@ module MixinBot
57
58
  def parse_response(response)
58
59
  content_type = response.headers[:content_type]
59
60
  parse_as = {
60
- %r{^application\/json} => :json,
61
- %r{^image\/.*} => :file,
62
- %r{^text\/html} => :xml,
63
- %r{^text\/plain} => :plain
61
+ %r{^application/json} => :json,
62
+ %r{^image/.*} => :file,
63
+ %r{^text/html} => :xml,
64
+ %r{^text/plain} => :plain
64
65
  }.each_with_object([]) { |match, memo| memo << match[1] if content_type =~ match[0] }.first || :plain
65
66
 
66
67
  if parse_as == :plain
67
- result = ActiveSupport::JSON.decode(response.body.to_s).with_indifferent_access rescue nil
68
- if result
69
- return yield(:json, result)
70
- else
71
- return yield(:plain, response.body)
72
- end
68
+ result = JSON.parse(response&.body&.to_s)
69
+ result && yield(:json, result)
70
+
71
+ yield(:plain, response.body)
73
72
  end
74
73
 
75
74
  case parse_as
76
75
  when :json
77
- result = ActiveSupport::JSON.decode(response.body.to_s).with_indifferent_access
76
+ result = JSON.parse(response.body.to_s)
78
77
  when :file
79
- if response.headers[:content_type] =~ %r{^image\/.*}
80
- extension =
81
- case response.headers['content-type']
82
- when 'image/gif' then '.gif'
83
- when 'image/jpeg' then '.jpg'
84
- when 'image/png' then '.png'
85
- end
86
- else
87
- extension = ''
88
- end
78
+ extension =
79
+ if response.headers[:content_type] =~ %r{^image/.*}
80
+ {
81
+ 'image/gif': '.gif',
82
+ 'image/jpeg': '.jpg',
83
+ 'image/png': '.png'
84
+ }[response.headers['content-type']]
85
+ else
86
+ ''
87
+ end
89
88
 
90
89
  begin
91
90
  file = Tempfile.new(['mixin-file-', extension])
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MixinBot
2
4
  module Errors
3
5
  # 通用异常
@@ -14,7 +16,7 @@ module MixinBot
14
16
  @errcode = errcode
15
17
  @errmsg = errmsg
16
18
 
17
- super(format('[%s]: %s', @errcode, @errmsg))
19
+ super(format('[%<errcode>s]: %<errmsg>s', errcode: @errcode, errmsg: @errmsg))
18
20
  end
19
21
  end
20
22
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MixinBot
2
- VERSION = '0.0.1.4'.freeze
4
+ VERSION = '0.3.0'
3
5
  end
metadata CHANGED
@@ -1,104 +1,227 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixin_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - an-lee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-16 00:00:00.000000000 Z
11
+ date: 2020-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: http
14
+ name: awesome_print
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bcrypt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cli-ui
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
25
53
  - !ruby/object:Gem::Version
26
- version: '0'
54
+ version: '1.3'
27
55
  - !ruby/object:Gem::Dependency
28
- name: jwt
56
+ name: faye-websocket
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
59
  - - ">="
32
60
  - !ruby/object:Gem::Version
33
- version: '0'
61
+ version: '0.11'
34
62
  type: :runtime
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
66
  - - ">="
39
67
  - !ruby/object:Gem::Version
40
- version: '0'
68
+ version: '0.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: http
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.1'
41
83
  - !ruby/object:Gem::Dependency
42
84
  name: jose
43
85
  requirement: !ruby/object:Gem::Requirement
44
86
  requirements:
45
- - - ">="
87
+ - - "~>"
46
88
  - !ruby/object:Gem::Version
47
- version: '0'
89
+ version: '1.1'
48
90
  type: :runtime
49
91
  prerelease: false
50
92
  version_requirements: !ruby/object:Gem::Requirement
51
93
  requirements:
52
- - - ">="
94
+ - - "~>"
53
95
  - !ruby/object:Gem::Version
54
- version: '0'
96
+ version: '1.1'
55
97
  - !ruby/object:Gem::Dependency
56
- name: bcrypt
98
+ name: msgpack
57
99
  requirement: !ruby/object:Gem::Requirement
58
100
  requirements:
59
- - - ">="
101
+ - - "~>"
60
102
  - !ruby/object:Gem::Version
61
- version: '0'
103
+ version: '1.3'
62
104
  type: :runtime
63
105
  prerelease: false
64
106
  version_requirements: !ruby/object:Gem::Requirement
65
107
  requirements:
66
- - - ">="
108
+ - - "~>"
67
109
  - !ruby/object:Gem::Version
68
- version: '0'
110
+ version: '1.3'
69
111
  - !ruby/object:Gem::Dependency
70
- name: activesupport
112
+ name: thor
71
113
  requirement: !ruby/object:Gem::Requirement
72
114
  requirements:
73
- - - ">="
115
+ - - "~>"
74
116
  - !ruby/object:Gem::Version
75
- version: '0'
117
+ version: '1.0'
76
118
  type: :runtime
77
119
  prerelease: false
78
120
  version_requirements: !ruby/object:Gem::Requirement
79
121
  requirements:
80
- - - ">="
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rake
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '13.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '13.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rspec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '3.8'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '3.8'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubocop
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '0.72'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '0.72'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop-rspec
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1.33'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '1.33'
181
+ - !ruby/object:Gem::Dependency
182
+ name: simplecov
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
81
186
  - !ruby/object:Gem::Version
82
- version: '0'
187
+ version: 0.18.2
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 0.18.2
83
195
  description: An API wrapper for Mixin Nexwork
84
196
  email:
85
197
  - an.lee.work@gmail.com
86
- executables: []
198
+ executables:
199
+ - mixinbot
87
200
  extensions: []
88
201
  extra_rdoc_files: []
89
202
  files:
90
203
  - MIT-LICENSE
204
+ - bin/mixinbot
91
205
  - lib/mixin_bot.rb
92
206
  - lib/mixin_bot/api.rb
207
+ - lib/mixin_bot/api/app.rb
208
+ - lib/mixin_bot/api/attachment.rb
93
209
  - lib/mixin_bot/api/auth.rb
210
+ - lib/mixin_bot/api/blaze.rb
94
211
  - lib/mixin_bot/api/conversation.rb
95
212
  - lib/mixin_bot/api/me.rb
96
213
  - lib/mixin_bot/api/message.rb
214
+ - lib/mixin_bot/api/multisig.rb
97
215
  - lib/mixin_bot/api/payment.rb
98
216
  - lib/mixin_bot/api/pin.rb
99
217
  - lib/mixin_bot/api/snapshot.rb
100
218
  - lib/mixin_bot/api/transfer.rb
101
219
  - lib/mixin_bot/api/user.rb
220
+ - lib/mixin_bot/api/withdraw.rb
221
+ - lib/mixin_bot/cli.rb
222
+ - lib/mixin_bot/cli/me.rb
223
+ - lib/mixin_bot/cli/multisig.rb
224
+ - lib/mixin_bot/cli/node.rb
102
225
  - lib/mixin_bot/client.rb
103
226
  - lib/mixin_bot/errors.rb
104
227
  - lib/mixin_bot/version.rb
@@ -114,14 +237,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
114
237
  requirements:
115
238
  - - ">="
116
239
  - !ruby/object:Gem::Version
117
- version: '0'
240
+ version: 2.6.0
118
241
  required_rubygems_version: !ruby/object:Gem::Requirement
119
242
  requirements:
120
243
  - - ">="
121
244
  - !ruby/object:Gem::Version
122
245
  version: '0'
123
246
  requirements: []
124
- rubygems_version: 3.0.2
247
+ rubygems_version: 3.0.3
125
248
  signing_key:
126
249
  specification_version: 4
127
250
  summary: An API wrapper for Mixin Nexwork