Skip to content

Send Transaction ​

The following guide teaches you how to send transactions in Wagmi. The example below builds on the Connect Wallet guide and uses the useSendTransaction & useWaitForTransaction composables.

Example ​

Feel free to check out the example before moving on:

Steps ​

1. Connect Wallet ​

Follow the Connect Wallet guide guide to get this set up.

2. Create a new component ​

Create your SendTransaction component that will contain the send transaction logic.

tsx
<script setup lang="ts">
</script>

<template>
  <form>
    <input name="address" placeholder="0xA0Cf…251e" required />
    <input name="value" placeholder="0.05" required />
    <button type="submit">Send</button>
  </form>
</template>

3. Add a form handler ​

Next, we will need to add a handler to the form that will send the transaction when the user hits "Send". This will be a basic handler in this step.

vue
<script setup lang="ts">
  function submit(event: Event) {
    const formData = new FormData(event.target as HTMLFormElement)
    const to = formData.get('address') as `0x${string}`
    const value = formData.get('value') as string
    sendTransaction({ to, value: parseEther(value) })
  }
</script>

<template>
  <form>
  <form @submit.prevent="submit">
    <input name="address" placeholder="0xA0Cf…251e" required />
    <input name="value" placeholder="0.05" required />
    <button type="submit">Send</button>
  </form>
</template>

4. Hook up the useSendTransaction Hook ​

Now that we have the form handler, we can hook up the useSendTransaction Hook to send the transaction.

vue
<script setup lang="ts">
  import { useSendTransaction } from 'wagmi'
  import { parseEther } from 'viem'

  const { data: hash, sendTransaction } = useSendTransaction()

  function submit(event: Event) {
    const formData = new FormData(event.target as HTMLFormElement)
    const to = formData.get('address') as `0x${string}`
    const value = formData.get('value') as string
    sendTransaction({ to, value: parseEther(value) })
  }
</script>

<template>
  <form @submit.prevent="submit">
    <input name="address" placeholder="0xA0Cf…251e" required />
    <input name="value" placeholder="0.05" required />
    <button type="submit">Send</button>
    <div v-if="hash">Transaction Hash: {{ hash }}</div>
  </form>
</template>

5. Add loading state (optional) ​

We can optionally add a loading state to the "Send" button while we are waiting confirmation from the user's wallet.

vue
<script setup lang="ts">
  import { useSendTransaction } from 'wagmi'
  import { parseEther } from 'viem'

  const { 
    data: hash, 
    isPending,
    sendTransaction 
  } = useSendTransaction()

  function submit(event: Event) {
    const formData = new FormData(event.target as HTMLFormElement)
    const to = formData.get('address') as `0x${string}`
    const value = formData.get('value') as string
    sendTransaction({ to, value: parseEther(value) })
  }
</script>

<template>
  <form @submit.prevent="submit">
    <input name="address" placeholder="0xA0Cf…251e" required />
    <input name="value" placeholder="0.05" required />
    <button :disabled="isPending" type="submit">
      <span v-if="isPending">Sending...</span>
      <span v-else>Send</span>
    </button>
    <div v-if="hash">Transaction Hash: {{ hash }}</div>
  </form>
</template>

6. Wait for transaction receipt (optional) ​

We can also display the transaction confirmation status to the user by using the useWaitForTransactionReceipt Composable.

vue
<script setup lang="ts">
  import { 
    useSendTransaction,
    useWaitForTransactionReceipt,
  } from 'wagmi'
  import { parseEther } from 'viem'

  const { 
    data: hash, 
    isPending,
    sendTransaction 
  } = useSendTransaction()

  function submit(event: Event) {
    const formData = new FormData(event.target as HTMLFormElement)
    const to = formData.get('address') as `0x${string}`
    const value = formData.get('value') as string
    sendTransaction({ to, value: parseEther(value) })
  }

  const { isLoading: isConfirming, isSuccess: isConfirmed } =
    useWaitForTransactionReceipt({ 
      hash, 
    })
</script>

<template>
  <form @submit.prevent="submit">
    <input name="address" placeholder="0xA0Cf…251e" required />
    <input name="value" placeholder="0.05" required />
    <button :disabled="isPending" type="submit">
      <span v-if="isPending">Sending...</span>
      <span v-else>Send</span>
    </button>
    <div v-if="hash">Transaction Hash: {{ hash }}</div>
    <div v-if="isConfirming">Waiting for confirmation...</div>
    <div v-if="isConfirmed">Transaction Confirmed!</div>
  </form>
</template>

7. Handle errors (optional) ​

If the user rejects the transaction, or the user does not have enough funds to cover the transaction, we can display an error message to the user.

:::

vue
<script setup lang="ts">
  import { 
    useSendTransaction,
    useWaitForTransactionReceipt,
  } from 'wagmi'
  import { parseEther } from 'viem'

  const { 
    data: hash, 
    error,
    isPending,
    sendTransaction 
  } = useSendTransaction()

  function submit(event: Event) {
    const formData = new FormData(event.target as HTMLFormElement)
    const to = formData.get('address') as `0x${string}`
    const value = formData.get('value') as string
    sendTransaction({ to, value: parseEther(value) })
  }

  const { isLoading: isConfirming, isSuccess: isConfirmed } = 
    useWaitForTransactionReceipt({ 
      hash, 
    }) 
</script>

<template>
  <form @submit.prevent="submit">
    <input name="address" placeholder="0xA0Cf…251e" required />
    <input name="value" placeholder="0.05" required />
    <button :disabled="isPending" type="submit">
      <span v-if="isPending">Sending...</span>
      <span v-else>Send</span>
    </button>
    <div v-if="hash">Transaction Hash: {{ hash }}</div>
    <div v-if="isConfirming">Waiting for confirmation...</div> 
    <div v-if="isConfirmed">Transaction Confirmed!</div> 
    <div v-if="error">
      Error: {{ (error as BaseError).shortMessage || error.message }}
    </div>
  </form>
</template>

8. Wire it up! ​

Finally, we can wire up our Send Transaction component to our application's entrypoint.

vue
<script setup lang="ts">
import { useAccount } from '@wagmi/vue';
import Account from './Account.vue';
import Connect from './Connect.vue';
import SendTransaction from './SendTransaction.vue';

const { isConnected } = useAccount();
</script>

<template>
  <Account v-if="isConnected" />
  <Connect v-else />
  <SendTransaction v-if="isConnected" />
</template>
vue
<script setup lang="ts">
  import { 
    useSendTransaction,
    useWaitForTransactionReceipt,
  } from 'wagmi'
  import { parseEther } from 'viem'

  const { 
    data: hash, 
    error,
    isPending,
    sendTransaction 
  } = useSendTransaction()

  function submit(event: Event) {
    const formData = new FormData(event.target as HTMLFormElement)
    const to = formData.get('address') as `0x${string}`
    const value = formData.get('value') as string
    sendTransaction({ to, value: parseEther(value) })
  }

  const { isLoading: isConfirming, isSuccess: isConfirmed } = 
    useWaitForTransactionReceipt({ 
      hash, 
    }) 
</script>

<template>
  <form @submit.prevent="submit">
    <input name="address" placeholder="0xA0Cf…251e" required />
    <input name="value" placeholder="0.05" required />
    <button :disabled="isPending" type="submit">
      <span v-if="isPending">Sending...</span>
      <span v-else>Send</span>
    </button>
    <div v-if="hash">Transaction Hash: {{ hash }}</div>
    <div v-if="isConfirming">Waiting for confirmation...</div> 
    <div v-if="isConfirmed">Transaction Confirmed!</div> 
    <div v-if="error">
      Error: {{ (error as BaseError).shortMessage || error.message }}
    </div>
  </form>
</template>

See the Example.

Released under the MIT License.