@@ 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