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

# submitFlowTransaction

# submitFlowTransaction

Prepares, signs, and broadcasts a flow transaction in one call. This is the recommended way to submit — it handles the full sequence:

1. Calls `prepareFlowSigning` to lock the quote and get the signing payload
2. Switches the wallet to the correct network
3. Signs the transaction (including ERC-20 approval if needed)
4. Calls `broadcastFlow` with the resulting `txHash`

## When to call

Call `submitFlowTransaction` when `executionState` is `quoted`. The function starts by calling `prepareFlowSigning`, which requires that state.

Before retrying after an interruption or network error, call [`getFlow`](/docs/javascript/reference/client/get-flow):

* If the flow is still `quoted`, you can call `submitFlowTransaction` again.
* If it is `signing`, first determine whether the wallet submitted a transaction. If you have its transaction hash, call [`broadcastFlow`](/docs/javascript/reference/client/broadcast-flow) to record it. If no transaction was submitted, call [`getFlowQuote`](/docs/javascript/reference/client/get-flow-quote) to return to `quoted` with a new quote, then submit again.
* If it is `broadcasted` or `source_confirmed`, the transaction has already been submitted. Poll the flow instead.
* If it is `cancelled`, `expired`, or `failed`, create a new flow for another attempt.

<Warning>
  Do not retry `submitFlowTransaction` without checking state. Calling it after
  the flow has advanced from `quoted` returns `409` and can prompt the user to
  repeat signing unnecessarily.
</Warning>

## Usage

```javascript theme={"system"}
import { submitFlowTransaction } from '@dynamic-labs-sdk/client';

const flow = await submitFlowTransaction({
  flowId: 'your-flow-id',
  walletAccount,
});

console.log('Broadcasted:', flow.txHash);
```

## Parameters

| Parameter                        | Type                                                     | Description                                                                                                                         |
| -------------------------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `flowId`                         | `string`                                                 | The flow ID.                                                                                                                        |
| `walletAccount`                  | `WalletAccount`                                          | The wallet account to sign with. Get this from the Dynamic SDK's wallet management (e.g., `useGetWalletAccounts()` in React hooks). |
| `onStepChange`                   | `(step: 'approval' \| 'transaction') => void` (optional) | Callback fired when the signing step changes — useful for showing progress UI.                                                      |
| `assertBalanceForGasCost`        | `boolean` (optional)                                     | Verify the wallet has enough for gas before signing. Returns `422` if insufficient. Default: `false`.                               |
| `assertBalanceForTransferAmount` | `boolean` (optional)                                     | Verify the wallet has enough for the transfer. Returns `422` if insufficient. Default: `false`.                                     |

## Returns

`Promise<Flow>` — the flow after broadcast, with `executionState: 'broadcasted'` and `txHash` populated.

## Examples

### Basic submission

```javascript theme={"system"}
import { submitFlowTransaction } from '@dynamic-labs-sdk/client';

const flow = await submitFlowTransaction({
  flowId: 'your-flow-id',
  walletAccount,
});
```

### With balance assertions and step tracking

```javascript theme={"system"}
import { submitFlowTransaction } from '@dynamic-labs-sdk/client';

const flow = await submitFlowTransaction({
  flowId: 'your-flow-id',
  walletAccount,
  assertBalanceForGasCost: true,
  assertBalanceForTransferAmount: true,
  onStepChange: (step) => {
    console.log('Current step:', step);
    // 'approval' — signing ERC-20 token approval
    // 'transaction' — signing the main transaction
  },
});
```

### Handle wallet rejection

```javascript theme={"system"}
import { submitFlowTransaction, cancelFlow } from '@dynamic-labs-sdk/client';

try {
  await submitFlowTransaction({
    flowId: 'your-flow-id',
    walletAccount,
  });
} catch (error) {
  if (error.message.includes('rejected')) {
    await cancelFlow({ flowId: 'your-flow-id' });
  }
}
```

## React

```tsx theme={"system"}
import { useGetWalletAccounts } from '@dynamic-labs-sdk/react-hooks';
import { useSubmitFlowTransaction } from '@dynamic-labs-sdk/react-hooks';

function SubmitFlow({ flowId }) {
  const { data: walletAccounts = [] } = useGetWalletAccounts();
  const { mutate: submit, isPending, data: flow } = useSubmitFlowTransaction();

  return (
    <button
      onClick={() => submit({ flowId, walletAccount: walletAccounts[0] })}
      disabled={isPending || !walletAccounts[0]}
    >
      {isPending ? 'Submitting...' : 'Submit'}
    </button>
  );
}
```

## Related

* [Fireblocks Flow JavaScript SDK guide](/docs/overview/fireblocks-flow-js-sdk) - End-to-end flow guide
* [`prepareFlowSigning`](/docs/javascript/reference/client/prepare-flow-signing) - Prepare signing manually (advanced)
* [`broadcastFlow`](/docs/javascript/reference/client/broadcast-flow) - Record broadcast manually (advanced)
* [`getFlow`](/docs/javascript/reference/client/get-flow) - Poll flow state after submission
