> For the complete documentation index, see [llms.txt](https://docs.peach.ag/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.peach.ag/documentation/bsc/aggregator/editor/delegated-execution-with-permit2-witness.md).

# Delegated Swaps

Use Permit2 Witness when the payer and executor are different accounts.

The payer supplies ERC20 input and signs authorization; a different executor submits the swap and pays gas. Set an explicit recipient. The SDK supports native BNB output, but not native input.

<table><thead><tr><th width="218.75">Step</th><th>Public method</th><th>Required inputs / result</th></tr></thead><tbody><tr><td>Prepare</td><td><code>prepareDelegatedSwap(params)</code></td><td><code>from</code>, <code>target</code>, <code>amount</code>, different <code>payer</code> and <code>executor</code>, and explicit <code>recipient</code>; returns <code>PAYER_SIGNATURE_REQUIRED</code></td></tr><tr><td>Check ERC20 allowance</td><td><code>checkPermit2BaseAllowance(params)</code></td><td><code>payer</code>, <code>token</code>, <code>requiredAmount</code>; returns <code>{ allowance, sufficient }</code></td></tr><tr><td>Sign</td><td><code>signPayerAuthorization(prepared, payerSigner)</code></td><td>Signer must match the prepared payer; returns the Witness signature</td></tr><tr><td>Build</td><td><code>buildDelegatedSwap(prepared, payerSignature)</code></td><td>Returns a <code>ReadyDelegatedSwap</code> with status <code>TRANSACTION_READY</code></td></tr><tr><td>Simulate / submit</td><td><code>simulateSwap(ready)</code> / <code>executeSwap(ready, executorSigner)</code></td><td>Uses the built transaction; submission signer must match the executor</td></tr></tbody></table>

The preparation amount field is `amount`, and routing fields `providers`, `depth` and `splitCount` are top-level inputs. `prepareSwap()` selects this same mode when payer differs from executor; `prepareDelegatedSwap()` rejects equal addresses.

Start with the display-quote step in [Quickstart](https://docs.peach.ag/documentation/bsc/aggregator/quickstart). The examples below use the same `client`, token pair and input `amount`, plus separate `payerSigner` and `executorSigner` connected to BSC. Import `ethers` from `ethers` and `PERMIT2_ADDRESS` from `@masterpeach/aggregator-sdk` for the authorization step.

### 1. Prepare the swap

Run this after the user chooses to trade.

```typescript
const payer = await payerSigner.getAddress();
const executor = await executorSigner.getAddress();
const prepared = await client.prepareDelegatedSwap({
  from: tokenIn, target: tokenOut, amount, payer, executor, recipient,
  slippageBps: 50, // 0.5%
  deadlineSecs: 300,
});
if (prepared.amountIn !== amount) throw new Error("Prepared input differs from the order");
```

Before signing, have the payer review `prepared.amountIn`, `prepared.expectAmountOut`, payer, executor, recipient, `prepared.payerAuthorization.deadline` and the requested slippage. `slippageBps: 50` means **0.5%**; use the user's chosen tolerance. Preparation searches again, so its expected output may differ from the preview.

**Signing authorizes execution.** Once shared, the signature lets the designated executor submit while the plan remains valid. A later UI confirmation cannot revoke it.

Preparation exposes the plan hash and authorization. The full transaction and signed minimum output become available only after build. Showing the payer that exact minimum before signing requires additional API support.

### 2. Approve, sign, and build

```typescript
const allowance = await client.checkPermit2BaseAllowance({
  payer: prepared.payer, token: prepared.tokenIn, requiredAmount: prepared.amountIn,
});
if (!allowance.sufficient) {
  const token = new ethers.Interface(["function approve(address,uint256) returns (bool)"]);
  const approvalTx = await payerSigner.sendTransaction({
    to: prepared.tokenIn,
    data: token.encodeFunctionData("approve", [PERMIT2_ADDRESS, prepared.amountIn]),
  });
  if ((await approvalTx.wait())?.status !== 1) throw new Error("Approval failed");
}
const signature = await client.signPayerAuthorization(prepared, payerSigner);
const ready = await client.buildDelegatedSwap(prepared, signature);
console.log("Expected output:", ethers.formatUnits(ready.execution.plan.expectedAmountOut, outputDecimals));
console.log("Minimum received:", ethers.formatUnits(ready.tx.amountOutMin, outputDecimals));
```

The approval transaction is sent to the input ERC20 contract, granting canonical Permit2 permission to spend the exact prepared amount. The following Witness authorization is an EIP-712 message signature binding the plan to the Execution Router.

Build returns `TRANSACTION_READY`. Before submission, display the built expected output and `ready.tx.amountOutMin` using `outputDecimals`. This review controls your application's submission; the payer has already authorized execution. Do not deduct slippage again or edit the transaction.

The built result retains the original preparation as `ready.prepared`. Read its token and amount metadata there; signed execution values are in `ready.execution.plan`.

### 3. Execute the swap

```typescript
if (ready.execution.plan.deadline <= BigInt(Math.floor(Date.now() / 1000))) {
  throw new Error("Plan expired; prepare again and obtain a new signature");
}
const tx = await client.executeSwap(ready, executorSigner);
console.log("Transaction hash:", tx.hash);
const receipt = await tx.wait();
if (receipt?.status !== 1) throw new Error("Swap failed");
```

Optionally call `client.simulateSwap(ready, ready.executor)` before submission. It requires the payer's input balance and confirmed base allowance. The executor needs BNB for gas.

### Expired plans and retries

The SDK revalidates expiry before signing and building. If the plan expires, prepare again and obtain a new payer signature. Repreparing does not revoke a previous signature. See [Transaction Safety](https://docs.peach.ag/documentation/bsc/aggregator/editor/validation-approvals-and-expiry) for input changes and allowance reuse, and [Client Configuration](https://docs.peach.ag/documentation/bsc/aggregator/editor/configuration-and-error-handling) for failures and uncertain submissions.

The current SDK accepts only 64-byte compact or 65-byte payer signatures. Do not assume general ERC-1271 smart-contract-wallet compatibility; it has not been established for this workflow.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.peach.ag/documentation/bsc/aggregator/editor/delegated-execution-with-permit2-witness.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
