# Transaction Steps

## Introduction

Some product purchases may require more than one transaction to complete. For example, Edition products configured with ERC20 payments require:

1. **ERC20 spend approval**: Grant contract permission to spend user tokens
2. **Mint**: Execute the actual purchase transaction

Other scenarios include cross-chain purchases (bridge, then mint) or batch operations.

## Execution Methods

### 1. Built-in Execution (Recommended)

For **user-facing apps**, the SDK separates transactions into explicit steps. This gives you:

* Progress tracking for multi-step flows
* Fine-grained error handling per transaction
* Safer UX - users approve each step individually

The [preparePurchase](/client-sdk/sdk/product/blind-mint/preparepurchase.md) function returns [TransactionStep](/client-sdk/sdk/transaction-steps.md) objects. Call [execute](/client-sdk/sdk/transaction-steps/execute.md) on each step to submit the transaction. The SDK automatically skips unnecessary steps (e.g., if approval is already granted).

For **server-side apps** or **agentic flows**, call [purchase](/client-sdk/sdk/product/common/purchase.md) directly and the SDK handles all transactions sequentially without explicit step management.

### 2. Custom Execution with transactionData

Each `TransactionStep` includes a [transactionData](https://github.com/manifoldxyz/client-sdk/blob/main/packages/client-sdk/docs/sdk/transaction-steps/transactionData.md) field containing raw blockchain transaction data. This enables custom transaction execution for advanced use cases:

* **EIP-7702 Support**: Account abstraction and smart contract wallets
* **Custom Gas Management**: Implement your own gas strategies
* **Transaction Infrastructure**: Integrate with existing systems
* **Batch Transactions**: Combine multiple transactions
* **Custom Error Handling**: Implement retry logic

Example:

```typescript
// Prepare purchase normally
const preparedPurchase = await product.preparePurchase({
  userAddress: walletAddress,
  payload: { quantity: 1 }
});

// Execute with custom logic
for (const step of preparedPurchase.steps) {
  const { contractAddress, transactionData, value, gasEstimate } = step.transactionData;
  
  // Use your preferred Web3 library
  const txHash = await walletClient.sendTransaction({
    to: contractAddress,
    data: transactionData,
    value: value,
    gas: gasEstimate * 110n / 100n, // Custom gas buffer
  });
}
```

## Available Documentation

* [execute](/client-sdk/sdk/transaction-steps/execute.md) - Built-in execution method for transaction steps
* [TransactionData](/client-sdk/reference/transactiondata.md) - Raw transaction data for custom execution


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.manifold.xyz/client-sdk/sdk/transaction-steps.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
