Skip to main content
Most zaps go quote → approve → build → send. Some routes need something extra in the middle: a signature from the user that has to exist before DZap can build the transaction, because it gets embedded in the transaction itself. Those are pre-execution steps. A borrow is the usual example. The zap contract borrows on the user’s behalf, and a lending market won’t let anyone take on debt in someone’s name without permission. On Aave v3 that permission is a credit-delegation signature (DelegationWithSig). In plain terms it says “the DZap zap contract may borrow up to this much USDC against my account, until this deadline.” DZap can’t produce that signature itself, and the transaction can’t exist without it, so the quote asks for it first.

How it works

  1. The quote comes back with preExecutionSteps, a list of things to sign. Quotes never need the signatures, so you can show a quote before asking the user for anything.
  2. You have the user sign each one.
  3. You send the signatures back as preExecutionStepsData on the build request. The build puts them into the transaction.
prepareZapPreExecutionData asks the wallet to sign each step’s typed data, one at a time and in order. On success, preExecutionStepsData holds { id, type, signature, message } for every step, which is exactly what the build expects. If the quote asked for nothing, you get success with an empty list, so you can call it on every quote without checking first. It doesn’t throw. Like approve() and zap(), it returns a result with a status. If the user cancels a signature you get status: 'rejected', and any other failure comes back as error, both with an errorMsg you can show and a code. It stops at the first step that fails, so a partial list never reaches the build.
If you don’t need to show anything between signing and sending, zap() can do all of it in one call. Pass the request and preExecutionSteps: quote.preExecutionSteps, leave out steps, and it signs, builds and sends.

Types

All exported from @dzapio/sdk.
preExecutionStepsData is accepted on both ZapBundleRequest and ZapBuildTxnRequest, so single zaps can use it as well as bundles.

Things to know before you ship it

  • It’s a signature, not a transaction. No gas, and the wallet shows it as a typed-data request. Nothing happens on-chain until the built transaction is sent.
  • Sign everything in the list, and don’t count on its length. An Aave v3 borrow asks for one signature today. Other markets ask for their own (Aave v4 and Morpho each have an authorization), and most routes return an empty list. If your code loops over whatever comes back, it keeps working when that changes.
  • The signature can pin parts of the route. For an Aave borrow, the signed message.value is the amount the build borrows. Change destAmount between quote and build and the build is rejected. Quote again and sign again.
  • It expires. The Aave delegation is valid for an hour and tied to the user’s current delegation nonce on that debt token, so any other delegation signed in the meantime invalidates it. Ask for the signature when the user is about to confirm, not when the page loads, and don’t reuse it for a later transaction.
  • Building without it fails. The build won’t fall back to something else. It errors until the signatures are there.

Without the SDK

Over REST, the quote returns the same list in data.preExecutionSteps. Each sign step’s data is a ready-made EIP-712 payload (domain, types, primaryType, message). Pass it to eth_signTypedData_v4, or to viem’s signTypedData, and add this to the build body:
Send the message back exactly as you received it, without rebuilding it. The backend reads values like the amount and deadline from it, and anything that differs from what was signed invalidates the signature.

Errors

  • No signature provided for borrow delegation: the build had no preExecutionStepsData, or it had signatures from a different quote. Sign what the latest quote returned.
  • Signed credit delegation (…) does not match the borrow amount: the signed amount and the built amount differ. Either destAmount changed after signing, or you left destAmount out and the maximum dropped below what was signed. Quote and sign again.
  • The signature stopped working after a while: it expired, or another delegation used up its nonce. Quote again right before asking the user to sign.
For a full walkthrough of both borrow flows, see the Borrow recipe.
Last modified on October 10, 2026