From 128b2897234863acf0b2858c29e149ff0e08a0bd Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Thu, 15 Oct 2020 17:45:21 +0200 Subject: [PATCH 1/3] Fix payments param so it is possible to send multi-tx to the same address --- lib/cardano_wallet/byron.rb | 8 +++---- lib/cardano_wallet/shelley.rb | 8 +++---- lib/cardano_wallet/utils.rb | 23 ++++++++++++++----- spec/byron_spec.rb | 28 +++++++++++++---------- spec/shelley_spec.rb | 43 ++++++++++++++++++++--------------- 5 files changed, 66 insertions(+), 44 deletions(-) diff --git a/lib/cardano_wallet/byron.rb b/lib/cardano_wallet/byron.rb index 6cb9dba..417783f 100644 --- a/lib/cardano_wallet/byron.rb +++ b/lib/cardano_wallet/byron.rb @@ -181,7 +181,7 @@ def initialize opt # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/byronSelectCoins # # @example - # random(wid, {address1: 123, address2: 456}) + # random(wid, [{addr1: 1000000}, {addr2: 1000000}]) def random(wid, payments) payments_formatted = Utils.format_payments(payments) self.class.post("/byron-wallets/#{wid}/coin-selections/random", @@ -217,10 +217,10 @@ def list(wid, q = {}) # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postByronTransaction # @param wid [String] source wallet id # @param passphrase [String] source wallet's passphrase - # @param payments [Hash] addres, amount pair + # @param payments [Array of Hashes] addres, amount pair # # @example - # create(wid, passphrase, {addr1: 1000000}) + # create(wid, passphrase, [{addr1: 1000000}, {addr2: 1000000}]) def create(wid, passphrase, payments) payments_formatted = Utils.format_payments(payments) self.class.post("/byron-wallets/#{wid}/transactions", @@ -234,7 +234,7 @@ def create(wid, passphrase, payments) # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postTransactionFee # # @example - # payment_fees(wid, {addr1: 1000000}) + # payment_fees(wid, [{addr1: 1000000}, {addr2: 1000000}]) def payment_fees(wid, payments) payments_formatted = Utils.format_payments(payments) self.class.post("/byron-wallets/#{wid}/payment-fees", diff --git a/lib/cardano_wallet/shelley.rb b/lib/cardano_wallet/shelley.rb index 49f1f66..6d2df46 100644 --- a/lib/cardano_wallet/shelley.rb +++ b/lib/cardano_wallet/shelley.rb @@ -158,7 +158,7 @@ def initialize opt # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/selectCoins # # @example - # random(wid, {address1: 123, address2: 456}) + # random(wid, [{addr1: 1000000}, {addr2: 1000000}]) def random(wid, payments) payments_formatted = Utils.format_payments(payments) self.class.post("/wallets/#{wid}/coin-selections/random", @@ -194,12 +194,12 @@ def list(wid, q = {}) # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postTransaction # @param wid [String] source wallet id # @param passphrase [String] source wallet's passphrase - # @param payments [Hash] addres, amount pair + # @param payments [Array of Hashes] addres, amount pair # @param withdrawal [String or Array] 'self' or mnemonic sentence # @param metadata [Hash] special metadata JSON subset format (cf: https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postTransaction) # # @example - # create(wid, passphrase, {addr1: 1000000}, 'self', {"1": "abc"}) + # create(wid, passphrase, [{addr1: 1000000}, {addr2: 1000000}], 'self', {"1": "abc"}) def create(wid, passphrase, payments, withdrawal = nil, metadata = nil) payments_formatted = Utils.format_payments(payments) payload = { :payments => payments_formatted, @@ -217,7 +217,7 @@ def create(wid, passphrase, payments, withdrawal = nil, metadata = nil) # @see https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postTransactionFee # # @example - # payment_fees(wid, {addr1: 1000000}, {"1": "abc"}) + # payment_fees(wid, [{addr1: 1000000}, {addr2: 1000000}], {"1": "abc"}) def payment_fees(wid, payments, withdrawal = nil, metadata = nil) payments_formatted = Utils.format_payments(payments) payload = { :payments => payments_formatted } diff --git a/lib/cardano_wallet/utils.rb b/lib/cardano_wallet/utils.rb index caca0dc..e969ad4 100644 --- a/lib/cardano_wallet/utils.rb +++ b/lib/cardano_wallet/utils.rb @@ -5,13 +5,24 @@ def self.verify_param_is_hash!(param) raise ArgumentError, "argument should be Hash" unless param.is_a?(Hash) end + def self.verify_param_is_array!(param) + raise ArgumentError, "argument should be Array" unless param.is_a?(Array) + end + + ## + # @param payments [Array of Hashes] - [{addr1: 1}, {addr2: 2}] + # @return [Array of Hashes] - [{:address=>"addr1", :amount=>{:quantity=>1, :unit=>"lovelace"}}, {:address=>"addr2", :amount=>{:quantity=>2, :unit=>"lovelace"}}] def self.format_payments(payments) - verify_param_is_hash!(payments) - payments.collect do |addr, amt| - {:address => addr.to_s, - :amount => {:quantity => amt.to_i, - :unit => "lovelace"} - } + verify_param_is_array!(payments) + raise ArgumentError, "argument should be Array of single Hashes" unless payments.all?{|p| p.size == 1 && p.is_a?(Hash)} + payments.map do |p| + a = p.collect do |addr, amt| + {:address => addr.to_s, + :amount => {:quantity => amt.to_i, + :unit => "lovelace"} + } + end.flatten + Hash[*a] end end diff --git a/spec/byron_spec.rb b/spec/byron_spec.rb index a8d912f..4e4801b 100644 --- a/spec/byron_spec.rb +++ b/spec/byron_spec.rb @@ -23,7 +23,7 @@ def test_byron_tx(source_wid, target_wid) amt = 1000000 address = SHELLEY.addresses.list(target_wid)[0]['id'] - tx_sent = BYRON.transactions.create(source_wid, PASS, {address => amt}) + tx_sent = BYRON.transactions.create(source_wid, PASS, [{address => amt}]) expect(tx_sent['status']).to eq "pending" expect(tx_sent.code).to eq 202 @@ -217,10 +217,10 @@ def test_byron_tx(source_wid, target_wid) it "I could trigger random coin selection - if had money" do wid = create_byron_wallet "icarus" addresses = BYRON.addresses.list(wid) - addr_amount = - {addresses[0]['id'] => 123, - addresses[1]['id'] => 456 - } + addr_amount = [ + { addresses[0]['id'] => 123 }, + { addresses[1]['id'] => 456 } + ] rnd = BYRON.coin_selections.random wid, addr_amount expect(rnd).to include "not_enough_money" @@ -229,12 +229,16 @@ def test_byron_tx(source_wid, target_wid) it "ArgumentError on bad argument address_amount" do wid = create_byron_wallet - payments =[[{addr1: 1, addr2: 2}], "addr:123", 123] + p =[[{addr1: 1, addr2: 2}], "addr:123", 123] cs = BYRON.coin_selections - payments.each do |p| - expect{ cs.random(wid, p) }.to raise_error ArgumentError, - "argument should be Hash" - end + expect{ cs.random(wid, p[0]) }.to raise_error ArgumentError, + "argument should be Array of single Hashes" + + expect{ cs.random(wid, p[1]) }.to raise_error ArgumentError, + "argument should be Array" + + expect{ cs.random(wid, p[2]) }.to raise_error ArgumentError, + "argument should be Array" end end @@ -271,7 +275,7 @@ def test_byron_tx(source_wid, target_wid) target_id = create_byron_wallet "icarus" target_addr = BYRON.addresses.list(target_id)[0]['id'] - tx_sent = BYRON.transactions.create(id, PASS, {target_addr => 1000000}) + tx_sent = BYRON.transactions.create(id, PASS, [{target_addr => 1000000}]) expect(tx_sent.code).to eq 403 expect(tx_sent).to include "not_enough_money" end @@ -281,7 +285,7 @@ def test_byron_tx(source_wid, target_wid) target_id = create_byron_wallet "icarus" target_addr = BYRON.addresses.list(target_id)[0]['id'] - fees = BYRON.transactions.payment_fees(id, {target_addr => 1000000}) + fees = BYRON.transactions.payment_fees(id, [{target_addr => 1000000}]) expect(fees.code).to eq 403 expect(fees).to include "not_enough_money" end diff --git a/spec/shelley_spec.rb b/spec/shelley_spec.rb index 4d29077..b8154e8 100644 --- a/spec/shelley_spec.rb +++ b/spec/shelley_spec.rb @@ -26,7 +26,7 @@ amt = 1000000 address = SHELLEY.addresses.list(@target_id)[0]['id'] - tx_sent = SHELLEY.transactions.create(@wid, PASS, {address => amt}) + tx_sent = SHELLEY.transactions.create(@wid, PASS, [{address => amt}]) expect(tx_sent['status']).to eq "pending" expect(tx_sent.code).to eq 202 @@ -41,7 +41,7 @@ amt = 1000000 address = SHELLEY.addresses.list(@target_id_withdrawal)[0]['id'] - tx_sent = SHELLEY.transactions.create(@wid, PASS, {address => amt}, 'self') + tx_sent = SHELLEY.transactions.create(@wid, PASS, [{address => amt}], 'self') expect(tx_sent['status']).to eq "pending" expect(tx_sent.code).to eq 202 @@ -64,7 +64,7 @@ address = SHELLEY.addresses.list(@target_id_meta)[0]['id'] tx_sent = SHELLEY.transactions.create(@wid, PASS, - {address => amt}, + [{address => amt}], nil, metadata ) @@ -335,24 +335,28 @@ it "I could trigger random coin selection - if had money" do wid = create_shelley_wallet addresses = SHELLEY.addresses.list(wid) - addr_amount = - {addresses[0]['id'] => 123, - addresses[1]['id'] => 456 - } + addr_amount = [ + { addresses[0]['id'] => 123 }, + { addresses[1]['id'] => 456 } + ] rnd = SHELLEY.coin_selections.random wid, addr_amount - expect(rnd.code).to eq 403 expect(rnd).to include "not_enough_money" + expect(rnd.code).to eq 403 end it "ArgumentError on bad argument address_amount" do wid = create_shelley_wallet - payments =[[{addr1: 1, addr2: 2}], "addr:123", 123] + p =[[{addr1: 1, addr2: 2}], "addr:123", 123] cs = SHELLEY.coin_selections - payments.each do |p| - expect{ cs.random(wid, p) }.to raise_error ArgumentError, - "argument should be Hash" - end + expect{ cs.random(wid, p[0]) }.to raise_error ArgumentError, + "argument should be Array of single Hashes" + + expect{ cs.random(wid, p[1]) }.to raise_error ArgumentError, + "argument should be Array" + + expect{ cs.random(wid, p[2]) }.to raise_error ArgumentError, + "argument should be Array" end end @@ -388,8 +392,9 @@ target_id = create_shelley_wallet address = SHELLEY.addresses.list(target_id)[0]['id'] txs = SHELLEY.transactions + amt = [{address => 1000000}] - tx_sent = txs.create(id, PASS, {address => 1000000}) + tx_sent = txs.create(id, PASS, amt) expect(tx_sent).to include "not_enough_money" expect(tx_sent.code).to eq 403 end @@ -399,8 +404,9 @@ target_id = create_shelley_wallet address = SHELLEY.addresses.list(target_id)[0]['id'] txs = SHELLEY.transactions + amt = [{address => 1000000}] - tx_sent = txs.create(id, PASS, {address => 1000000}, 'self') + tx_sent = txs.create(id, PASS, amt, 'self') expect(tx_sent).to include "not_enough_money" expect(tx_sent.code).to eq 403 end @@ -409,14 +415,15 @@ id = create_shelley_wallet target_id = create_shelley_wallet address = SHELLEY.addresses.list(target_id)[0]['id'] + amt = [{address => 1000000}] txs = SHELLEY.transactions - fees = txs.payment_fees(id, {address => 1000000}) + fees = txs.payment_fees(id, amt) expect(fees).to include "not_enough_money" expect(fees.code).to eq 403 - fees = txs.payment_fees(id, {address => 1000000}, 'self') + fees = txs.payment_fees(id, amt, 'self') expect(fees).to include "not_enough_money" expect(fees.code).to eq 403 @@ -427,7 +434,7 @@ "4"=>{ "map"=>[ { "k"=>{ "string"=>"key" }, "v"=>{ "string"=>"value" } }, { "k"=>{ "int"=>14 }, "v"=>{ "int"=>42 } } ] } } - fees = txs.payment_fees(id, {address => 1000000}, 'self', metadata) + fees = txs.payment_fees(id, amt, 'self', metadata) expect(fees).to include "not_enough_money" expect(fees.code).to eq 403 end From 115ab99410c83853c12c32db4cf09d4d0a3cee2a Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Thu, 15 Oct 2020 17:45:51 +0200 Subject: [PATCH 2/3] Version to 0.2.2 --- lib/cardano_wallet/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cardano_wallet/version.rb b/lib/cardano_wallet/version.rb index f6380a5..0a8d9ca 100644 --- a/lib/cardano_wallet/version.rb +++ b/lib/cardano_wallet/version.rb @@ -1,3 +1,3 @@ module CardanoWallet - VERSION = "0.2.1" + VERSION = "0.2.2" end From 6e6c9f3a93fdfb236bde7f7b1d31e36b89fdc98f Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Thu, 15 Oct 2020 17:55:29 +0200 Subject: [PATCH 3/3] Fix tests --- spec/utils_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/utils_spec.rb b/spec/utils_spec.rb index de5e959..0c2c154 100644 --- a/spec/utils_spec.rb +++ b/spec/utils_spec.rb @@ -11,7 +11,7 @@ end it "format_payments" do - payments = CardanoWallet::Utils.format_payments({a1: 1, a2: 2}) + payments = CardanoWallet::Utils.format_payments([{a1: 1}, {a2: 2}]) payments_expected = [ {:address => "a1", @@ -25,7 +25,7 @@ ] expect(payments).to eq payments_expected - payments = CardanoWallet::Utils.format_payments({a1: 1}) + payments = CardanoWallet::Utils.format_payments([{a1: 1}]) payments_expected = [ {:address => "a1", @@ -36,7 +36,7 @@ expect(payments).to eq payments_expected expect{ CardanoWallet::Utils.format_payments("BadArg") }.to raise_error ArgumentError, - "argument should be Hash" + "argument should be Array" end # it "test minUtxoValue" do