> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spark.money/llms.txt
> Use this file to discover all available pages before exploring further.

# optimizeLeaves

> Manually optimize leaf structure for faster transfers.

Manually optimizes wallet leaf structure by consolidating or splitting leaves into power-of-2 denominations. This is an async generator that yields progress updates and can be interrupted between steps.

<Info>
  For background on leaf optimization concepts, multiplicity levels, and tradeoffs, see [Leaf Optimization](/api-reference/wallet/initialize#leaf-optimization) in the initialize docs.
</Info>

## When to Use

Use this method when you've configured **manual mode** (`auto: false`) in your initialization options. In manual mode, the SDK won't optimize automatically—you control exactly when optimization runs.

```typescript theme={null}
// Initialize with manual mode
const { wallet } = await SparkWallet.initialize({
  options: {
    network: "MAINNET",
    optimizationOptions: {
      auto: false,
      multiplicity: 5
    }
  }
});

// Then call optimizeLeaves() explicitly
for await (const progress of wallet.optimizeLeaves()) {
  console.log(`Optimizing: ${progress.step}/${progress.total}`);
}
```

<Note>
  In **auto mode** (default), the SDK handles optimization automatically. You typically don't need to call this method directly.
</Note>

## Method Signature

```typescript theme={null}
async *optimizeLeaves(
  multiplicity?: number
): AsyncGenerator<{
  step: number;
  total: number;
  controller: AbortController;
}>
```

## Parameters

<ResponseField name="multiplicity" type="number">
  Optimization multiplicity (0-5). Defaults to the value set in `optimizationOptions` during initialization.
</ResponseField>

## Yields

<ResponseField name="progress" type="object" required>
  Progress object containing:

  * `step`: Current step number
  * `total`: Total number of steps
  * `controller`: AbortController to cancel optimization between steps
</ResponseField>

## Interrupting Optimization

The abort controller lets you pause optimization between steps—useful when the user wants to send a payment mid-optimization.

```typescript theme={null}
let optimizeGenerator = wallet.optimizeLeaves();

async function runOptimization() {
  for await (const progress of optimizeGenerator) {
    console.log(`Step ${progress.step} of ${progress.total}`);

    // User wants to send payment - abort optimization
    if (userWantsToSend) {
      progress.controller.abort();
      break;
    }
  }
}

// Start optimization
runOptimization();

// Later: user triggers a send
userWantsToSend = true;
await wallet.transfer({ ... });

// Resume optimization after the transfer
runOptimization();
```

<Warning>
  Optimization runs multiple swap operations with the SSP. If you abort mid-optimization, the wallet remains in a valid state but may not be fully optimized. You can resume optimization later.
</Warning>

## Example: Basic Usage

```typescript theme={null}
for await (const progress of wallet.optimizeLeaves()) {
  console.log(`Step ${progress.step} of ${progress.total}`);
}
console.log("Optimization complete");
```

## Example: With Progress UI

```typescript theme={null}
async function optimizeWithProgress() {
  const progressBar = showProgressBar();

  try {
    for await (const { step, total } of wallet.optimizeLeaves(5)) {
      progressBar.update(step / total * 100);
    }
    progressBar.complete();
  } catch (error) {
    progressBar.error("Optimization failed");
    throw error;
  }
}
```
