~singpolyma/sgx-jmp

ref: da30c371e56b8bb577897f1151b59c24e209127f sgx-jmp/lib/electrum.rb -rw-r--r-- 1.8 KiB
da30c371Stephen Paul Weber Allow finishing admin command 1 year, 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
# frozen_string_literal: true

require "bigdecimal"
require "em-http"
require "em_promise"
require "em-synchrony/em-http" # For apost vs post
require "json"
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 createnewaddress
		rpc_call(:createnewaddress, {}).then { |r| r["result"] }
	end

	def getaddresshistory(address)
		rpc_call(:getaddresshistory, address: address).then { |r| r["result"] }
	end

	def gettransaction(tx_hash)
		rpc_call(:gettransaction, txid: tx_hash).then { |tx|
			rpc_call(:deserialize, [tx["result"]])
		}.then do |tx|
			Transaction.new(self, tx_hash, tx["result"])
		end
	end

	def get_tx_status(tx_hash)
		rpc_call(:get_tx_status, txid: tx_hash).then { |r| r["result"] }
	end

	def notify(address, url)
		rpc_call(:notify, address: address, URL: url).then { |r| r["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).then { |r| r["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)
		post_json(
			jsonrpc: "2.0",
			id: SecureRandom.hex,
			method: method.to_s,
			params: params
		).then { |res| JSON.parse(res.response) }
	end

	def post_json(data)
		EM::HttpRequest.new(
			@rpc_uri,
			tls: { verify_peer: true }
		).apost(
			head: {
				"Authorization" => [@rpc_username, @rpc_password],
				"Content-Type" => "application/json"
			},
			body: data.to_json
		)
	end
end