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

# Advanced Topics

> Fund recovery, clawback monitoring, and manual clawback operations

This section covers advanced features of the Flashnet AMM SDK including fund recovery mechanisms, background monitoring, and manual clawback operations.

## Automatic Fund Recovery

<Info>
  **Good news**: The SDK automatically handles fund recovery for most failures. When operations like swaps or liquidity additions fail, the SDK attempts to clawback your funds before throwing an error.
</Info>

### How Auto-Clawback Works

When you execute an operation that sends funds to a pool (swap, route swap, add liquidity, or confirm deposit), the SDK:

1. **Transfers your funds** to the pool
2. **Executes the operation** (signing intents, calling the API)
3. **If the operation fails**, checks if the error requires clawback
4. **Automatically claws back** your funds if needed
5. **Returns a typed error** with recovery status

```typescript theme={null}
import { isFlashnetError } from '@flashnet/sdk';

try {
  await client.executeSwap({
    poolId: "pool-id",
    assetInAddress: "btc-address",
    assetOutAddress: "usdb-address",
    amountIn: "100000000",
    minAmountOut: "99000000",
    maxSlippageBps: 100,
  });
} catch (error) {
  if (isFlashnetError(error)) {
    // Check auto-clawback results
    if (error.wasClawbackAttempted()) {
      const summary = error.clawbackSummary!;
      console.log(`Recovery: ${summary.successCount}/${summary.totalTransfers} transfers`);
      
      if (error.wereAllTransfersRecovered()) {
        console.log('✅ All funds recovered!');
      } else {
        console.log('⚠️ Some funds may need manual recovery:', summary.unrecoveredTransferIds);
      }
    }
    
    // Business errors (slippage, liquidity) auto-refund without clawback
    if (error.willAutoRefund()) {
      console.log('Funds will be returned automatically');
    }
  }
}
```

### Operations with Auto-Clawback

| Operation               | Transfer(s) Protected                     |
| ----------------------- | ----------------------------------------- |
| `executeSwap`           | Input asset transfer                      |
| `executeRouteSwap`      | Initial asset transfer to first pool      |
| `addLiquidity`          | Both asset A and asset B transfers        |
| `createSingleSidedPool` | Initial reserve transfer (during confirm) |

## Clawback Monitor

For applications that need continuous fund recovery, the SDK provides a background monitor that automatically recovers any stuck transfers.

### Starting the Monitor

```typescript theme={null}
const monitor = client.startClawbackMonitor({
  intervalMs: 60000,     // Poll every 60 seconds
  batchSize: 2,          // Process 2 clawbacks per batch (rate limit safe)
  batchDelayMs: 500,     // 500ms between batches
  maxTransfersPerPoll: 100,
  
  onClawbackSuccess: (result) => {
    console.log(`✅ Recovered: ${result.transferId}`);
  },
  
  onClawbackError: (transferId, error) => {
    console.error(`❌ Failed to recover ${transferId}:`, error);
  },
  
  onPollComplete: (result) => {
    if (result.transfersFound > 0) {
      console.log(`Poll: ${result.clawbacksSucceeded}/${result.transfersFound} recovered`);
    }
  },
  
  onPollError: (error) => {
    console.error('Poll failed:', error);
  },
});
```

### Monitor Options

| Option                | Type     | Default | Description                             |
| --------------------- | -------- | ------- | --------------------------------------- |
| `intervalMs`          | number   | 60000   | Polling interval in milliseconds        |
| `batchSize`           | number   | 2       | Clawbacks per batch (for rate limiting) |
| `batchDelayMs`        | number   | 500     | Delay between batches                   |
| `maxTransfersPerPoll` | number   | 100     | Max transfers to fetch per poll         |
| `onClawbackSuccess`   | function | -       | Called on successful clawback           |
| `onClawbackError`     | function | -       | Called on failed clawback               |
| `onPollComplete`      | function | -       | Called after each poll cycle            |
| `onPollError`         | function | -       | Called if polling itself fails          |

### Controlling the Monitor

```typescript theme={null}
// Check if running
console.log('Running:', monitor.isRunning());

// Trigger immediate poll
const result = await monitor.pollNow();
console.log('Found:', result.transfersFound);
console.log('Recovered:', result.clawbacksSucceeded);

// Stop gracefully (waits for current poll to complete)
await monitor.stop();
```

### Poll Result Structure

```typescript theme={null}
interface ClawbackPollResult {
  transfersFound: number;      // Clawbackable transfers found
  clawbacksAttempted: number;  // Clawback attempts made
  clawbacksSucceeded: number;  // Successful recoveries
  clawbacksFailed: number;     // Failed attempts
  results: ClawbackAttemptResult[]; // Detailed results
}
```

## Manual Clawback

For cases where you need manual control over fund recovery.

### Check Clawback Eligibility

Before attempting clawback, verify a transfer is eligible:

```typescript theme={null}
const eligibility = await client.checkClawbackEligibility({
  sparkTransferId: "transfer-id-here"
});

if (eligibility.accepted) {
  console.log('Transfer is eligible for clawback');
} else {
  console.log('Cannot clawback:', eligibility.error);
}
```

### List Clawbackable Transfers

Get all your transfers that can be clawed back:

```typescript theme={null}
const response = await client.listClawbackableTransfers({
  limit: 100,
  offset: 0
});

for (const transfer of response.transfers) {
  console.log(`Transfer: ${transfer.id}`);
  console.log(`  Pool: ${transfer.lpIdentityPublicKey}`);
  console.log(`  Created: ${transfer.createdAt}`);
}
```

### Execute Single Clawback

Recover a specific stuck transfer:

```typescript theme={null}
async function recoverTransfer(transferId: string, poolId: string) {
  try {
    const response = await client.clawback({
      sparkTransferId: transferId,
      lpIdentityPublicKey: poolId,
    });

    if (response.accepted) {
      console.log('Clawback initiated!');
      console.log('Request ID:', response.internalRequestId);
      console.log('Tracking ID:', response.sparkStatusTrackingId);
    } else {
      console.error('Rejected:', response.error);
    }
  } catch (error) {
    console.error('Clawback failed:', error);
  }
}
```

### Batch Clawback

Recover multiple transfers at once:

```typescript theme={null}
const results = await client.clawbackMultiple(
  ['transfer-1', 'transfer-2', 'transfer-3'],
  'pool-id'
);

for (const result of results) {
  if (result.success) {
    console.log(`✅ ${result.transferId} recovered`);
  } else {
    console.log(`❌ ${result.transferId} failed: ${result.error}`);
  }
}
```

## When to Use Manual Clawback

Manual clawback is useful when:

1. **Auto-clawback partially failed** - Check `error.getUnrecoveredTransferIds()` and retry manually
2. **Application crashed** mid-operation - Use the monitor or `listClawbackableTransfers` to find stuck funds
3. **Debugging** - Investigate specific transfers before recovery
4. **Custom recovery logic** - Implement your own retry strategies

## Clawback Eligibility Rules

A transfer is eligible for clawback if:

* The authenticated user is the original sender
* The transfer was sent to an LP wallet
* The transfer is not already reserved or spent
* The transfer has not been claimed/settled
* The transfer is less than **23 hours old** (for eligibility check) or **10 days old** (for listing)

<Warning>
  Transfers become ineligible after the time limit expires. Use the clawback monitor for continuous recovery.
</Warning>

## Error Recovery Decision Tree

```mermaid theme={null}
flowchart TD
    A[Operation Failed] --> B{Is it a FlashnetError?}
    B -->|No| C[Generic error handling]
    B -->|Yes| D{What's the recovery strategy?}
    
    D -->|auto_refund| E[✅ Funds return automatically]
    D -->|none| F[✅ No funds at risk]
    D -->|clawback_required<br/>clawback_recommended| G{Was auto-clawback attempted?}
    
    G -->|No| H[Manual clawback needed]
    G -->|Yes| I{Were all transfers recovered?}
    
    I -->|Yes| J[✅ Funds safe]
    I -->|No| K[Check unrecoveredTransferIds<br/>for manual recovery]
```

## Next Steps

* Learn about [Error Codes](/products/flashnet-amm/errors) and their meanings
* See [Swaps](/products/flashnet-amm/swaps) for swap operations
* See [Liquidity](/products/flashnet-amm/liquidity) for liquidity operations
