Send JSON-RPC 2.0 requests over HTTP.
The implementation is guided by the following specifications:
{ method : String
, params : Params
, result : Json.Decode.Decoder result
}
An RPC call is represented by sending a Request object
to a server. This Request
record is used to create a Request object.
method
contains the name of the method to be invoked.params
holds the parameter values to be used during the invocation of the
method.result
is the JSON decoder used to decode the result field of a successful
Response object.For example, the following Request
record:
import Json.Decode as JD
import Json.Encode as JE
import JsonRpc
getBalance : JsonRpc.Request String
getBalance =
{ method = "eth_getBalance"
, params =
JsonRpc.positionalParams
[ JE.string "0x0000000000000000000000000000000000000000"
, JE.string "latest"
]
, result = JD.string
}
corresponds to the following Request object:
{
"jsonrpc": "2.0",
"method": "eth_getBalance",
"params": [ "0x0000000000000000000000000000000000000000", "latest" ],
"id": ...
}
And, on a successful response the result field is expected to contain a
String
.
Note: The id field is set when sending the request.
A JSON Array or Object that holds the parameter values to be used during invocation of an RPC method.
Json.Encode.Value
A JSON value.
noParams : Params
An empty JSON Array.
positionalParams : List Param -> Params
A JSON Array containing the parameter values in the server expected order.
For example, the following:
import Json.Encode as JE
import JsonRpc
JsonRpc.positionalParams
[ JE.string "0x0000000000000000000000000000000000000000"
, JE.string "latest"
]
represents the JSON Array:
[ "0x0000000000000000000000000000000000000000", "latest" ]
namedParams : List ( String, Param ) -> List ( String, Maybe Param ) -> Params
A JSON Object with member names that match the server expected parameter names.
For example, the following:
import Json.Encode as JE
import JsonRpc
JsonRpc.namedParams
[ ( "apiKey", JE.string "YOUR API KEY"
, ( "n", JE.int 5 )
, ( "min", JE.int 1 )
, ( "max", JE.int 10 )
]
[ ( "replacement", Just False )
]
represents the JSON Object:
{
"apiKey": "YOUR API KEY",
"n": 5,
"min": 1,
"max": 10,
"replacement": false
}
send : String -> (Result Error result -> msg) -> Request result -> Platform.Cmd.Cmd msg
Sends a Request object over HTTP to a JSON-RPC server with a default request identifier of 1.
import JsonRpc
type Msg
= GotBalance (Result JsonRpc.Error String)
let
rpcUrl =
"https://eth-goerli.public.blastapi.io"
in
JsonRpc.send rpcUrl GotBalance getBalance
The Request object:
{
"jsonrpc": "2.0",
"method": "eth_getBalance",
"params": [ "0x0000000000000000000000000000000000000000", "latest" ],
"id": 1
}
will be sent over HTTP to the JSON-RPC server at the endpoint
https://eth-goerli.public.blastapi.io
.
An identifier established by you.
intId : Basics.Int -> Id
An integer identifier.
stringId : String -> Id
A string identifier. Maybe you'd want to use a UUID as your identifier.
import JsonRpc
JsonRpc.stringId "789e08a1-6156-4046-88b6-5b96a87a2eba"
sendWithId : String -> (Result Error result -> msg) -> Id -> Request result -> Platform.Cmd.Cmd msg
Just like send
, but it allows you to set the identifier.
{ headers : List Http.Header
, timeout : Maybe Basics.Float
, tracker : Maybe String
}
The HTTP options you're allowed to modify.
headers
are the extra HTTP headers you'd like to add. The
Content-Type: application/json
, Content-Length: ...
,
and Accept: application/json
headers are always automatically added.timeout
is the number of milliseconds you are willing to wait before giving
up.tracker
lets you cancel
and track
requests.defaultHttpOptions : HttpOptions
The default HTTP options used by send
and sendWithId
.
{ headers = []
, timeout = Nothing
, tracker = Nothing
}
sendCustom : HttpOptions -> String -> (Result Error result -> msg) -> Id -> Request result -> Platform.Cmd.Cmd msg
Just like sendWithId
, but it allows you to customize the
HTTP options.
import JsonRpc exposing (defaultHttpOptions)
type Msg
= GotBalance (Result JsonRpc.Error String)
let
httpOptions =
-- wait 1 minute
{ defaultHttpOptions | timeout = Just 60000 }
rpcUrl =
"https://eth-goerli.public.blastapi.io"
id =
JsonRpc.stringId "abc123"
in
JsonRpc.sendCustom httpOptions rpcUrl GotBalance id getBalance
A request can fail in multiple ways.
HttpError
means there was an error trying to reach the server and the
underlying HttpError
will tell you why.UnexpectedStatus
means the successful HTTP status code
returned by the server was not 200. In other words, it was in the 200 to 299
range, maybe it was 202 or 204 but not 200.DecodeError
means the Response object
returned by the server was malformed.MismatchedIds
means the id of the Request object
is not the same as the id of the Response object.JsonRpcError
means the RPC call encountered an error. The maybeData
field may contain detailed error information as defined by the server.The HTTP transport can fail in multiple ways.
BadUrl
means you did not provide a valid URL.Timeout
means it took too long to get a response.NetworkError
means the user turned off their wifi, went in a cave, etc.BadStatus
means you got a response back, but the status code indicates
failure.This data type categorizes the error code of a failed RPC call.
The categories are derived from the specification as given by the table under the Error object section.