mirror of
https://github.com/logos-storage/nim-ethers.git
synced 2026-01-02 13:43:06 +00:00
fix(async): propagate async cancellation (#105)
* fix(async): propagate CancelledErrors * remove CatchableError from contract macro async raises list * remove mistakenly added ContractError
This commit is contained in:
parent
26342d3e27
commit
d2b11a8657
@ -19,6 +19,8 @@ export events
|
||||
export errors.SolidityError
|
||||
export errors.errors
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
logScope:
|
||||
topics = "ethers contract"
|
||||
|
||||
@ -48,10 +50,10 @@ func new*(ContractType: type Contract,
|
||||
|
||||
func new*(ContractType: type Contract,
|
||||
address: Address,
|
||||
signer: Signer): ContractType =
|
||||
signer: Signer): ContractType {.raises: [SignerError].} =
|
||||
ContractType(signer: some signer, provider: signer.provider, address: address)
|
||||
|
||||
func connect*[T: Contract](contract: T, provider: Provider | Signer): T =
|
||||
func connect*[T: Contract](contract: T, provider: Provider | Signer): T {.raises: [SignerError].} =
|
||||
T.new(contract.address, provider)
|
||||
|
||||
func provider*(contract: Contract): Provider =
|
||||
@ -83,24 +85,25 @@ proc createTransaction(contract: Contract,
|
||||
gasLimit: overrides.gasLimit,
|
||||
)
|
||||
|
||||
proc decodeResponse(T: type, bytes: seq[byte]): T =
|
||||
proc decodeResponse(T: type, bytes: seq[byte]): T {.raises: [ContractError].} =
|
||||
without decoded =? AbiDecoder.decode(bytes, T):
|
||||
raiseContractError "unable to decode return value as " & $T
|
||||
return decoded
|
||||
|
||||
proc call(provider: Provider,
|
||||
transaction: Transaction,
|
||||
overrides: TransactionOverrides): Future[seq[byte]] {.async: (raises: [ProviderError]).} =
|
||||
if overrides of CallOverrides and
|
||||
blockTag =? CallOverrides(overrides).blockTag:
|
||||
proc call(
|
||||
provider: Provider, transaction: Transaction, overrides: TransactionOverrides
|
||||
): Future[seq[byte]] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
if overrides of CallOverrides and blockTag =? CallOverrides(overrides).blockTag:
|
||||
await provider.call(transaction, blockTag)
|
||||
else:
|
||||
await provider.call(transaction)
|
||||
|
||||
proc call(contract: Contract,
|
||||
function: string,
|
||||
parameters: tuple,
|
||||
overrides = TransactionOverrides()) {.async: (raises: [ProviderError, SignerError]).} =
|
||||
proc call(
|
||||
contract: Contract,
|
||||
function: string,
|
||||
parameters: tuple,
|
||||
overrides = TransactionOverrides(),
|
||||
) {.async: (raises: [ProviderError, SignerError, CancelledError]).} =
|
||||
var transaction = createTransaction(contract, function, parameters, overrides)
|
||||
|
||||
if signer =? contract.signer and transaction.sender.isNone:
|
||||
@ -108,11 +111,15 @@ proc call(contract: Contract,
|
||||
|
||||
discard await contract.provider.call(transaction, overrides)
|
||||
|
||||
proc call(contract: Contract,
|
||||
function: string,
|
||||
parameters: tuple,
|
||||
ReturnType: type,
|
||||
overrides = TransactionOverrides()): Future[ReturnType] {.async: (raises: [ProviderError, SignerError, ContractError]).} =
|
||||
proc call(
|
||||
contract: Contract,
|
||||
function: string,
|
||||
parameters: tuple,
|
||||
ReturnType: type,
|
||||
overrides = TransactionOverrides(),
|
||||
): Future[ReturnType] {.
|
||||
async: (raises: [ProviderError, SignerError, ContractError, CancelledError])
|
||||
.} =
|
||||
var transaction = createTransaction(contract, function, parameters, overrides)
|
||||
|
||||
if signer =? contract.signer and transaction.sender.isNone:
|
||||
@ -126,7 +133,7 @@ proc send(
|
||||
function: string,
|
||||
parameters: tuple,
|
||||
overrides = TransactionOverrides()
|
||||
): Future[?TransactionResponse] {.async: (raises: [AsyncLockError, CancelledError, CatchableError]).} =
|
||||
): Future[?TransactionResponse] {.async: (raises: [AsyncLockError, SignerError, ProviderError, CancelledError]).} =
|
||||
|
||||
if signer =? contract.signer:
|
||||
withLock(signer):
|
||||
@ -263,10 +270,22 @@ func addAsyncPragma(procedure: var NimNode) =
|
||||
let pragmas = procedure[4]
|
||||
if pragmas.kind == nnkEmpty:
|
||||
procedure[4] = newNimNode(nnkPragma)
|
||||
procedure[4].add ident("async")
|
||||
|
||||
macro contract*(procedure: untyped{nkProcDef|nkMethodDef}): untyped =
|
||||
procedure[4].add nnkExprColonExpr.newTree(
|
||||
newIdentNode("async"),
|
||||
nnkTupleConstr.newTree(
|
||||
nnkExprColonExpr.newTree(
|
||||
newIdentNode("raises"),
|
||||
nnkBracket.newTree(
|
||||
newIdentNode("CancelledError"),
|
||||
newIdentNode("ProviderError"),
|
||||
newIdentNode("EthersError"),
|
||||
newIdentNode("AsyncLockError"),
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
macro contract*(procedure: untyped{nkProcDef | nkMethodDef}): untyped =
|
||||
let parameters = procedure[3]
|
||||
let body = procedure[6]
|
||||
|
||||
|
||||
@ -102,96 +102,85 @@ func toTransaction*(past: PastTransaction): Transaction =
|
||||
)
|
||||
|
||||
method getBlockNumber*(
|
||||
provider: Provider): Future[UInt256] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider
|
||||
): Future[UInt256] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method getBlock*(
|
||||
provider: Provider,
|
||||
tag: BlockTag): Future[?Block] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider, tag: BlockTag
|
||||
): Future[?Block] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method call*(
|
||||
provider: Provider,
|
||||
tx: Transaction,
|
||||
blockTag = BlockTag.latest): Future[seq[byte]] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider, tx: Transaction, blockTag = BlockTag.latest
|
||||
): Future[seq[byte]] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method getGasPrice*(
|
||||
provider: Provider): Future[UInt256] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider
|
||||
): Future[UInt256] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method getTransactionCount*(
|
||||
provider: Provider,
|
||||
address: Address,
|
||||
blockTag = BlockTag.latest): Future[UInt256] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider, address: Address, blockTag = BlockTag.latest
|
||||
): Future[UInt256] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method getTransaction*(
|
||||
provider: Provider,
|
||||
txHash: TransactionHash): Future[?PastTransaction] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider, txHash: TransactionHash
|
||||
): Future[?PastTransaction] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method getTransactionReceipt*(
|
||||
provider: Provider,
|
||||
txHash: TransactionHash): Future[?TransactionReceipt] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider, txHash: TransactionHash
|
||||
): Future[?TransactionReceipt] {.
|
||||
base, async: (raises: [ProviderError, CancelledError])
|
||||
.} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method sendTransaction*(
|
||||
provider: Provider,
|
||||
rawTransaction: seq[byte]): Future[TransactionResponse] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider, rawTransaction: seq[byte]
|
||||
): Future[TransactionResponse] {.
|
||||
base, async: (raises: [ProviderError, CancelledError])
|
||||
.} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method getLogs*(
|
||||
provider: Provider,
|
||||
filter: EventFilter): Future[seq[Log]] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider, filter: EventFilter
|
||||
): Future[seq[Log]] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method estimateGas*(
|
||||
provider: Provider,
|
||||
transaction: Transaction,
|
||||
blockTag = BlockTag.latest): Future[UInt256] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider, transaction: Transaction, blockTag = BlockTag.latest
|
||||
): Future[UInt256] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method getChainId*(
|
||||
provider: Provider): Future[UInt256] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider
|
||||
): Future[UInt256] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method subscribe*(
|
||||
provider: Provider,
|
||||
filter: EventFilter,
|
||||
callback: LogHandler): Future[Subscription] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider, filter: EventFilter, callback: LogHandler
|
||||
): Future[Subscription] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method subscribe*(
|
||||
provider: Provider,
|
||||
callback: BlockHandler): Future[Subscription] {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: Provider, callback: BlockHandler
|
||||
): Future[Subscription] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method unsubscribe*(
|
||||
subscription: Subscription) {.base, async: (raises:[ProviderError]).} =
|
||||
|
||||
subscription: Subscription
|
||||
) {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method isSyncing*(provider: Provider): Future[bool] {.base, async.} =
|
||||
method isSyncing*(provider: Provider): Future[bool] {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
proc replay*(
|
||||
provider: Provider,
|
||||
tx: Transaction,
|
||||
blockNumber: UInt256) {.async: (raises:[ProviderError]).} =
|
||||
provider: Provider, tx: Transaction, blockNumber: UInt256
|
||||
) {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
# Replay transaction at block. Useful for fetching revert reasons, which will
|
||||
# be present in the raised error message. The replayed block number should
|
||||
# include the state of the chain in the block previous to the block in which
|
||||
@ -203,8 +192,8 @@ proc replay*(
|
||||
discard await provider.call(tx, BlockTag.init(blockNumber))
|
||||
|
||||
proc ensureSuccess(
|
||||
provider: Provider,
|
||||
receipt: TransactionReceipt) {.async: (raises: [ProviderError]).} =
|
||||
provider: Provider, receipt: TransactionReceipt
|
||||
) {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
## If the receipt.status is Failed, the tx is replayed to obtain a revert
|
||||
## reason, after which a ProviderError with the revert reason is raised.
|
||||
## If no revert reason was obtained
|
||||
@ -252,7 +241,7 @@ proc confirm*(
|
||||
if number > blockNumber:
|
||||
blockNumber = number
|
||||
blockEvent.fire()
|
||||
except ProviderError:
|
||||
except ProviderError, CancelledError:
|
||||
# there's nothing we can do here
|
||||
discard
|
||||
|
||||
@ -312,5 +301,7 @@ proc confirm*(
|
||||
let txResp = await tx
|
||||
return await txResp.confirm(confirmations, timeout)
|
||||
|
||||
method close*(provider: Provider) {.base, async: (raises:[ProviderError]).} =
|
||||
method close*(
|
||||
provider: Provider
|
||||
) {.base, async: (raises: [ProviderError, CancelledError]).} =
|
||||
discard
|
||||
|
||||
@ -56,7 +56,7 @@ proc new*(
|
||||
var client: RpcClient
|
||||
var subscriptions: JsonRpcSubscriptions
|
||||
|
||||
proc initialize {.async: (raises:[JsonRpcProviderError]).} =
|
||||
proc initialize() {.async: (raises: [JsonRpcProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
case parseUri(url).scheme
|
||||
of "ws", "wss":
|
||||
@ -72,12 +72,16 @@ proc new*(
|
||||
pollingInterval = pollingInterval)
|
||||
subscriptions.start()
|
||||
|
||||
proc awaitClient: Future[RpcClient] {.async:(raises:[JsonRpcProviderError]).} =
|
||||
proc awaitClient(): Future[RpcClient] {.
|
||||
async: (raises: [JsonRpcProviderError, CancelledError])
|
||||
.} =
|
||||
convertError:
|
||||
await initialized
|
||||
return client
|
||||
|
||||
proc awaitSubscriptions: Future[JsonRpcSubscriptions] {.async:(raises:[JsonRpcProviderError]).} =
|
||||
proc awaitSubscriptions(): Future[JsonRpcSubscriptions] {.
|
||||
async: (raises: [JsonRpcProviderError, CancelledError])
|
||||
.} =
|
||||
convertError:
|
||||
await initialized
|
||||
return subscriptions
|
||||
@ -86,29 +90,29 @@ proc new*(
|
||||
return JsonRpcProvider(client: awaitClient(), subscriptions: awaitSubscriptions())
|
||||
|
||||
proc callImpl(
|
||||
client: RpcClient,
|
||||
call: string,
|
||||
args: JsonNode): Future[JsonNode] {.async: (raises: [JsonRpcProviderError]).} =
|
||||
|
||||
without response =? (await client.call(call, %args)).catch, error:
|
||||
client: RpcClient, call: string, args: JsonNode
|
||||
): Future[JsonNode] {.async: (raises: [JsonRpcProviderError, CancelledError]).} =
|
||||
try:
|
||||
let response = await client.call(call, %args)
|
||||
without json =? JsonNode.fromJson(response.string), error:
|
||||
raiseJsonRpcProviderError "Failed to parse response '" & response.string & "': " &
|
||||
error.msg
|
||||
return json
|
||||
except CancelledError as error:
|
||||
raise error
|
||||
except CatchableError as error:
|
||||
raiseJsonRpcProviderError error.msg
|
||||
without json =? JsonNode.fromJson(response.string), error:
|
||||
raiseJsonRpcProviderError "Failed to parse response: " & error.msg
|
||||
json
|
||||
|
||||
proc send*(
|
||||
provider: JsonRpcProvider,
|
||||
call: string,
|
||||
arguments: seq[JsonNode] = @[]): Future[JsonNode]
|
||||
{.async: (raises: [JsonRpcProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider, call: string, arguments: seq[JsonNode] = @[]
|
||||
): Future[JsonNode] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
return await client.callImpl(call, %arguments)
|
||||
|
||||
proc listAccounts*(provider: JsonRpcProvider): Future[seq[Address]]
|
||||
{.async: (raises: [JsonRpcProviderError]).} =
|
||||
|
||||
proc listAccounts*(
|
||||
provider: JsonRpcProvider
|
||||
): Future[seq[Address]] {.async: (raises: [JsonRpcProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
return await client.eth_accounts()
|
||||
@ -120,73 +124,66 @@ proc getSigner*(provider: JsonRpcProvider, address: Address): JsonRpcSigner =
|
||||
JsonRpcSigner(provider: provider, address: some address)
|
||||
|
||||
method getBlockNumber*(
|
||||
provider: JsonRpcProvider): Future[UInt256] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider
|
||||
): Future[UInt256] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
return await client.eth_blockNumber()
|
||||
|
||||
method getBlock*(
|
||||
provider: JsonRpcProvider,
|
||||
tag: BlockTag): Future[?Block] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider, tag: BlockTag
|
||||
): Future[?Block] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
return await client.eth_getBlockByNumber(tag, false)
|
||||
|
||||
method call*(
|
||||
provider: JsonRpcProvider,
|
||||
tx: Transaction,
|
||||
blockTag = BlockTag.latest): Future[seq[byte]] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider, tx: Transaction, blockTag = BlockTag.latest
|
||||
): Future[seq[byte]] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
return await client.eth_call(tx, blockTag)
|
||||
|
||||
method getGasPrice*(
|
||||
provider: JsonRpcProvider): Future[UInt256] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider
|
||||
): Future[UInt256] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
return await client.eth_gasPrice()
|
||||
|
||||
method getTransactionCount*(
|
||||
provider: JsonRpcProvider,
|
||||
address: Address,
|
||||
blockTag = BlockTag.latest): Future[UInt256] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider, address: Address, blockTag = BlockTag.latest
|
||||
): Future[UInt256] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
return await client.eth_getTransactionCount(address, blockTag)
|
||||
|
||||
method getTransaction*(
|
||||
provider: JsonRpcProvider,
|
||||
txHash: TransactionHash): Future[?PastTransaction] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider, txHash: TransactionHash
|
||||
): Future[?PastTransaction] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
return await client.eth_getTransactionByHash(txHash)
|
||||
|
||||
method getTransactionReceipt*(
|
||||
provider: JsonRpcProvider,
|
||||
txHash: TransactionHash): Future[?TransactionReceipt] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider, txHash: TransactionHash
|
||||
): Future[?TransactionReceipt] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
return await client.eth_getTransactionReceipt(txHash)
|
||||
|
||||
method getLogs*(
|
||||
provider: JsonRpcProvider,
|
||||
filter: EventFilter): Future[seq[Log]] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider, filter: EventFilter
|
||||
): Future[seq[Log]] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
let logsJson = if filter of Filter:
|
||||
await client.eth_getLogs(Filter(filter))
|
||||
elif filter of FilterByBlockHash:
|
||||
await client.eth_getLogs(FilterByBlockHash(filter))
|
||||
else:
|
||||
await client.eth_getLogs(filter)
|
||||
let logsJson =
|
||||
if filter of Filter:
|
||||
await client.eth_getLogs(Filter(filter))
|
||||
elif filter of FilterByBlockHash:
|
||||
await client.eth_getLogs(FilterByBlockHash(filter))
|
||||
else:
|
||||
await client.eth_getLogs(filter)
|
||||
|
||||
var logs: seq[Log] = @[]
|
||||
for logJson in logsJson.getElems:
|
||||
@ -196,10 +193,10 @@ method getLogs*(
|
||||
return logs
|
||||
|
||||
method estimateGas*(
|
||||
provider: JsonRpcProvider,
|
||||
transaction: Transaction,
|
||||
blockTag = BlockTag.latest): Future[UInt256] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider,
|
||||
transaction: Transaction,
|
||||
blockTag = BlockTag.latest,
|
||||
): Future[UInt256] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
try:
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
@ -209,24 +206,24 @@ method estimateGas*(
|
||||
msg: "Estimate gas failed: " & error.msg,
|
||||
data: error.data,
|
||||
transaction: transaction,
|
||||
parent: error
|
||||
parent: error,
|
||||
)
|
||||
|
||||
method getChainId*(
|
||||
provider: JsonRpcProvider): Future[UInt256] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider
|
||||
): Future[UInt256] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
try:
|
||||
return await client.eth_chainId()
|
||||
except CancelledError as error:
|
||||
raise error
|
||||
except CatchableError:
|
||||
return parse(await client.net_version(), UInt256)
|
||||
|
||||
method sendTransaction*(
|
||||
provider: JsonRpcProvider,
|
||||
rawTransaction: seq[byte]): Future[TransactionResponse]
|
||||
{.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider, rawTransaction: seq[byte]
|
||||
): Future[TransactionResponse] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let
|
||||
client = await provider.client
|
||||
@ -235,41 +232,40 @@ method sendTransaction*(
|
||||
return TransactionResponse(hash: hash, provider: provider)
|
||||
|
||||
method subscribe*(
|
||||
provider: JsonRpcProvider,
|
||||
filter: EventFilter,
|
||||
onLog: LogHandler): Future[Subscription] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider, filter: EventFilter, onLog: LogHandler
|
||||
): Future[Subscription] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let subscriptions = await provider.subscriptions
|
||||
let id = await subscriptions.subscribeLogs(filter, onLog)
|
||||
return JsonRpcSubscription(subscriptions: subscriptions, id: id)
|
||||
|
||||
method subscribe*(
|
||||
provider: JsonRpcProvider,
|
||||
onBlock: BlockHandler): Future[Subscription] {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider, onBlock: BlockHandler
|
||||
): Future[Subscription] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let subscriptions = await provider.subscriptions
|
||||
let id = await subscriptions.subscribeBlocks(onBlock)
|
||||
return JsonRpcSubscription(subscriptions: subscriptions, id: id)
|
||||
|
||||
method unsubscribe*(
|
||||
subscription: JsonRpcSubscription) {.async: (raises:[ProviderError]).} =
|
||||
|
||||
subscription: JsonRpcSubscription
|
||||
) {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let subscriptions = subscription.subscriptions
|
||||
let id = subscription.id
|
||||
await subscriptions.unsubscribe(id)
|
||||
|
||||
method isSyncing*(provider: JsonRpcProvider): Future[bool] {.async.} =
|
||||
method isSyncing*(
|
||||
provider: JsonRpcProvider
|
||||
): Future[bool] {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
let response = await provider.send("eth_syncing")
|
||||
if response.kind == JsonNodeKind.JObject:
|
||||
return true
|
||||
return response.getBool()
|
||||
|
||||
method close*(
|
||||
provider: JsonRpcProvider) {.async: (raises:[ProviderError]).} =
|
||||
|
||||
provider: JsonRpcProvider
|
||||
) {.async: (raises: [ProviderError, CancelledError]).} =
|
||||
convertError:
|
||||
let client = await provider.client
|
||||
let subscriptions = await provider.subscriptions
|
||||
@ -290,6 +286,8 @@ proc raiseJsonRpcSignerError(
|
||||
template convertSignerError(body) =
|
||||
try:
|
||||
body
|
||||
except CancelledError as error:
|
||||
raise error
|
||||
except JsonRpcError as error:
|
||||
raiseJsonRpcSignerError(error.msg)
|
||||
except CatchableError as error:
|
||||
@ -301,9 +299,8 @@ method provider*(signer: JsonRpcSigner): Provider
|
||||
signer.provider
|
||||
|
||||
method getAddress*(
|
||||
signer: JsonRpcSigner): Future[Address]
|
||||
{.async: (raises:[ProviderError, SignerError]).} =
|
||||
|
||||
signer: JsonRpcSigner
|
||||
): Future[Address] {.async: (raises: [ProviderError, SignerError, CancelledError]).} =
|
||||
if address =? signer.address:
|
||||
return address
|
||||
|
||||
@ -314,19 +311,18 @@ method getAddress*(
|
||||
raiseJsonRpcSignerError "no address found"
|
||||
|
||||
method signMessage*(
|
||||
signer: JsonRpcSigner,
|
||||
message: seq[byte]): Future[seq[byte]] {.async: (raises:[SignerError]).} =
|
||||
|
||||
signer: JsonRpcSigner, message: seq[byte]
|
||||
): Future[seq[byte]] {.async: (raises: [SignerError, CancelledError]).} =
|
||||
convertSignerError:
|
||||
let client = await signer.provider.client
|
||||
let address = await signer.getAddress()
|
||||
return await client.personal_sign(message, address)
|
||||
|
||||
method sendTransaction*(
|
||||
signer: JsonRpcSigner,
|
||||
transaction: Transaction): Future[TransactionResponse]
|
||||
{.async: (raises:[SignerError, ProviderError]).} =
|
||||
|
||||
signer: JsonRpcSigner, transaction: Transaction
|
||||
): Future[TransactionResponse] {.
|
||||
async: (raises: [SignerError, ProviderError, CancelledError])
|
||||
.} =
|
||||
convertError:
|
||||
let
|
||||
client = await signer.provider.client
|
||||
|
||||
@ -40,6 +40,8 @@ proc raiseJsonRpcProviderError*(
|
||||
template convertError*(body) =
|
||||
try:
|
||||
body
|
||||
except CancelledError as error:
|
||||
raise error
|
||||
except JsonRpcError as error:
|
||||
raiseJsonRpcProviderError(error.msg)
|
||||
except CatchableError as error:
|
||||
|
||||
@ -18,6 +18,8 @@ template raiseSignerError*(message: string, parent: ref ProviderError = nil) =
|
||||
template convertError(body) =
|
||||
try:
|
||||
body
|
||||
except CancelledError as error:
|
||||
raise error
|
||||
except ProviderError as error:
|
||||
raise error # do not convert provider errors
|
||||
except CatchableError as error:
|
||||
@ -28,59 +30,61 @@ method provider*(
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method getAddress*(
|
||||
signer: Signer): Future[Address]
|
||||
{.base, async: (raises:[ProviderError, SignerError]).} =
|
||||
|
||||
signer: Signer
|
||||
): Future[Address] {.
|
||||
base, async: (raises: [ProviderError, SignerError, CancelledError])
|
||||
.} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method signMessage*(
|
||||
signer: Signer,
|
||||
message: seq[byte]): Future[seq[byte]]
|
||||
{.base, async: (raises: [SignerError]).} =
|
||||
|
||||
signer: Signer, message: seq[byte]
|
||||
): Future[seq[byte]] {.base, async: (raises: [SignerError, CancelledError]).} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method sendTransaction*(
|
||||
signer: Signer,
|
||||
transaction: Transaction): Future[TransactionResponse]
|
||||
{.base, async: (raises:[SignerError, ProviderError]).} =
|
||||
|
||||
signer: Signer, transaction: Transaction
|
||||
): Future[TransactionResponse] {.
|
||||
base, async: (raises: [SignerError, ProviderError, CancelledError])
|
||||
.} =
|
||||
doAssert false, "not implemented"
|
||||
|
||||
method getGasPrice*(
|
||||
signer: Signer): Future[UInt256]
|
||||
{.base, async: (raises: [ProviderError, SignerError]).} =
|
||||
|
||||
signer: Signer
|
||||
): Future[UInt256] {.
|
||||
base, async: (raises: [ProviderError, SignerError, CancelledError])
|
||||
.} =
|
||||
return await signer.provider.getGasPrice()
|
||||
|
||||
method getTransactionCount*(
|
||||
signer: Signer,
|
||||
blockTag = BlockTag.latest): Future[UInt256]
|
||||
{.base, async: (raises:[SignerError, ProviderError]).} =
|
||||
|
||||
signer: Signer, blockTag = BlockTag.latest
|
||||
): Future[UInt256] {.
|
||||
base, async: (raises: [SignerError, ProviderError, CancelledError])
|
||||
.} =
|
||||
convertError:
|
||||
let address = await signer.getAddress()
|
||||
return await signer.provider.getTransactionCount(address, blockTag)
|
||||
|
||||
method estimateGas*(
|
||||
signer: Signer,
|
||||
transaction: Transaction,
|
||||
blockTag = BlockTag.latest): Future[UInt256]
|
||||
{.base, async: (raises:[SignerError, ProviderError]).} =
|
||||
|
||||
signer: Signer, transaction: Transaction, blockTag = BlockTag.latest
|
||||
): Future[UInt256] {.
|
||||
base, async: (raises: [SignerError, ProviderError, CancelledError])
|
||||
.} =
|
||||
var transaction = transaction
|
||||
transaction.sender = some(await signer.getAddress())
|
||||
return await signer.provider.estimateGas(transaction, blockTag)
|
||||
|
||||
method getChainId*(
|
||||
signer: Signer): Future[UInt256]
|
||||
{.base, async: (raises: [ProviderError, SignerError]).} =
|
||||
|
||||
signer: Signer
|
||||
): Future[UInt256] {.
|
||||
base, async: (raises: [SignerError, ProviderError, CancelledError])
|
||||
.} =
|
||||
return await signer.provider.getChainId()
|
||||
|
||||
method getNonce(
|
||||
signer: Signer): Future[UInt256] {.base, async: (raises: [SignerError, ProviderError]).} =
|
||||
|
||||
signer: Signer
|
||||
): Future[UInt256] {.
|
||||
base, async: (raises: [SignerError, ProviderError, CancelledError])
|
||||
.} =
|
||||
return await signer.getTransactionCount(BlockTag.pending)
|
||||
|
||||
template withLock*(signer: Signer, body: untyped) =
|
||||
|
||||
@ -69,7 +69,7 @@ method provider*(wallet: Wallet): Provider {.gcsafe, raises: [SignerError].} =
|
||||
|
||||
method getAddress*(
|
||||
wallet: Wallet): Future[Address]
|
||||
{.async: (raises:[ProviderError, SignerError]).} =
|
||||
{.async: (raises:[ProviderError, SignerError, CancelledError]).} =
|
||||
|
||||
return wallet.address
|
||||
|
||||
@ -83,7 +83,7 @@ proc signTransaction*(wallet: Wallet,
|
||||
method sendTransaction*(
|
||||
wallet: Wallet,
|
||||
transaction: Transaction): Future[TransactionResponse]
|
||||
{.async: (raises:[SignerError, ProviderError]).} =
|
||||
{.async: (raises:[SignerError, ProviderError, CancelledError]).} =
|
||||
|
||||
let signed = await signTransaction(wallet, transaction)
|
||||
return await provider(wallet).sendTransaction(signed)
|
||||
|
||||
@ -9,5 +9,7 @@ func raiseWalletError*(message: string) {.raises: [WalletError].}=
|
||||
template convertError*(body) =
|
||||
try:
|
||||
body
|
||||
except CancelledError as error:
|
||||
raise error
|
||||
except CatchableError as error:
|
||||
raiseWalletError(error.msg)
|
||||
|
||||
@ -13,13 +13,13 @@ method provider*(signer: MockSigner): Provider =
|
||||
|
||||
method getAddress*(
|
||||
signer: MockSigner): Future[Address]
|
||||
{.async: (raises:[ProviderError, SignerError]).} =
|
||||
{.async: (raises:[ProviderError, SignerError, CancelledError]).} =
|
||||
|
||||
return signer.address
|
||||
|
||||
method sendTransaction*(
|
||||
signer: MockSigner,
|
||||
transaction: Transaction): Future[TransactionResponse]
|
||||
{.async: (raises:[SignerError, ProviderError]).} =
|
||||
{.async: (raises:[SignerError, ProviderError, CancelledError]).} =
|
||||
|
||||
signer.transactions.add(transaction)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user