module TxCatcher class Server < Goliath::API use Goliath::Rack::Params def response(env) uri = env["REQUEST_URI"] return route_for(uri) end def route_for(path) puts "[REQUEST: #{path}]" if path =~ /\A\/addr\/[0-9a-zA-Z]+\/utxo/ utxo(path) elsif path.start_with? "/addr/" address(path) elsif path.start_with? "/tx/send" broadcast_tx(params["rawtx"]) elsif path == "/" || path.empty? [200, {}, "TxCatcher server, #{TxCatcher::Config.rpcnode["name"]}, current_block_height: #{TxCatcher.current_block_height}"] else [404, {}, { error: "404, not found" }.to_json] end end def address(path) path = path.split("/").delete_if { |i| i.empty? } addr = path.last model = Address.where(address: addr).eager(deposits: :transactions).first if model transactions_ids = model.deposits.map { |d| d.transaction.txid } deposits = model.deposits.map do |d| t = d.transaction { txid: t.txid, amount: d.amount_in_btc, satoshis: d.amount, confirmations: 0 } end [200, {}, { address: model.address, received: model.received, deposits: deposits }.to_json] else [200, {}, { address: addr, received: 0, deposits: [] }.to_json] end end def utxo(path) path = path.split("/").delete_if { |i| i.empty? } path.pop addr = path.last model = Address.where(address: addr).eager(deposits: :transactions).first transactions = model.deposits.map { |d| d.transaction } utxos = transactions.map do |t| outs = t.tx_hash["vout"].select { |out| out["scriptPubKey"]["addresses"] == [addr] } outs.map! do |out| out["confirmations"] = t.confirmations || 0 out["txid"] = t.txid out end outs end.flatten [200, {}, utxos.to_json] end def broadcast_tx(txhex) TxCatcher.rpc_node.sendrawtransaction(txhex) tx = TxCatcher.rpc_node.decoderawtransaction(txhex) [200, {}, tx.to_json] end end end