diff --git a/ethers/providers/jsonrpc.nim b/ethers/providers/jsonrpc.nim index 2f6e294..c45a81d 100644 --- a/ethers/providers/jsonrpc.nim +++ b/ethers/providers/jsonrpc.nim @@ -2,6 +2,7 @@ import std/uri import pkg/json_rpc/rpcclient import ../basics import ../provider +import ../signer import ./rpccalls export basics @@ -9,8 +10,18 @@ export provider push: {.upraises: [].} -type JsonRpcProvider* = ref object of Provider - client: Future[RpcClient] +type + JsonRpcProvider* = ref object of Provider + client: Future[RpcClient] + JsonRpcSigner* = ref object of Signer + provider: JsonRpcProvider + address: ?Address + JsonRpcProviderError* = object of IOError + +template raiseProviderError(message: string) = + raise newException(JsonRpcProviderError, message) + +# Provider const defaultUrl = "http://localhost:8545" @@ -38,6 +49,12 @@ proc listAccounts*(provider: JsonRpcProvider): Future[seq[Address]] {.async.} = let client = await provider.client return await client.eth_accounts() +proc getSigner*(provider: JsonRpcProvider): JsonRpcSigner = + JsonRpcSigner(provider: provider) + +proc getSigner*(provider: JsonRpcProvider, address: Address): JsonRpcSigner = + JsonRpcSigner(provider: provider, address: some address) + method getBlockNumber*(provider: JsonRpcProvider): Future[UInt256] {.async.} = let client = await provider.client return await client.eth_blockNumber() @@ -46,3 +63,15 @@ method call*(provider: JsonRpcProvider, tx: Transaction): Future[seq[byte]] {.async.} = let client = await provider.client return await client.eth_call(tx) + +# Signer + +method getAddress*(signer: JsonRpcSigner): Future[Address] {.async.} = + if address =? signer.address: + return address + + let accounts = await signer.provider.listAccounts() + if accounts.len > 0: + return accounts[0] + + raiseProviderError "no address found" diff --git a/ethers/signer.nim b/ethers/signer.nim new file mode 100644 index 0000000..e1a0618 --- /dev/null +++ b/ethers/signer.nim @@ -0,0 +1,8 @@ +import ./basics + +export basics + +type Signer* = ref object of RootObj + +method getAddress*(signer: Signer): Future[Address] {.base, async.} = + doAssert false, "not implemented" diff --git a/testmodule/test.nim b/testmodule/test.nim index 0dff5da..236088c 100644 --- a/testmodule/test.nim +++ b/testmodule/test.nim @@ -1,4 +1,5 @@ import ./testJsonRpcProvider +import ./testJsonRpcSigner import ./testContracts {.warning[UnusedImport]:off.} diff --git a/testmodule/testJsonRpcSigner.nim b/testmodule/testJsonRpcSigner.nim new file mode 100644 index 0000000..544c2c5 --- /dev/null +++ b/testmodule/testJsonRpcSigner.nim @@ -0,0 +1,18 @@ +import pkg/asynctest +import pkg/ethers + +suite "JsonRpcSigner": + + var provider: JsonRpcProvider + + setup: + provider = JsonRpcProvider.new() + + test "is connected to the first account of the provider by default": + let signer = provider.getSigner() + check (await signer.getAddress()) == (await provider.listAccounts())[0] + + test "can connect to a different account": + let account = (await provider.listAccounts())[1] + let signer = provider.getSigner(account) + check (await signer.getAddress()) == account