basically I want wrap new proc takes same args except first arg and return same results as original procs,
all procs wraps as same logic, the original takes type A as self, the new version takes type B as self, in the proc body add few lines and call original proc,
the way 1: just make a macro that takes typed proc
well, it doesn't work.
on the 1.2.6 it shows Error: illformed AST
on the devel branch it shows Error: Expected one of {nnkLambda, nnkDo, nnkProcDef, nnkMethodDef, nnkConverterDef, nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkFuncDef}, got nnkSym
https://play.nim-lang.org/#ix=2zg8
import macros
import asyncdispatch
proc hello(){.async.} = discard
macro wrapApi(prc:typed):untyped =
 result = prc.getImpl
 result.name = ident"abc"
wrapApi(hello)
the way 2 :
wraps it as template
https://play.nim-lang.org/#ix=2zgw
well, it can't resolve the await
macro wraps(): untyped =
  result = nnkStmtList.newTree()
  for api in ["rawQuery"]:
    let id = ident(api)
    let conId = ident("conIdx")
    let args = ident("args")
    let r = ident("result")
    let prc = nnkTemplateDef.newTree(
        nnkPostfix.newTree(
          newIdentNode("*"),
          id
        ),
the way 3:
make the macro as a pragma that attach to original proc, turn it to original version and wrapped version, that maybe work, but I really dont want to touch original code.
I'm not 100% sure what you are trying to do, but this works:
import macros, asyncdispatch
proc duplicateAndModifyArg (prc: NimNode): NimNode {.compileTime.} =
  result = newStmtList()
  let prc2 = copyNimTree(prc)
  
  prc2[3][1][1] = newIdentNode("string")
  
  result.add prc
  result.add prc2
macro wraps* (prc: untyped) =
  ## generate a copy of the provided proc which replaces first argument type
  result = duplicateAndModifyArg(prc)
proc hello (arg1: int): Future[string] {.wraps, async.} =
  result = $arg1
echo "old proc: ", waitFor hello(31)
echo "new proc: ", waitFor hello("hello world ")