keoken 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b1d20582c06a5bde5731c062f61c038b828ee20d
4
- data.tar.gz: c9f9c0e8f7226cbbc5864c8f231a144f2a12a265
2
+ SHA256:
3
+ metadata.gz: 36a966435a46a152f5aee0c5c00a304c64031c140e1b2ff5b507a6744eb3d3f6
4
+ data.tar.gz: 735d9de726b7242405f69810b4c90b0b21778e7748eb32cbcc2da37cbfd1f921
5
5
  SHA512:
6
- metadata.gz: 09840e38ffc0e34cf915bae18f7da07dfa030f0d6d59285ac0dfee6e92cff6fcd815952d1afe6cb30c07bc768abfdec704123aaf6567d713f2d0969924d22117
7
- data.tar.gz: c46649ec6d06f1716a72c1b46d77b44f517a4f4f0d1e131425cdd5563e5f72308cc84a00271fa62cbe8fb39fbc6dbcefb0bba8b04b675ae0dc9719f47fb916dc
6
+ metadata.gz: cbae48063498f66dd47fb7c2cc65a8fdb107450d1dd6895610eb60db50e86f96b10327f2b9ea8f0db05dbb0a5f34144138b14d89e7148af392a51f6489ed60a7
7
+ data.tar.gz: b74a780b42b28c763a17f68d210d8c3db8aefb2a54fc3d8959d6b6348d0c159e6351ca8d2c6eb227567db6dcd3b2d979c4ff35bd455b5db41b1de621e8f65b7c
@@ -1,2 +1,4 @@
1
1
  Metrics/LineLength:
2
2
  Max: 120
3
+ Metrics/MethodLength:
4
+ Max: 20
@@ -7,7 +7,7 @@ GIT
7
7
  PATH
8
8
  remote: .
9
9
  specs:
10
- keoken (0.3.1)
10
+ keoken (0.3.2)
11
11
  bitcoin-ruby (~> 0.0.18)
12
12
  money-tree (~> 0.9.0)
13
13
 
@@ -1,35 +1,28 @@
1
1
  module Keoken
2
2
  module Backend
3
3
  class Base
4
- attr_accessor :inputs, :bitprim_transaction, :total_inputs_amount
4
+ attr_accessor :inputs, :bitprim_transaction, :total_inputs_amount, :tokens
5
5
 
6
6
  def initialize
7
7
  @inputs = []
8
+ @tokens = []
9
+ @total_inputs_amount = 0
8
10
  @bitprim_transaction = Keoken::Bitprim::Transaction.new
9
11
  end
10
12
 
11
13
  protected
12
14
 
13
- def build_inputs(address)
14
- utxos = bitprim_transaction.utxos(address)
15
- @total_inputs_amount = 0
16
- utxos.each do |utxo|
17
- txid = utxo['txid']
18
- transaction = bitprim_transaction.tx(txid)
19
- outputs = transaction['vout'].select do |vout|
20
- addresses = vout['scriptPubKey']['addresses']
21
- addresses.any? { |vout_address| vout_address == address } if addresses
22
- end
23
- raise Keoken::Error::OutputNotFound if outputs.empty?
24
- output = outputs.first
25
- amount = output['value'].sub!(/\./, '').sub!(/^0+/, '').to_i
26
- @inputs.push(
27
- tx_id: txid,
28
- position: output['n'],
29
- input_script: output['scriptPubKey']['hex'],
30
- input_amount: amount
31
- )
32
- @total_inputs_amount += amount
15
+ def build_inputs(addresses)
16
+ addresses.each do |address|
17
+ @total_inputs_amount =
18
+ bitprim_transaction.utxos(address).inject(0) do |previous_amount, utxo|
19
+ txid = utxo['txid']
20
+ transaction = bitprim_transaction.tx(txid)
21
+ add_script_token(transaction['vout'])
22
+ output = output_for_input(txid, transaction['vout'], addresses)
23
+ @inputs.push(output)
24
+ previous_amount + output[:input_amount]
25
+ end
33
26
  end
34
27
  end
35
28
 
@@ -49,6 +42,30 @@ module Keoken
49
42
  3
50
43
  end
51
44
  end
45
+
46
+ def add_script_token(outputs)
47
+ outputs.each do |vout|
48
+ if vout['scriptPubKey']['asm'].split.first == 'OP_RETURN'
49
+ @tokens.push(Token.new(script: vout['scriptPubKey']['hex']))
50
+ end
51
+ end
52
+ end
53
+
54
+ def output_for_input(txid, outputs, addresses)
55
+ output = nil
56
+ outputs.each do |vout|
57
+ next if (vout['scriptPubKey']['addresses'].to_a & addresses).empty?
58
+ output =
59
+ {
60
+ tx_id: txid,
61
+ position: vout['n'],
62
+ input_script: vout['scriptPubKey']['hex'],
63
+ input_amount: vout['value'].sub!(/\./, '').sub!(/^0+/, '').to_i
64
+ }
65
+ end
66
+ raise Keoken::Error::OutputNotFound unless output
67
+ output
68
+ end
52
69
  end
53
70
  end
54
71
  end
@@ -41,7 +41,7 @@ module Keoken
41
41
  # @return [Keoken::Backend::BitcoinRuby::Transaction] An object instanciated with the transaction to broadcast.
42
42
  #
43
43
  def build(address, addr2, key, script, type)
44
- build_inputs(address)
44
+ build_inputs([address])
45
45
  total, fee = build_fee(type)
46
46
  case type
47
47
  when :create
@@ -16,10 +16,15 @@ module Keoken
16
16
  # @return [Keoken::Backend::Trezor::Transaction] A serialized object ready for Trezor signing.
17
17
  #
18
18
  def build_for_creation(address, path, script, xpubs = [])
19
- build_inputs(address)
19
+ build_inputs([address])
20
20
  total, fee = build_fee(:create)
21
21
  output_amount = total - fee.to_i
22
- create(@inputs, path, address, output_amount, script, xpubs)
22
+ create(inputs: @inputs,
23
+ path: path,
24
+ address: address,
25
+ output_amount: output_amount,
26
+ script: script,
27
+ xpubs: xpubs)
23
28
  end
24
29
 
25
30
  # Create the transaction to broadcast in order to send amount between tokens.
@@ -33,26 +38,57 @@ module Keoken
33
38
  # @return [Keoken::Backend::Trezor::Transaction] A serialized object ready for Trezor signing.
34
39
  #
35
40
  def build_for_send_amount(address, address_dest, path, script, xpubs = [])
36
- build_inputs(address)
41
+ build_inputs([address])
37
42
  total, fee = build_fee(:send)
38
43
  output_amount = total - (fee.to_i * 2)
39
44
  output_amount_to_addr2 = fee.to_i
40
- send(@inputs, path, output_amount, address, output_amount_to_addr2, address_dest, script, xpubs)
45
+ send(inputs: @inputs,
46
+ path: path,
47
+ output_amount: output_amount,
48
+ address: address,
49
+ output_amount_to_addr2: output_amount_to_addr2,
50
+ addr2: address_dest,
51
+ script: script,
52
+ xpubs: xpubs)
53
+ end
54
+
55
+ # Create the transaction to broadcast in order to empty the wallet.
56
+ #
57
+ # @param addresses [Array] Addresses that will contain the token and will be emptied.
58
+ # @param address_dest [String] Address to receive the tokens.
59
+ # @param path [Array] Address derivation path.
60
+ # @param xpubs [Array] The xpubs corresponding to the multisig address.
61
+ #
62
+ # @return [Keoken::Backend::Trezor::Transaction] A serialized object ready for Trezor signing.
63
+ #
64
+ def build_for_empty_wallet(addresses, address_dest, path, xpubs = [])
65
+ build_inputs(addresses)
66
+ total, fee = build_fee(:send)
67
+ raise Keoken::Error::NoToken if @tokens.empty?
68
+
69
+ send(inputs: @inputs,
70
+ path: path,
71
+ output_amount: total - (fee.to_i * 2),
72
+ address: nil,
73
+ output_amount_to_addr2: fee.to_i,
74
+ addr2: address_dest,
75
+ script: token_script_for_inputs,
76
+ xpubs: xpubs)
41
77
  end
42
78
 
43
79
  private
44
80
 
45
- def create(inputs, path, address, output_amount, script, xpubs)
81
+ def create(options = {})
46
82
  {
47
- inputs: build_trezor_inputs(inputs, path, address, xpubs),
83
+ inputs: build_trezor_inputs(options[:inputs], options[:path], options[:address], options[:xpubs]),
48
84
  outputs: [
49
85
  {
50
- address: Cashaddress.from_legacy(address),
51
- amount: output_amount.to_s,
86
+ address: Cashaddress.from_legacy(options[:address]),
87
+ amount: options[:output_amount].to_s,
52
88
  script_type: 'PAYTOADDRESS'
53
89
  },
54
90
  {
55
- op_return_data: script,
91
+ op_return_data: options[:script],
56
92
  amount: '0',
57
93
  script_type: 'PAYTOOPRETURN'
58
94
  }
@@ -60,26 +96,34 @@ module Keoken
60
96
  }
61
97
  end
62
98
 
63
- def send(inputs, path, output_amount, address, output_amount_to_addr2, addr2, script, xpubs)
99
+ def send(options = {})
100
+ first_output = if options[:address]
101
+ [
102
+ {
103
+ address: Cashaddress.from_legacy(options[:address]),
104
+ amount: options[:output_amount].to_s,
105
+ script_type: 'PAYTOADDRESS'
106
+ }
107
+ ]
108
+ else
109
+ []
110
+ end
64
111
  {
65
- inputs: build_trezor_inputs(inputs, path, address, xpubs),
66
- outputs: [
67
- {
68
- address: Cashaddress.from_legacy(address),
69
- amount: output_amount.to_s,
70
- script_type: 'PAYTOADDRESS'
71
- },
72
- {
73
- address: Cashaddress.from_legacy(addr2),
74
- amount: output_amount_to_addr2.to_s,
75
- script_type: 'PAYTOADDRESS'
76
- },
77
- {
78
- op_return_data: script,
79
- amount: '0',
80
- script_type: 'PAYTOOPRETURN'
81
- }
82
- ]
112
+ inputs: build_trezor_inputs(options[:inputs], options[:path], options[:address], options[:xpubs]),
113
+ outputs: first_output.concat(
114
+ [
115
+ {
116
+ address: Cashaddress.from_legacy(options[:addr2]),
117
+ amount: options[:output_amount_to_addr2].to_s,
118
+ script_type: 'PAYTOADDRESS'
119
+ },
120
+ {
121
+ op_return_data: options[:script],
122
+ amount: '0',
123
+ script_type: 'PAYTOOPRETURN'
124
+ }
125
+ ]
126
+ )
83
127
  }
84
128
  end
85
129
 
@@ -124,7 +168,13 @@ module Keoken
124
168
  }
125
169
  end
126
170
  end
171
+
172
+ def token_script_for_inputs
173
+ token = Token.new(id: @tokens.first.id)
174
+ token.send_amount(@tokens.map(&:amount).inject(:+))
175
+ token.hex
176
+ end
127
177
  end
128
178
  end
129
179
  end
130
- end
180
+ end
@@ -0,0 +1,9 @@
1
+ module Keoken
2
+ module Error
3
+ class NoToken < StandardError
4
+ def initialize(msg = 'Transaction needs at least one token')
5
+ super
6
+ end
7
+ end
8
+ end
9
+ end
@@ -7,4 +7,3 @@ module Keoken
7
7
  end
8
8
  end
9
9
  end
10
-
@@ -1,6 +1,6 @@
1
1
  module Keoken
2
2
  class Token < Parser
3
- attr_accessor :data_script, :id
3
+ attr_accessor :data_script, :id, :amount
4
4
 
5
5
  # Creates a new token object.
6
6
  #
@@ -43,7 +43,6 @@ module Keoken
43
43
  #
44
44
  def send_amount(amount)
45
45
  raise Keoken::Error::IdNotFound unless @id
46
- asset_length = Keoken::ASSET_ID_SIZE - @id.to_s.length
47
46
  @data_script =
48
47
  [
49
48
  Keoken::VERSION_NODE,
@@ -1,3 +1,3 @@
1
1
  module Keoken
2
- VERSION = '0.3.2'.freeze
2
+ VERSION = '0.4.0'.freeze
3
3
  end
@@ -323,6 +323,92 @@ describe Keoken do
323
323
  )
324
324
  )
325
325
  end
326
+
327
+ it 'empty the wallet' do
328
+ mock_requests
329
+ allow(ENV).to receive(:[]).with('KEOKEN_NODE').and_return('PRODUCTION')
330
+ @transaction_token = Keoken::Backend::Trezor::Transaction.new
331
+
332
+ expect(
333
+ @transaction_token.build_for_empty_wallet(
334
+ ['17wrMVCa9EJUVVEC3c5CZZanjT1NtWU2mX',
335
+ '32tM1kKxnTzcJugmGsavg5MnsJiNZfUUzQ'],
336
+ '32tM1kKxnTzcJugmGsavg5MnsJiNZfUUzQ',
337
+ [44, 145, 0, 0, 0],
338
+ ['ypub6WrVGzkKFeNTTppAVe2KkY3yiohKNvFDZm7qAFKBAu8ozm2DYRmwoXwpQUAaEbLkCJmdGaYBLxBUbJcfeLZcwXEtF9neUCDXuWtVyFDApi6',
339
+ 'ypub6WtFU3UPzgvu1AJzw9Quw6TgNp7FM5ro2AZwcwmkgP4HvdurTiGRSDYKV4YaofGny96xFykeNxJGgt8SiNwhFnBbdmwyiiLVRxoKWTeQnuB']
340
+ )
341
+ ).to(
342
+ eq(
343
+ {:inputs=>
344
+ [{:address_n=>[44, 145, 0, 0, 0],
345
+ :prev_index=>1,
346
+ :prev_hash=>
347
+ "448a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da",
348
+ :amount=>"8985999",
349
+ :script_type=>"SPENDMULTISIG",
350
+ :multisig=>
351
+ {:signatures=>["", "", ""],
352
+ :m=>2,
353
+ :pubkeys=>
354
+ [{:address_n=>[44, 145, 0, 0, 0],
355
+ :node=>
356
+ {:chain_code=>
357
+ "7bd6545bf255444ba4cf93b893e56deacf59e0b8e065d44673e9afff4e3655c6",
358
+ :depth=>0,
359
+ :child_num=>0,
360
+ :fingerprint=>0,
361
+ :public_key=>
362
+ "03db551b0f0962d4cbbf15b6d81dd7dc0e82868867182ec15b1e5e28b90fac97c4"}},
363
+ {:address_n=>[44, 145, 0, 0, 0],
364
+ :node=>
365
+ {:chain_code=>
366
+ "4199329ed001a33fb58fd75bac23c80c0d38cedc009bac8f89c89df91c35bc8e",
367
+ :depth=>0,
368
+ :child_num=>0,
369
+ :fingerprint=>0,
370
+ :public_key=>
371
+ "02408f31733a184b6d0dd52a0800bf1a6b02102b9bfcc9c158b508365869c8c73d"}}]}},
372
+ {:address_n=>[44, 145, 0, 0, 0],
373
+ :prev_index=>1,
374
+ :prev_hash=>
375
+ "348a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da",
376
+ :amount=>"8985999",
377
+ :script_type=>"SPENDMULTISIG",
378
+ :multisig=>
379
+ {:signatures=>["", "", ""],
380
+ :m=>2,
381
+ :pubkeys=>
382
+ [{:address_n=>[44, 145, 0, 0, 0],
383
+ :node=>
384
+ {:chain_code=>
385
+ "7bd6545bf255444ba4cf93b893e56deacf59e0b8e065d44673e9afff4e3655c6",
386
+ :depth=>0,
387
+ :child_num=>0,
388
+ :fingerprint=>0,
389
+ :public_key=>
390
+ "03db551b0f0962d4cbbf15b6d81dd7dc0e82868867182ec15b1e5e28b90fac97c4"}},
391
+ {:address_n=>[44, 145, 0, 0, 0],
392
+ :node=>
393
+ {:chain_code=>
394
+ "4199329ed001a33fb58fd75bac23c80c0d38cedc009bac8f89c89df91c35bc8e",
395
+ :depth=>0,
396
+ :child_num=>0,
397
+ :fingerprint=>0,
398
+ :public_key=>
399
+ "02408f31733a184b6d0dd52a0800bf1a6b02102b9bfcc9c158b508365869c8c73d"}}]}}],
400
+ :outputs=>
401
+ [{:address=>"bitcoincash:pqx3eghuvc7kmc4qkwg0qwfjqyedh3wg8qkwanr9pd",
402
+ :amount=>"124874",
403
+ :script_type=>"PAYTOADDRESS"},
404
+ {:op_return_data=>"6a0400004b5010000000010000001100000000000000c8",
405
+ :amount=>"0",
406
+ :script_type=>"PAYTOOPRETURN"}
407
+ ]
408
+ }
409
+ )
410
+ )
411
+ end
326
412
  end
327
413
  end
328
414
 
@@ -347,6 +433,16 @@ def mock_requests
347
433
  }).
348
434
  to_return(:status => 200, :body => body_request, :headers => {})
349
435
 
436
+ body_request = "[{\"address\":\"32tM1kKxnTzcJugmGsavg5MnsJiNZfUUzQ\",\"txid\":\"348a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da\",\"vout\":1,\"scriptPubKey\":\"56a9147bb97684cc43e2f8ea0ed1d50dddce3ebf80063888ac\",\"amount\":0.07985999,\"satoshis\":8985999,\"height\":1282589,\"confirmations\":1356}]"
437
+ stub_request(:get, "https://bch.blockdozer.com/insight-api/addr/32tM1kKxnTzcJugmGsavg5MnsJiNZfUUzQ/utxo").
438
+ with(:headers => {
439
+ "Accept" => "*/*",
440
+ "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
441
+ "Host" => "bch.blockdozer.com",
442
+ "User-Agent" => "Ruby",
443
+ }).
444
+ to_return(:status => 200, :body => body_request, :headers => {})
445
+
350
446
  body_request = "{\"txid\":\"448a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da\",\"version\":1,\"locktime\":0,\"vin\":[{\"txid\":\"48c158109ca432e109971ca61e4bccbdc2b51053c02f8183f5ca7f60a55df4d0\",\"vout\":0,\"sequence\":4294967295,\"n\":0,\"scriptSig\":{\"hex\":\"483045022100a64b8798d783d1fb7ea306cfdc2aa09cae972cbfed3fcd92a4501e54035f869b022004da604a3dd52cecd8b89200065b96bdf7c3684e6ec983ed3dceed1bf8d3a480412102bd2af43b8c683f7bb5c5dc4aad7c5a2961252676d85c2547de9767e1a6252455\",\"asm\":\"3045022100a64b8798d783d1fb7ea306cfdc2aa09cae972cbfed3fcd92a4501e54035f869b022004da604a3dd52cecd8b89200065b96bdf7c3684e6ec983ed3dceed1bf8d3a480[ALL|FORKID] 02bd2af43b8c683f7bb5c5dc4aad7c5a2961252676d85c2547de9767e1a6252455\"},\"addr\":\"mro9aqn4xCzXVS7jRFFuzT2ERKonvPdSDA\",\"valueSat\":9991999,\"value\":0.09991999,\"doubleSpentTxID\":null}],\"vout\":[{\"value\":\"0.01000000\",\"n\":0,\"scriptPubKey\":{\"hex\":\"76a9141a53f3efae04708754ca1c5382085249c0ff597d88ac\",\"asm\":\"OP_DUP OP_HASH160 1a53f3efae04708754ca1c5382085249c0ff597d OP_EQUALVERIFY OP_CHECKSIG\",\"addresses\":[\"mhvASBxPioT6eLPtSA5u1SNoT49RsME3BJ\"],\"type\":\"pubkeyhash\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null},{\"value\":\"0.08985999\",\"n\":1,\"scriptPubKey\":{\"hex\":\"76a9147bb97684cc43e2f8ea0ed1d50dddce3ebf80063888ac\",\"asm\":\"OP_DUP OP_HASH160 7bb97684cc43e2f8ea0ed1d50dddce3ebf800638 OP_EQUALVERIFY OP_CHECKSIG\",\"addresses\":[\"mro9aqn4xCzXVS7jRFFuzT2ERKonvPdSDA\"],\"type\":\"pubkeyhash\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null},{\"value\":\"0.00000000\",\"n\":2,\"scriptPubKey\":{\"hex\":\"6a0400004b501000000001000000170000000000000064\",\"asm\":\"OP_RETURN 1347092480 00000001000000170000000000000064\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null}],\"blockhash\":\"0000000000009505e41c238f88f5c9b5591e92f7eb68545962a5dd71cd075525\",\"blockheight\":1282589,\"confirmations\":1356,\"time\":1548360176,\"blocktime\":1548360176,\"valueOut\":0.09985999,\"size\":258,\"valueIn\":0.09991999,\"fees\":0.00006}"
351
447
  stub_request(:get, "https://tbch.blockdozer.com/insight-api/tx/448a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da").
352
448
  with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'tbch.blockdozer.com', 'User-Agent'=>'Ruby'}).
@@ -357,6 +453,11 @@ def mock_requests
357
453
  with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'bch.blockdozer.com', 'User-Agent'=>'Ruby'}).
358
454
  to_return(:status => 200, :body => body_request, :headers => {})
359
455
 
456
+ body_request = "{\"txid\":\"348a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da\",\"version\":1,\"locktime\":0,\"vin\":[{\"txid\":\"58c158109ca432e109971ca61e4bccbdc2b51053c02f8183f5ca7f60a55df4d0\",\"vout\":0,\"sequence\":12345678,\"n\":0,\"scriptSig\":{\"hex\":\"483045022100a64b8798d783d1fb7ea306cfdc2aa09cae972cbfed3fcd92a4501e54035f869b022004da604a3dd52cecd8b89200065b96bdf7c3684e6ec983ed3dceed1bf8d3a480412102bd2af43b8c683f7bb5c5dc4aad7c5a2961252676d85c2547de9767e1a6252455\",\"asm\":\"3045022100a64b8798d783d1fb7ea306cfdc2aa09cae972cbfed3fcd92a4501e54035f869b022004da604a3dd52cecd8b89200065b96bdf7c3684e6ec983ed3dceed1bf8d3a480[ALL|FORKID] 02bd2af43b8c683f7bb5c5dc4aad7c5a2961252676d85c2547de9767e1a6252455\"},\"addr\":\"17wrMVCa9EJUVVEC3c5CZZanjT1NtWU2mX\",\"valueSat\":9991999,\"value\":0.09991999,\"doubleSpentTxID\":null}],\"vout\":[{\"value\":\"0.01000000\",\"n\":0,\"scriptPubKey\":{\"hex\":\"76a9141a53f3efae04708754ca1c5382085249c0ff597d88ac\",\"asm\":\"OP_DUP OP_HASH160 1a53f3efae04708754ca1c5382085249c0ff597d OP_EQUALVERIFY OP_CHECKSIG\",\"addresses\":[\"mhvASBxPioT6eLPtSA5u1SNoT49RsME3BJ\"],\"type\":\"pubkeyhash\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null},{\"value\":\"0.08985999\",\"n\":1,\"scriptPubKey\":{\"hex\":\"76a9147bb97684cc43e2f8ea0ed1d50dddce3ebf80063888ac\",\"asm\":\"OP_DUP OP_HASH160 7bb97684cc43e2f8ea0ed1d50dddce3ebf800638 OP_EQUALVERIFY OP_CHECKSIG\",\"addresses\":[\"17wrMVCa9EJUVVEC3c5CZZanjT1NtWU2mX\"],\"type\":\"pubkeyhash\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null},{\"value\":\"0.00000000\",\"n\":2,\"scriptPubKey\":{\"hex\":\"6a0400004b501000000001000000170000000000000064\",\"asm\":\"OP_RETURN 1347092480 00000001000000170000000000000064\"},\"spentTxId\":null,\"spentIndex\":null,\"spentHeight\":null}],\"blockhash\":\"0000000000009505e41c238f88f5c9b5591e92f7eb68545962a5dd71cd075525\",\"blockheight\":1282589,\"confirmations\":1356,\"time\":1548360176,\"blocktime\":1548360176,\"valueOut\":0.09985999,\"size\":258,\"valueIn\":0.09991999,\"fees\":0.00006}"
457
+ stub_request(:get, "https://bch.blockdozer.com/insight-api/tx/348a9356f6317eeaa9581f9a39d41431ac74aa2b73438c01e1d522543d14e8da").
458
+ with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'bch.blockdozer.com', 'User-Agent'=>'Ruby'}).
459
+ to_return(:status => 200, :body => body_request, :headers => {})
460
+
360
461
  stub_request(:get, "https://tbch.blockdozer.com/insight-api/utils/estimatefee").
361
462
  with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'tbch.blockdozer.com', 'User-Agent'=>'Ruby'}).
362
463
  to_return(:status => 200, :body => "{\"2\":0.0001021}", :headers => {})
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keoken
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bitex
@@ -186,6 +186,7 @@ files:
186
186
  - lib/keoken/errors/data_not_parsed.rb
187
187
  - lib/keoken/errors/id_not_found.rb
188
188
  - lib/keoken/errors/name_not_found.rb
189
+ - lib/keoken/errors/no_token.rb
189
190
  - lib/keoken/errors/output_not_found.rb
190
191
  - lib/keoken/extensions/bitcoin/script.rb
191
192
  - lib/keoken/parser.rb
@@ -213,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
213
214
  version: '0'
214
215
  requirements: []
215
216
  rubyforge_project:
216
- rubygems_version: 2.4.8
217
+ rubygems_version: 2.7.7
217
218
  signing_key:
218
219
  specification_version: 4
219
220
  summary: Keoken protocol implemented in Ruby