mirror of
https://github.com/logos-storage/nim-ethers.git
synced 2026-01-02 13:43:06 +00:00
87 lines
2.4 KiB
Nim
87 lines
2.4 KiB
Nim
import std/macros
|
|
import ../errors/conversion
|
|
import ./syntax
|
|
import ./transactions
|
|
|
|
func getErrorTypes(procedure: NimNode): NimNode =
|
|
let pragmas = procedure[4]
|
|
var tupl = newNimNode(nnkTupleConstr)
|
|
for pragma in pragmas:
|
|
if pragma.kind == nnkExprColonExpr:
|
|
if pragma[0].eqIdent "errors":
|
|
pragma[1].expectKind(nnkBracket)
|
|
for error in pragma[1]:
|
|
tupl.add error
|
|
if tupl.len == 0:
|
|
quote do: tuple[]
|
|
else:
|
|
tupl
|
|
|
|
func addContractCall(procedure: var NimNode) =
|
|
let contractCall = getContractCall(procedure)
|
|
let returnType = procedure.params[0]
|
|
let isGetter = procedure.isGetter
|
|
|
|
let errors = getErrorTypes(procedure)
|
|
|
|
func call: NimNode =
|
|
if returnType.kind == nnkEmpty:
|
|
quote:
|
|
await callTransaction(`contractCall`)
|
|
elif returnType.isMultipleReturn or isGetter:
|
|
quote:
|
|
return await callTransaction(`contractCall`, `returnType`)
|
|
else:
|
|
quote:
|
|
# solidity functions return a tuple, so wrap return type in a tuple
|
|
let tupl = await callTransaction(`contractCall`, (`returnType`,))
|
|
return tupl[0]
|
|
|
|
func send: NimNode =
|
|
if returnType.kind == nnkEmpty:
|
|
quote:
|
|
discard await sendTransaction(`contractCall`)
|
|
else:
|
|
quote:
|
|
when typeof(result) isnot Confirmable:
|
|
{.error:
|
|
"unexpected return type, " &
|
|
"missing {.view.}, {.pure.} or {.getter.} ?"
|
|
.}
|
|
let response = await sendTransaction(`contractCall`)
|
|
let convert = customErrorConversion(`errors`)
|
|
Confirmable(response: response, convert: convert)
|
|
|
|
procedure.body =
|
|
if procedure.isConstant:
|
|
call()
|
|
else:
|
|
send()
|
|
|
|
func addErrorHandling(procedure: var NimNode) =
|
|
let body = procedure[6]
|
|
let errors = getErrorTypes(procedure)
|
|
procedure.body = quote do:
|
|
try:
|
|
`body`
|
|
except ProviderError as error:
|
|
if data =? error.data:
|
|
let convert = customErrorConversion(`errors`)
|
|
raise convert(error)
|
|
else:
|
|
raise error
|
|
|
|
func addFuture(procedure: var NimNode) =
|
|
let returntype = procedure[3][0]
|
|
if returntype.kind != nnkEmpty:
|
|
procedure[3][0] = quote: Future[`returntype`]
|
|
|
|
func createContractFunction*(procedure: NimNode): NimNode =
|
|
result = copyNimTree(procedure)
|
|
result.addOverridesParameter()
|
|
result.addContractCall()
|
|
result.addErrorHandling()
|
|
result.addFuture()
|
|
result.addAsyncPragma()
|
|
|