~singpolyma/jmp-pay

ref: 68ed9c34b0d4a2eaa0e49def372deabe4eb55daf jmp-pay/lib/electrum.rb -rw-r--r-- 1.7 KiB
68ed9c34Stephen Paul Weber Run billing 3 at a time 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# frozen_string_literal: true

require "bigdecimal"
require "json"
require "net/http"
require "securerandom"

class Electrum
	def initialize(rpc_uri:, rpc_username:, rpc_password:)
		@rpc_uri = URI(rpc_uri)
		@rpc_username = rpc_username
		@rpc_password = rpc_password
	end

	def getaddresshistory(address)
		rpc_call(:getaddresshistory, address: address)["result"]
	end

	def gettransaction(tx_hash)
		Transaction.new(self, tx_hash, rpc_call(
			:deserialize,
			[rpc_call(:gettransaction, txid: tx_hash)["result"]]
		)["result"])
	end

	def get_tx_status(tx_hash)
		rpc_call(:get_tx_status, txid: tx_hash)["result"]
	end

	def listaddresses
		rpc_call(:listaddresses, {})["result"]
	end

	def notify(address, url)
		rpc_call(:notify, address: address, URL: url)["result"]
	end

	class Transaction
		def initialize(electrum, tx_hash, tx)
			@electrum = electrum
			@tx_hash = tx_hash
			@tx = tx
		end

		def confirmations
			@electrum.get_tx_status(@tx_hash)["confirmations"]
		end

		def amount_for(*addresses)
			BigDecimal(
				@tx["outputs"]
					.select { |o| addresses.include?(o["address"]) }
					.map { |o| o["value_sats"] }
					.sum
			) * 0.00000001
		end
	end

protected

	def rpc_call(method, params)
		JSON.parse(post_json(
			jsonrpc: "2.0",
			id: SecureRandom.hex,
			method: method.to_s,
			params: params
		).body)
	end

	def post_json_req(data)
		req = Net::HTTP::Post.new(
			@rpc_uri,
			"Content-Type" => "application/json"
		)
		req.basic_auth(@rpc_username, @rpc_password)
		req.body = data.to_json
		req
	end

	def post_json(data)
		Net::HTTP.start(
			@rpc_uri.hostname,
			@rpc_uri.port,
			use_ssl: @rpc_uri.scheme == "https"
		) do |http|
			http.request(post_json_req(data))
		end
	end
end