1#!/usr/bin/ruby
2# frozen_string_literal: true
3
4# This reads the queue of "changed addresses" from electrum webhooks in the
5# form "<address>/<customer_id>" and turns those into <tx_hash>/<address> =>
6# customer_id keys for the bin/process_pending_btc_transactions script to run
7# through and process more fully
8#
9# Usage: bin/process_pending-btc_transactions '{
10# pidfile : Text,
11# electrum : env:ELECTRUM_CONFIG,
12# }'
13
14require "dhall"
15
16CONFIG =
17 Dhall::Coder
18 .new(safe: Dhall::Coder::JSON_LIKE + [Symbol, Proc])
19 .load(ARGV[0], transform_keys: :to_sym)
20
21require "redis"
22require_relative "../lib/electrum"
23require_relative "../lib/pidfile"
24
25REDIS = Redis.new
26ELECTRUM = Electrum.new(**CONFIG[:electrum])
27
28PIDFile.new(CONFIG[:pidfile]).lock do |pid|
29 loop do
30 key, value = REDIS.brpop("exciting_#{ELECTRUM.currency}_addrs", 600)
31
32 # Rewrite the pidfile so monit can see we're still alive
33 pid.refresh
34
35 # brpop allows blocking on multiple keys, and key tells us which one
36 # signalled but in this case we know which one, so just make sure it's
37 # not nil which means the timeout fired
38 next unless key
39
40 address, customer_id = value.split("/", 2)
41
42 txids =
43 ELECTRUM
44 .getaddresshistory(address)
45 .map { |item| "#{item['tx_hash']}/#{address}" }
46
47 next if txids.empty?
48
49 REDIS.hset(
50 "pending_#{ELECTRUM.currency}_transactions",
51 *txids.flat_map { |txid| [txid, customer_id] }
52 )
53 end
54end