diff --git a/bin/process_pending_btc_transactions b/bin/process_pending_btc_transactions index 51cbcc8cac3d3b606d4f6963986c9e3c458a2ac7..e1f81c0682efa9043ac483895bdc86e742964974 100755 --- a/bin/process_pending_btc_transactions +++ b/bin/process_pending_btc_transactions @@ -4,6 +4,11 @@ # Usage: bin/process_pending-btc_transactions '{ # oxr_app_id = "", # required_confirmations = 3, +# notify_using = { +# jid = "", +# password = "", +# target = \(tel: Text) -> "${tel}@cheogram.com" +# }, # electrum = env:ELECTRUM_CONFIG, # plans = ./plans.dhall # }' @@ -16,11 +21,12 @@ require "nokogiri" require "pg" require "redis" +require_relative "../lib/blather_notify" require_relative "../lib/electrum" CONFIG = Dhall::Coder - .new(safe: Dhall::Coder::JSON_LIKE + [Symbol]) + .new(safe: Dhall::Coder::JSON_LIKE + [Symbol, Proc]) .load(ARGV[0], transform_keys: :to_sym) REDIS = Redis.new @@ -30,6 +36,11 @@ DB = PG.connect(dbname: "jmp") DB.type_map_for_results = PG::BasicTypeMapForResults.new(DB) DB.type_map_for_queries = PG::BasicTypeMapForQueries.new(DB) +BlatherNotify.start( + CONFIG[:notify_using][:jid], + CONFIG[:notify_using][:password] +) + unless (cad_to_usd = REDIS.get("cad_to_usd")&.to_f) oxr = Money::Bank::OpenExchangeRatesBank.new(Money::RatesStore::Memory.new) oxr.app_id = CONFIG.fetch(:oxr_app_id) @@ -70,6 +81,44 @@ class Plan end end +class Customer + def initialize(customer_id) + @customer_id = customer_id + end + + def notify(body) + jid = REDIS.get("jmp_customer_jid-#{@customer_id}") + tel = REDIS.lindex("catapult_cred-#{jid}", 3) + BlatherNotify.say( + CONFIG[:notify_using][:target].call(tel.to_s), + body + ) + end + + def plan + Plan.for_customer(@customer_id) + end + + def add_btc_credit(txid, fiat_amount) + DB.exec_params(<<-SQL, [@customer_id, txid, fiat_amount]) + INSERT INTO transactions + (customer_id, transaction_id, amount, note) + VALUES + ($1, $2, $3, 'Bitcoin payment') + ON CONFLICT (transaction_id) DO NOTHING + SQL + notify_btc_credit(txid, fiat_amount) + end + + def notify_btc_credit(txid, fiat_amount) + tx_hash, = txid.split("/", 2) + notify( + "Your Bitcoin transaction has been added as $#{'%.4f' % fiat_amount} " \ + "to your account.\n(txhash: #{tx_hash})" + ) + end +end + REDIS.hgetall("pending_btc_transactions").each do |(txid, customer_id)| tx_hash, address = txid.split("/", 2) transaction = ELECTRUM.gettransaction(tx_hash) @@ -80,16 +129,11 @@ REDIS.hgetall("pending_btc_transactions").each do |(txid, customer_id)| next end DB.transaction do - plan = Plan.for_customer(customer_id) + customer = Customer.new(customer_id) + plan = customer.plan if plan amount = btc * btc_sell_price.fetch(plan.currency).round(4, :floor) - DB.exec_params(<<-SQL, [customer_id, txid, amount]) - INSERT INTO transactions - (customer_id, transaction_id, amount, note) - VALUES - ($1, $2, $3, 'Bitcoin payment') - ON CONFLICT (transaction_id) DO NOTHING - SQL + customer.add_btc_credit(txid, amount) else warn "No plan for #{customer_id} cannot save #{txid}" end