From 05366c4a49817364986cb8a8f9394e7b80374374 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Tue, 18 Jan 2022 12:10:20 +0100 Subject: [PATCH] Introduce JsonRpcProvider --- ethers.nimble | 1 + ethers/basics.nim | 7 +++++ ethers/provider.nim | 2 ++ ethers/providers/jsonrpc.nim | 35 ++++++++++++++++++++++++ ethers/providers/rpccalls.nim | 7 +++++ ethers/providers/rpccalls/signatures.nim | 1 + testmodule/testJsonRpcProvider.nim | 23 ++++++++++++++++ 7 files changed, 76 insertions(+) create mode 100644 ethers/basics.nim create mode 100644 ethers/provider.nim create mode 100644 ethers/providers/jsonrpc.nim create mode 100644 ethers/providers/rpccalls.nim create mode 100644 ethers/providers/rpccalls/signatures.nim create mode 100644 testmodule/testJsonRpcProvider.nim diff --git a/ethers.nimble b/ethers.nimble index 25dc9c5..ea548fa 100644 --- a/ethers.nimble +++ b/ethers.nimble @@ -6,6 +6,7 @@ license = "MIT" requires "chronos >= 3.0.0 & < 4.0.0" requires "contractabi >= 0.4.0 & < 0.5.0" requires "questionable >= 0.10.2 & < 0.11.0" +requires "json_rpc" requires "stew" task test, "Run the test suite": diff --git a/ethers/basics.nim b/ethers/basics.nim new file mode 100644 index 0000000..2390d31 --- /dev/null +++ b/ethers/basics.nim @@ -0,0 +1,7 @@ +import pkg/chronos +import pkg/questionable +import ./address + +export chronos +export address +export questionable diff --git a/ethers/provider.nim b/ethers/provider.nim new file mode 100644 index 0000000..d9df3c6 --- /dev/null +++ b/ethers/provider.nim @@ -0,0 +1,2 @@ +type + Provider* = ref object of RootObj diff --git a/ethers/providers/jsonrpc.nim b/ethers/providers/jsonrpc.nim new file mode 100644 index 0000000..812861f --- /dev/null +++ b/ethers/providers/jsonrpc.nim @@ -0,0 +1,35 @@ +import std/uri +import pkg/json_rpc/rpcclient +import ../basics +import ../provider +import ./rpccalls + +export basics +export provider + +type JsonRpcProvider* = ref object of Provider + client: Future[RpcClient] + +const defaultUrl = "http://localhost:8545" + +proc connect(_: type RpcClient, url: string): Future[RpcClient] {.async.} = + case parseUri(url).scheme + of "ws", "wss": + let client = newRpcWebSocketClient() + await client.connect(url) + return client + else: + let client = newRpcHttpClient() + await client.connect(url) + return client + +proc new*(_: type JsonRpcProvider, url=defaultUrl): JsonRpcProvider = + JsonRpcProvider(client: RpcClient.connect(url)) + +proc listAccounts*(provider: JsonRpcProvider): Future[seq[Address]] {.async.} = + let client = await provider.client + var addresses: seq[Address] + for address in await client.eth_accounts(): + if address =? Address.init(address): + addresses.add(address) + return addresses diff --git a/ethers/providers/rpccalls.nim b/ethers/providers/rpccalls.nim new file mode 100644 index 0000000..21c0a86 --- /dev/null +++ b/ethers/providers/rpccalls.nim @@ -0,0 +1,7 @@ +import std/os +import pkg/json_rpc/rpcclient +import ../basics + +const file = currentSourcePath.parentDir / "rpccalls" / "signatures.nim" + +createRpcSigs(RpcClient, file) diff --git a/ethers/providers/rpccalls/signatures.nim b/ethers/providers/rpccalls/signatures.nim new file mode 100644 index 0000000..0fac95c --- /dev/null +++ b/ethers/providers/rpccalls/signatures.nim @@ -0,0 +1 @@ +proc eth_accounts: seq[string] diff --git a/testmodule/testJsonRpcProvider.nim b/testmodule/testJsonRpcProvider.nim new file mode 100644 index 0000000..9d625de --- /dev/null +++ b/testmodule/testJsonRpcProvider.nim @@ -0,0 +1,23 @@ +import pkg/asynctest +import pkg/chronos +import pkg/ethers/providers/jsonrpc + +suite "JsonRpcProvider": + + var provider: JsonRpcProvider + + setup: + provider = JsonRpcProvider.new("ws://localhost:8545") + + test "can be instantiated with a default URL": + discard JsonRpcProvider.new() + + test "can be instantiated with an HTTP URL": + discard JsonRpcProvider.new("http://localhost:8545") + + test "can be instantiated with a websocket URL": + discard JsonRpcProvider.new("ws://localhost:8545") + + test "lists all accounts": + let accounts = await provider.listAccounts() + check accounts.len > 0