-
Notifications
You must be signed in to change notification settings - Fork 1
/
rpc.jl
47 lines (41 loc) · 1.3 KB
/
rpc.jl
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
import Base.IO, HTTP
using JSON
# RPC config
jsonrpcversion = "2.0"
const RpcEndpoint = Union{IO, String}
# Query encoding
rpcdict(method, params...) = Dict("jsonrpc"=>jsonrpcversion, "method"=>method, "params"=>params, "id"=>rand(1:10000))
rpcjson(method, params...) = JSON.json(rpcdict(method, params...))
encode(h::Integer) = string("0x", string(h, base=16))
# IPC request
function rpcraw(io::IO, rpcjson::String)
write(io, rpcjson)
flush(io)
readavailable(io)
end
# HTTP request
function rpcraw(http::String, rpcjson::String)
HTTP.post(http, Dict("Content-Type"=>"application/json"), rpcjson)
end
function rpcrequest(io::RpcEndpoint, method::String, params...)
rpcraw(io, rpcjson(method, params...))
end
# Output decoding
struct Empty end # Fixes Dict iteration
decode(v::Nothing) = Empty
decode(b::Bool) = b
decode(s::String) = try parse(Int64, s) catch _ s end
decode(n::Int) = n
decode(d::Dict) = Dict(k => decode(v) for (k, v) in d)
decode(a::Vector) = map(decode, a)
# RPC with parsing
function parseresult(streamout::Vector{UInt8})
out = JSON.parse(String(streamout))
decode(get(out, "result", out))
end
function parseresult(response::HTTP.Response)
parseresult(response.body)
end
function rpc(io::RpcEndpoint, method::String, params...)
parseresult(rpcrequest(io, method, params...))
end