From cbde134ee83665244a7d1f35da5bceb2abca03ed Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Wed, 17 Jan 2024 15:52:19 -0500 Subject: [PATCH] Ability to add new BCH address to an account --- config-schema.dhall | 5 ++++- config.dhall.sample | 4 ++-- forms/alt_top_up.rb | 4 +++- lib/alt_top_up_form.rb | 37 ++++++++++++++++++++++++++++++------ lib/customer.rb | 6 +++--- lib/customer_financials.rb | 19 +++++++++++++++++- sgx_jmp.rb | 1 + test/test_alt_top_up_form.rb | 25 +++++++++++++++++++----- 8 files changed, 82 insertions(+), 19 deletions(-) diff --git a/config-schema.dhall b/config-schema.dhall index 8ec135811a394fa90ef24fa8233c2a746cf30012..739f420352f153a1e40b3764ab3805e3437d3edc 100644 --- a/config-schema.dhall +++ b/config-schema.dhall @@ -30,7 +30,10 @@ , rpc_username : Text } , electrum_notify_url : - forall (address : Text) -> forall (customer_id : Text) -> Text + forall (address : Text) -> + forall (customer_id : Text) -> + forall (currency : Text) -> + Text , interac : Text , keep_area_codes : List Text , keep_area_codes_in : { account : Text, sip_peer_id : Text, site_id : Text } diff --git a/config.dhall.sample b/config.dhall.sample index 7d44a31fdf6fa0fbf14bf9c7fea5df1f5847e9c2..ebf2203e4c56eaa5e598c417f2f1ddb877a53246 100644 --- a/config.dhall.sample +++ b/config.dhall.sample @@ -86,8 +86,8 @@ in activation_amount_accept = 15, credit_card_url = \(jid: Text) -> \(customer_id: Text) -> "https://pay.jmp.chat/${jid}/credit_cards?customer_id=${customer_id}", - electrum_notify_url = \(address: Text) -> \(customer_id: Text) -> - "https://pay.jmp.chat/electrum_notify?address=${address}&customer_id=${customer_id}", + electrum_notify_url = \(address: Text) -> \(customer_id: Text) -> \(currency: Text) -> + "https://pay.jmp.chat/electrum_notify?address=${address}&customer_id=${customer_id}¤cy=${currency}", adr = "", interac = "", payable = "", diff --git a/forms/alt_top_up.rb b/forms/alt_top_up.rb index fbeaea163061141f37465970a07d61838e362ac3..d5f1625e4641ff35136e1bb9abf6869472c4e4ab 100644 --- a/forms/alt_top_up.rb +++ b/forms/alt_top_up.rb @@ -14,6 +14,7 @@ field( render "alt_top_up/mailing_address" render "alt_top_up/interac" if @currency == :CAD render "alt_top_up/btc_addresses" +render "alt_top_up/bch_addresses" field( var: "http://jabber.org/protocol/commands#actions", @@ -21,7 +22,8 @@ field( type: "list-single", options: [ { label: "Done", value: "complete" }, - { label: "Add new Bitcoin address to account", value: "BTC" }, + { label: "Add new Bitcoin address", value: "BTC" }, + { label: "Add new Bitcoin Cash address", value: "BCH" }, { label: "Get single-use Monero address", value: "XMR" }, { label: "Get single-use Ethereum address", value: "ETH" } ], diff --git a/lib/alt_top_up_form.rb b/lib/alt_top_up_form.rb index 88714d280700c67609f79b970d885a8869869fd5..041c0c9be96c7e6fb37e60f6e5736a2f17e6bf2c 100644 --- a/lib/alt_top_up_form.rb +++ b/lib/alt_top_up_form.rb @@ -4,16 +4,20 @@ require_relative "simple_swap" class AltTopUpForm def self.for(customer) - customer.btc_addresses.then do |addrs| - AltTopUpForm.new(customer, addrs) + EMPromise.all([ + customer.btc_addresses, + customer.bch_addresses + ]).then do |(btc, bch)| + AltTopUpForm.new(customer, btc, bch) end end - def initialize(customer, btc_addresses) + def initialize(customer, btc_addresses, bch_addresses) @customer = customer @balance = customer.balance @currency = customer.currency @btc_addresses = btc_addresses + @bch_addresses = bch_addresses end def form @@ -21,7 +25,8 @@ class AltTopUpForm "alt_top_up", balance: @balance, currency: @currency, - btc_addresses: @btc_addresses + btc_addresses: @btc_addresses, + bch_addresses: @bch_addresses ) end @@ -29,8 +34,8 @@ class AltTopUpForm action = form.field("http://jabber.org/protocol/commands#actions")&.value.to_s case action - when "BTC" - BitcoinAddress.new(@customer) + when "BTC", "BCH" + ADD_ADDR.fetch(action).new(@customer) when /\A[A-Z]{3}\Z/ SimpleSwapAddress.new(@customer, action, @btc_addresses.first) else @@ -57,6 +62,21 @@ class AltTopUpForm end end + class BitcoinCashAddress + def initialize(customer) + @customer = customer + end + + def action(reply) + @customer.add_bch_address.then do |addr| + reply.command << FormTemplate.render( + "alt_top_up/bch", + bch_addresses: [addr] + ) + end + end + end + class SimpleSwapAddress def initialize(customer, currency, btc_address, simple_swap: SimpleSwap.new) @customer = customer @@ -80,4 +100,9 @@ class AltTopUpForm end end end + + ADD_ADDR = { + "BTC" => BitcoinAddress, + "BCH" => BitcoinCashAddress + }.freeze end diff --git a/lib/customer.rb b/lib/customer.rb index 4c9708b07d10fad34b067c4659c7ce4036324eb4..ea288d82d52cb503448d60b056a8c0620c29e8a5 100644 --- a/lib/customer.rb +++ b/lib/customer.rb @@ -30,9 +30,9 @@ class Customer :fwd, :transcription_enabled def_delegators :@usage, :usage_report, :message_usage, :incr_message_usage, :calling_charges_this_month - def_delegators :@financials, :payment_methods, :btc_addresses, - :add_btc_address, :declines, :mark_decline, - :transactions + def_delegators :@financials, :payment_methods, :declines, :mark_decline, + :btc_addresses, :add_btc_address, :transactions, + :bch_addresses, :add_bch_address def self.extract(customer_id, jid, **kwargs) (kwargs[:parent_customer_id] ? ChildCustomer : Customer).new( diff --git a/lib/customer_financials.rb b/lib/customer_financials.rb index ea0df7491ba4c28d3da46cd47b3ab9337e1a6963..3b275b18e66a6845743b3ddb6579b61f5d95e236 100644 --- a/lib/customer_financials.rb +++ b/lib/customer_financials.rb @@ -21,6 +21,10 @@ class CustomerFinancials REDIS.smembers("jmp_customer_btc_addresses-#{@customer_id}") end + def bch_addresses + REDIS.smembers("jmp_customer_bch_addresses-#{@customer_id}") + end + def add_btc_address REDIS.spopsadd([ "jmp_available_btc_addresses", @@ -28,7 +32,20 @@ class CustomerFinancials ]).then do |addr| ELECTRUM.notify( addr, - CONFIG[:electrum_notify_url].call(addr, @customer_id) + CONFIG[:electrum_notify_url].call(addr, @customer_id, "btc") + ) + addr + end + end + + def add_bch_address + REDIS.spopsadd([ + "jmp_available_bch_addresses", + "jmp_customer_bch_addresses-#{@customer_id}" + ]).then do |addr| + ELECTRUM_BCH.notify( + addr, + CONFIG[:electrum_notify_url].call(addr, @customer_id, "bch") ) addr end diff --git a/sgx_jmp.rb b/sgx_jmp.rb index 9b1819c327942de9f7d73e3dfcf785f164574ab8..b6cda9e3c4dae5b3d503f38f7517d62cf49c1b7c 100644 --- a/sgx_jmp.rb +++ b/sgx_jmp.rb @@ -108,6 +108,7 @@ require_relative "web" require_relative "lib/statsd" ELECTRUM = Electrum.new(**CONFIG[:electrum]) +ELECTRUM_BCH = Electrum.new(**CONFIG[:electrum_bch]) EM::Hiredis::Client.load_scripts_from("./redis_lua") Faraday.default_adapter = :em_synchrony diff --git a/test/test_alt_top_up_form.rb b/test/test_alt_top_up_form.rb index 4de0024a129ff0aff7cb8597b404daccf042ebb9..1e9b7be6a13b054efd119902f07ff0e7ee75d517 100644 --- a/test/test_alt_top_up_form.rb +++ b/test/test_alt_top_up_form.rb @@ -11,6 +11,11 @@ class AltTopUpFormTest < Minitest::Test EMPromise.resolve([]), ["jmp_customer_btc_addresses-test"] ) + CustomerFinancials::REDIS.expect( + :smembers, + EMPromise.resolve([]), + ["jmp_customer_bch_addresses-test"] + ) assert_kind_of( AltTopUpForm, AltTopUpForm.for(customer).sync @@ -24,6 +29,11 @@ class AltTopUpFormTest < Minitest::Test EMPromise.resolve(["testaddr"]), ["jmp_customer_btc_addresses-test"] ) + CustomerFinancials::REDIS.expect( + :smembers, + EMPromise.resolve([]), + ["jmp_customer_bch_addresses-test"] + ) assert_kind_of( AltTopUpForm, AltTopUpForm.for(customer).sync @@ -37,6 +47,11 @@ class AltTopUpFormTest < Minitest::Test EMPromise.resolve([]), ["jmp_customer_btc_addresses-test"] ) + CustomerFinancials::REDIS.expect( + :smembers, + EMPromise.resolve([]), + ["jmp_customer_bch_addresses-test"] + ) assert_kind_of( AltTopUpForm, AltTopUpForm.for(customer(plan_name: "test_cad")).sync @@ -48,7 +63,7 @@ class AltTopUpFormTest < Minitest::Test assert_kind_of( Blather::Stanza::X, AltTopUpForm.new( - customer, ["some_addr"] + customer, ["some_addr"], [] ).form ) end @@ -57,7 +72,7 @@ class AltTopUpFormTest < Minitest::Test assert_kind_of( Blather::Stanza::X, AltTopUpForm.new( - customer, [] + customer, [], [] ).form ) end @@ -69,7 +84,7 @@ class AltTopUpFormTest < Minitest::Test ] assert_kind_of( AltTopUpForm::NoOp, - AltTopUpForm.new(customer, []).parse(iq_form) + AltTopUpForm.new(customer, [], []).parse(iq_form) ) end @@ -80,7 +95,7 @@ class AltTopUpFormTest < Minitest::Test ] assert_kind_of( AltTopUpForm::BitcoinAddress, - AltTopUpForm.new(customer, []).parse(iq_form) + AltTopUpForm.new(customer, [], []).parse(iq_form) ) end @@ -91,7 +106,7 @@ class AltTopUpFormTest < Minitest::Test ] assert_kind_of( AltTopUpForm::SimpleSwapAddress, - AltTopUpForm.new(customer, []).parse(iq_form) + AltTopUpForm.new(customer, [], []).parse(iq_form) ) end end