Generalize JSON-RPC subscription table
Allows for other types of subscriptions, not just logs.
This commit is contained in:
parent
8c45babcdf
commit
82043c2fcc
|
@ -17,7 +17,7 @@ push: {.upraises: [].}
|
||||||
type
|
type
|
||||||
JsonRpcProvider* = ref object of Provider
|
JsonRpcProvider* = ref object of Provider
|
||||||
client: Future[RpcClient]
|
client: Future[RpcClient]
|
||||||
subscriptions: Table[JsonNode, LogHandler]
|
subscriptions: Table[JsonNode, SubscriptionHandler]
|
||||||
JsonRpcSubscription = ref object of Subscription
|
JsonRpcSubscription = ref object of Subscription
|
||||||
provider: JsonRpcProvider
|
provider: JsonRpcProvider
|
||||||
id: JsonNode
|
id: JsonNode
|
||||||
|
@ -25,6 +25,7 @@ type
|
||||||
provider: JsonRpcProvider
|
provider: JsonRpcProvider
|
||||||
address: ?Address
|
address: ?Address
|
||||||
JsonRpcProviderError* = object of EthersError
|
JsonRpcProviderError* = object of EthersError
|
||||||
|
SubscriptionHandler = proc(id, arguments: JsonNode) {.gcsafe, upraises:[].}
|
||||||
|
|
||||||
template raiseProviderError(message: string) =
|
template raiseProviderError(message: string) =
|
||||||
raise newException(JsonRpcProviderError, message)
|
raise newException(JsonRpcProviderError, message)
|
||||||
|
@ -46,20 +47,19 @@ proc connect(_: type RpcClient, url: string): Future[RpcClient] {.async.} =
|
||||||
|
|
||||||
proc connect(provider: JsonRpcProvider, url: string) =
|
proc connect(provider: JsonRpcProvider, url: string) =
|
||||||
|
|
||||||
proc getLogHandler(subscriptionId: JsonNode): ?LogHandler =
|
proc getSubscriptionHandler(id: JsonNode): ?SubscriptionHandler =
|
||||||
try:
|
try:
|
||||||
if provider.subscriptions.hasKey(subscriptionId):
|
if provider.subscriptions.hasKey(id):
|
||||||
provider.subscriptions[subscriptionId].some
|
provider.subscriptions[id].some
|
||||||
else:
|
else:
|
||||||
LogHandler.none
|
SubscriptionHandler.none
|
||||||
except Exception:
|
except Exception:
|
||||||
LogHandler.none
|
SubscriptionHandler.none
|
||||||
|
|
||||||
proc handleSubscription(arguments: JsonNode) {.upraises: [].} =
|
proc handleSubscription(arguments: JsonNode) {.upraises: [].} =
|
||||||
if id =? arguments["subscription"].catch and
|
if id =? arguments["subscription"].catch and
|
||||||
handler =? getLogHandler(id) and
|
handler =? getSubscriptionHandler(id):
|
||||||
log =? Log.fromJson(arguments["result"]).catch:
|
handler(id, arguments)
|
||||||
handler(log)
|
|
||||||
|
|
||||||
proc subscribe: Future[RpcClient] {.async.} =
|
proc subscribe: Future[RpcClient] {.async.} =
|
||||||
let client = await RpcClient.connect(url)
|
let client = await RpcClient.connect(url)
|
||||||
|
@ -133,8 +133,14 @@ method subscribe*(provider: JsonRpcProvider,
|
||||||
Future[Subscription] {.async.} =
|
Future[Subscription] {.async.} =
|
||||||
let client = await provider.client
|
let client = await provider.client
|
||||||
doAssert client of RpcWebSocketClient, "subscriptions require websockets"
|
doAssert client of RpcWebSocketClient, "subscriptions require websockets"
|
||||||
|
|
||||||
|
proc handler(id, arguments: JsonNode) =
|
||||||
|
if log =? Log.fromJson(arguments["result"]).catch:
|
||||||
|
callback(log)
|
||||||
|
|
||||||
let id = await client.eth_subscribe("logs", some filter)
|
let id = await client.eth_subscribe("logs", some filter)
|
||||||
provider.subscriptions[id] = callback
|
provider.subscriptions[id] = handler
|
||||||
|
|
||||||
return JsonRpcSubscription(id: id, provider: provider)
|
return JsonRpcSubscription(id: id, provider: provider)
|
||||||
|
|
||||||
method unsubscribe*(subscription: JsonRpcSubscription) {.async.} =
|
method unsubscribe*(subscription: JsonRpcSubscription) {.async.} =
|
||||||
|
|
Loading…
Reference in New Issue