mirror of
https://github.com/logos-storage/nim-ethers.git
synced 2026-01-05 23:23:08 +00:00
support async subscription event handlers
This commit is contained in:
parent
e462649aec
commit
a87b1b23a8
@ -27,6 +27,7 @@ type
|
|||||||
ContractError* = object of EthersError
|
ContractError* = object of EthersError
|
||||||
Confirmable* = ?TransactionResponse
|
Confirmable* = ?TransactionResponse
|
||||||
EventHandler*[E: Event] = proc(event: E) {.gcsafe, upraises:[].}
|
EventHandler*[E: Event] = proc(event: E) {.gcsafe, upraises:[].}
|
||||||
|
AsyncEventHandler*[E: Event] = proc(event: E): Future[void] {.gcsafe, upraises:[].}
|
||||||
|
|
||||||
func new*(ContractType: type Contract,
|
func new*(ContractType: type Contract,
|
||||||
address: Address,
|
address: Address,
|
||||||
@ -215,3 +216,17 @@ proc subscribe*[E: Event](contract: Contract,
|
|||||||
handler(event)
|
handler(event)
|
||||||
|
|
||||||
contract.provider.subscribe(filter, logHandler)
|
contract.provider.subscribe(filter, logHandler)
|
||||||
|
|
||||||
|
proc subscribe*[E: Event](contract: Contract,
|
||||||
|
_: type E,
|
||||||
|
handler: AsyncEventHandler[E]):
|
||||||
|
Future[Subscription] =
|
||||||
|
|
||||||
|
let topic = topic($E, E.fieldTypes).toArray
|
||||||
|
let filter = Filter(address: contract.address, topics: @[topic])
|
||||||
|
|
||||||
|
proc logHandler(log: Log) {.async, upraises: [].} =
|
||||||
|
if event =? E.decode(log.data, log.topics):
|
||||||
|
await handler(event)
|
||||||
|
|
||||||
|
contract.provider.subscribe(filter, logHandler)
|
||||||
|
|||||||
@ -41,6 +41,7 @@ type
|
|||||||
cumulativeGasUsed*: UInt256
|
cumulativeGasUsed*: UInt256
|
||||||
status*: TransactionStatus
|
status*: TransactionStatus
|
||||||
LogHandler* = proc(log: Log) {.gcsafe, upraises:[].}
|
LogHandler* = proc(log: Log) {.gcsafe, upraises:[].}
|
||||||
|
AsyncLogHandler* = proc(log: Log): Future[void] {.gcsafe, upraises:[].}
|
||||||
BlockHandler* = proc(blck: Block): Future[void] {.gcsafe, upraises:[].}
|
BlockHandler* = proc(blck: Block): Future[void] {.gcsafe, upraises:[].}
|
||||||
Topic* = array[32, byte]
|
Topic* = array[32, byte]
|
||||||
Block* = object
|
Block* = object
|
||||||
@ -94,6 +95,12 @@ method subscribe*(provider: Provider,
|
|||||||
Future[Subscription] {.base.} =
|
Future[Subscription] {.base.} =
|
||||||
doAssert false, "not implemented"
|
doAssert false, "not implemented"
|
||||||
|
|
||||||
|
method subscribe*(provider: Provider,
|
||||||
|
filter: Filter,
|
||||||
|
callback: AsyncLogHandler):
|
||||||
|
Future[Subscription] {.base.} =
|
||||||
|
doAssert false, "not implemented"
|
||||||
|
|
||||||
method subscribe*(provider: Provider,
|
method subscribe*(provider: Provider,
|
||||||
callback: BlockHandler):
|
callback: BlockHandler):
|
||||||
Future[Subscription] {.base.} =
|
Future[Subscription] {.base.} =
|
||||||
|
|||||||
@ -195,6 +195,15 @@ method subscribe*(provider: JsonRpcProvider,
|
|||||||
callback(log)
|
callback(log)
|
||||||
return await provider.subscribe("logs", filter.some, handler)
|
return await provider.subscribe("logs", filter.some, handler)
|
||||||
|
|
||||||
|
method subscribe*(provider: JsonRpcProvider,
|
||||||
|
filter: Filter,
|
||||||
|
callback: AsyncLogHandler):
|
||||||
|
Future[Subscription] {.async.} =
|
||||||
|
proc handler(id, arguments: JsonNode) {.async.} =
|
||||||
|
if log =? Log.fromJson(arguments["result"]).catch:
|
||||||
|
await callback(log)
|
||||||
|
return await provider.subscribe("logs", filter.some, handler)
|
||||||
|
|
||||||
method subscribe*(provider: JsonRpcProvider,
|
method subscribe*(provider: JsonRpcProvider,
|
||||||
callback: BlockHandler):
|
callback: BlockHandler):
|
||||||
Future[Subscription] {.async.} =
|
Future[Subscription] {.async.} =
|
||||||
|
|||||||
@ -163,6 +163,24 @@ suite "Contracts":
|
|||||||
|
|
||||||
check transfers == @[Transfer(receiver: accounts[0], value: 100.u256)]
|
check transfers == @[Transfer(receiver: accounts[0], value: 100.u256)]
|
||||||
|
|
||||||
|
|
||||||
|
test "supports async event handlers in subscriptions":
|
||||||
|
var transfers: seq[Transfer]
|
||||||
|
|
||||||
|
proc handleTransfer(transfer: Transfer) {.async.} =
|
||||||
|
await sleepAsync(1.milliseconds)
|
||||||
|
transfers.add(transfer)
|
||||||
|
|
||||||
|
let signer0 = provider.getSigner(accounts[0])
|
||||||
|
|
||||||
|
let subscription = await token.subscribe(Transfer, handleTransfer)
|
||||||
|
discard await token.connect(signer0).mint(accounts[0], 100.u256)
|
||||||
|
await subscription.unsubscribe()
|
||||||
|
|
||||||
|
check transfers == @[
|
||||||
|
Transfer(receiver: accounts[0], value: 100.u256)
|
||||||
|
]
|
||||||
|
|
||||||
test "can wait for contract interaction tx to be mined":
|
test "can wait for contract interaction tx to be mined":
|
||||||
# must not be awaited so we can get newHeads inside of .wait
|
# must not be awaited so we can get newHeads inside of .wait
|
||||||
let futMined = provider.mineBlocks(10)
|
let futMined = provider.mineBlocks(10)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user