> ## Documentation Index
> Fetch the complete documentation index at: https://base-a060aa97-fix-dead-service-links.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# flowControl

> Control transaction batch behavior after failed or reverted calls

export const Button = ({children, disabled, variant = "primary", size = "medium", iconName, roundedFull = false, className = '', fullWidth = false, onClick = undefined}) => {
  const variantStyles = {
    primary: 'bg-blue text-black border border-blue hover:bg-blue-80 active:bg-[#06318E] dark:text-white',
    secondary: 'bg-white border border-white text-palette-foreground hover:bg-zinc-15 active:bg-zinc-30',
    outlined: 'bg-transparent text-white border border-white hover:bg-white hover:text-black active:bg-[#E3E7E9]'
  };
  const sizeStyles = {
    medium: 'text-md px-4 py-2 gap-3',
    large: 'text-lg px-6 py-4 gap-5'
  };
  const sizeIconRatio = {
    medium: '0.75rem',
    large: '1rem'
  };
  const classes = ['text-md px-4 py-2 whitespace-nowrap', 'flex items-center justify-center', 'disabled:opacity-40 disabled:pointer-events-none', 'transition-all', variantStyles[variant], sizeStyles[size], roundedFull ? 'rounded-full' : 'rounded-lg', fullWidth ? 'w-full' : 'w-auto', className];
  const buttonClasses = classes.filter(Boolean).join(' ');
  const iconSize = sizeIconRatio[size];
  return <button type="button" disabled={disabled} className={buttonClasses} onClick={onClick}>
      <span>{children}</span>
      {iconName && <Icon name={iconName} width={iconSize} height={iconSize} color="currentColor" />}
    </button>;
};

export const BaseBanner = ({content = null, id, dismissable = true}) => {
  const LOCAL_STORAGE_KEY_PREFIX = 'cb-docs-banner';
  const [isVisible, setIsVisible] = useState(false);
  const onDismiss = () => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY_PREFIX}-${id}`, 'false');
    setIsVisible(false);
  };
  useEffect(() => {
    const storedValue = localStorage.getItem(`${LOCAL_STORAGE_KEY_PREFIX}-${id}`);
    setIsVisible(storedValue !== 'false');
  }, []);
  if (!isVisible) {
    return null;
  }
  return <div className="fixed bottom-0 left-0 right-0 bg-white py-8 px-4 lg:px-12 z-50 text-black dark:bg-black dark:text-white border-t dark:border-gray-95">
      <div className="flex items-center max-w-8xl mx-auto">
        {typeof content === 'function' ? content({
    onDismiss
  }) : content}
        {dismissable && <button onClick={onDismiss} className="flex-shrink-0 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors" aria-label="Dismiss banner">
          ✕
        </button>}
      </div>
    </div>;
};

Defined in [ERC-7867](https://github.com/ethereum/ERCs/pull/7867) (Proposed)

<Info>
  The flowControl capability allows dapps to specify how transaction batches should behave when individual calls fail or revert. This provides fine-grained control over transaction execution flow and enables more sophisticated error handling strategies.
</Info>

<Warning>
  This capability is currently proposed in ERC-7867 and is not yet finalized. Implementation details may change as the specification develops.
</Warning>

## Parameters

<ParamField body="onFailure" type="string">
  Specifies the behavior when a transaction call fails or reverts.

  **Possible values:**

  * `"continue"`: Continue executing remaining calls
  * `"stop"`: Stop execution on failure
  * `"retry"`: Attempt to retry the failed call
</ParamField>

<ParamField body="fallbackCall" type="object">
  Optional fallback transaction to execute if the primary call fails.

  <Expandable title="FallbackCall properties">
    <ParamField body="to" type="string" required>
      The recipient address for the fallback call.
    </ParamField>

    <ParamField body="value" type="string">
      The value to send with the fallback call (in wei, hex format).
    </ParamField>

    <ParamField body="data" type="string">
      The call data for the fallback call (hex format).
    </ParamField>
  </Expandable>
</ParamField>

## Returns

<ResponseField name="flowControl" type="object">
  The flow control capability configuration for the specified chain.

  <Expandable title="FlowControl capability properties">
    <ResponseField name="supported" type="boolean">
      Indicates whether the wallet supports flow control functionality.
    </ResponseField>
  </Expandable>
</ResponseField>

## Example Usage

<RequestExample>
  ```typescript Check Flow Control Support theme={null}
  const capabilities = await provider.request({
    method: 'wallet_getCapabilities',
    params: [userAddress]
  });

  const flowControlCapability = capabilities["0x2105"]?.flowControl;
  ```

  ```typescript Proposed Usage (Subject to Change) theme={null}
  const result = await provider.request({
    method: 'wallet_sendCalls',
    params: [{
      version: "1.0",
      chainId: "0x2105",
      from: userAddress,
      calls: [
        {
          to: "0x1234567890123456789012345678901234567890",
          value: "0x0",
          data: "0xa9059cbb000000000000000000000000...",
          flowControl: {
            onFailure: "continue",
            fallbackCall: {
              to: "0x...",
              data: "0x..."
            }
          }
        }
      ]
    }]
  });
  ```
</RequestExample>

<ResponseExample>
  ```json Capability Response (Supported) theme={null}
  {
    "0x2105": {
      "flowControl": {
        "supported": true
      }
    }
  }
  ```

  ```json Capability Response (Unsupported) theme={null}
  {
    "0x2105": {
      "flowControl": {
        "supported": false
      }
    }
  }
  ```
</ResponseExample>

## Error Handling

| Code | Message                          | Description                                                     |
| ---- | -------------------------------- | --------------------------------------------------------------- |
| 4100 | Flow control not supported       | Wallet does not support flow control functionality              |
| 5700 | Flow control capability required | Transaction requires flow control but wallet doesn't support it |
| 5800 | Invalid flow control parameters  | The provided flow control configuration is invalid              |

## Potential Use Cases

### E-commerce Transactions

Handle scenarios where some purchases succeed while others fail:

```typescript theme={null}
// Example: Multi-item purchase with flow control
const purchaseResult = await provider.request({
  method: 'wallet_sendCalls',
  params: [{
    version: "1.0",
    chainId: "0x2105",
    from: userAddress,
    calls: [
      // Primary item purchase
      {
        to: marketplaceContract,
        value: "0x0",
        data: purchaseItem1CallData,
        flowControl: { onFailure: "continue" }
      },
      // Secondary item purchase  
      {
        to: marketplaceContract,
        value: "0x0", 
        data: purchaseItem2CallData,
        flowControl: { onFailure: "continue" }
      },
      // Payment processing (critical)
      {
        to: paymentContract,
        value: "0x16345785d8a0000",
        data: "0x",
        flowControl: { onFailure: "stop" }
      }
    ]
  }]
});
```

### DeFi Operations with Fallbacks

Implement sophisticated DeFi strategies with backup options:

```typescript theme={null}
// Example: Swap with fallback routing
const swapWithFallback = await provider.request({
  method: 'wallet_sendCalls',
  params: [{
    version: "1.0",
    chainId: "0x2105", 
    from: userAddress,
    calls: [
      // Primary DEX swap
      {
        to: primaryDexAddress,
        value: "0x0",
        data: primarySwapCallData,
        flowControl: {
          onFailure: "fallback",
          fallbackCall: {
            to: secondaryDexAddress,
            data: secondarySwapCallData
          }
        }
      }
    ]
  }]
});
```

### Batch Operations with Error Recovery

Execute batch operations that can gracefully handle individual failures:

```typescript theme={null}
// Example: Bulk token approvals with recovery
const bulkApprovals = await provider.request({
  method: 'wallet_sendCalls',
  params: [{
    version: "1.0",
    chainId: "0x2105",
    from: userAddress,
    calls: tokenAddresses.map((token, index) => ({
      to: token,
      value: "0x0",
      data: approveCallData,
      flowControl: {
        onFailure: "continue", // Don't stop batch if one approval fails
        retryCount: 2 // Retry failed approvals
      }
    }))
  }]
});
```

## Checking Capability Support

Once implemented, check for flow control support:

```typescript theme={null}
async function checkFlowControlSupport() {
  try {
    const capabilities = await provider.request({
      method: 'wallet_getCapabilities',
      params: [userAddress]
    });
    
    const flowControlCapability = capabilities["0x2105"]?.flowControl;
    
    if (flowControlCapability?.supported) {
      console.log("Flow control capability supported");
      return true;
    } else {
      console.log("Flow control capability not supported");
      return false;
    }
  } catch (error) {
    console.error("Error checking flow control capability:", error);
    return false;
  }
}
```

## Expected Benefits

When implemented, flow control will provide:

1. **Better User Experience**: Partial success instead of complete failure
2. **Flexible Error Handling**: Apps can define custom failure responses
3. **Reduced Gas Waste**: Avoid re-executing successful operations
4. **Complex Workflows**: Enable sophisticated multi-step processes

## Development Status

This capability is actively being developed:

* **ERC-7867**: Formal proposal for flow control capability
* **Community Input**: Ongoing discussions about implementation details
* **Wallet Integration**: Pending finalization of specification

## Preparing for Flow Control

While waiting for implementation, developers can:

1. **Design Flexible Architecture**: Build apps that can adapt to different execution models
2. **Implement Fallback Logic**: Create manual fallback strategies for critical operations
3. **Monitor Specification**: Track ERC-7867 progress for implementation updates
4. **Test Sequential Execution**: Use current capabilities to simulate flow control behavior

<Info>
  Stay updated on ERC-7867 development to implement flow control as soon as it's available in production wallets.
</Info>

<Warning>
  The examples above are conceptual and may not reflect the final implementation. Always refer to the latest ERC-7867 specification for accurate details.
</Warning>

## Related Capabilities

Flow control works alongside other capabilities:

* **[Atomic](/base-account/reference/core/capabilities/atomic)**: For strict all-or-nothing execution
* **[Paymaster Service](/base-account/reference/core/capabilities/paymasterService)**: For sponsored transaction flows
* **[Auxiliary Funds](/base-account/reference/core/capabilities/auxiliaryFunds)**: For flexible funding sources

<BaseBanner
  id="privacy-policy"
  dismissable={false}
  content={({ onDismiss }) => (
<div className="flex items-center">
  <div className="mr-2">
    We're updating the Base Privacy Policy, effective July 25, 2025, to reflect an expansion of Base services. Please review the updated policy here:{" "}
    <a
      href="https://docs.base.org/privacy-policy-2025"
      target="_blank"
      className="whitespace-nowrap"
    >
      Base Privacy Policy
    </a>. By continuing to use Base services, you confirm that you have read and understand the updated policy.
  </div>
  <Button onClick={onDismiss}>I Acknowledge</Button>
</div>
)}
/>
