> For the complete documentation index, see [llms.txt](https://docs.baas.sh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.baas.sh/baas-console/automations/actions/transaction.md).

# Transaction

Call a write function on one of your deployed contracts, sent on-chain with a key from your Vault.

The Transaction action calls a write function on one of your contracts, signed and sent with a key from your Vault. In this guide, it powers the weekly rewards automation from the [Cron](/baas-console/automations/triggers/cron.md) page. A cron tick carries no data, so the action holds the recipient and the amount itself.

{% hint style="info" %}
**You need a key set up on the deployment's network, and a registered deployment.** Keys are added in the Dashboard's [Vault](/dashboard/vault.md) and enabled per network in the Console's [Vault](/baas-console/vault.md). Deployments register through [`baas deploy`](/baas-cli/deploy.md) or the Console's [**Contracts**](/baas-console/contracts/register-a-contract.md) section.
{% endhint %}

## Set up the transaction

The form comes in two parts: **Contract call** first, then **Key & completion**: which key sends the transaction, and when it counts as done.

{% stepper %}
{% step %}

### Pick the Transaction type

[Add a step](/baas-console/automations/actions.md) to the pipeline and pick **Transaction**.
{% endstep %}

{% step %}

### Choose the contract

Point the action at a contract: **Contract name**, then **Version** (the latest is preselected), then **Deployment**. In our example: your token contract, latest version.
{% endstep %}

{% step %}

### Choose the function

**Function** lists the write functions of the selected version's ABI. In our example, `transfer`.
{% endstep %}

{% step %}

### Fill the arguments

Each argument gets its own field, labeled with its name. In our example, `to` takes the recipient and `value` the weekly amount. A `{{...}}` hole fills one whole argument: it cannot sit inside an array or a tuple argument.

An argument with a [unit](/baas-console/contracts/units.md) carries a **Smart unit** switch. Turn it on to write `12.5`; leave it off to write the raw integer.

To make an argument dynamic, write one `{{...}}` as the entire field, such as `{{context.previous.amountWei}}`. An argument cannot be optional (`{{...?}}` is refused here): a missing value fails the run rather than sending a wrong call.

**Value (wei)** adds native currency to the call, for functions marked `payable`. Its **Float**/**Wei** switch takes either a plain amount like `0.5` or the raw integer. For a plain `transfer` like ours, it stays at `0`.

An earlier Function step can compute these values in code: see [Dynamic arguments from a function](#dynamic-arguments-from-a-function).
{% endstep %}

{% step %}

### Pick the key

**Key** appears once the contract call is complete. The network is the deployment's, so the keys set up on that network are offered; a run needs the key enabled there. None fits? Set one up there in the [Vault](/baas-console/vault.md), or click **Add key** to add one in the Dashboard: it opens in a new tab, and the list refreshes when you come back.
{% endstep %}

{% step %}

### Choose when it completes

**Complete action when** decides what counts as success: **Accepted (queued)** finishes as soon as the transaction is queued for sending, while **Confirmed on-chain** waits for the on-chain receipt. In our example, pick **Confirmed on-chain**, so the report that follows describes tokens that actually moved. In [batch mode](/baas-console/automations/batch.md), only **Accepted (queued)** is available.

{% hint style="info" %}
**On a** [**light-engine**](/baas-console/console.md) **project, this choice is made for you.** Every transaction waits for its on-chain confirmation.
{% endhint %}
{% endstep %}

{% step %}

### Save

Click **Save**. The transaction now goes out on every run.
{% endstep %}
{% endstepper %}

## Dynamic arguments from a function

Each argument field accepts one `{{...}}` template, so a [Function](/baas-console/automations/actions/function.md) placed before this action can prepare the values it needs. With its [`plugins`](/baas-console/automations/reference/plugins.md), the function can call an API, sign a message, and assemble the arguments, then return them.

Say the contract exposes `claim(address,uint256,bytes)`: it pays an amount your backend decides, and verifies a signature from a key of your Vault. A Function before this action, with that key in its **Key (optional)** field, prepares all three arguments:

```js
async (trigger, context, plugins) => {
  const { responseData } = await plugins.api.call({
    method: "GET",
    url: "https://api.example.com/payouts/next",
  });
  const { signature } = await plugins.vault.signMessage(
    `${responseData.recipient}:${responseData.amountWei}`
  );
  return {
    recipient: responseData.recipient,
    amountWei: responseData.amountWei,
    signature,
  };
}
```

This action then reads the prepared values in its argument fields: `{{context.previous.recipient}}`, `{{context.previous.amountWei}}`, and `{{context.previous.signature}}`. For a payable call, **Value (wei)** takes a template the same way.

## What the next step receives

| Field           | Contents                                                   |
| --------------- | ---------------------------------------------------------- |
| `transactionId` | The submission's id                                        |
| `txHash`        | The transaction hash                                       |
| `status`        | `accepted` or `confirmed`, matching your completion choice |

In our example, `status` is `confirmed`, and the [API](/baas-console/automations/actions/api.md) action that follows POSTs the `transactionId` to your backend.

{% hint style="info" %}
**Accepted is not confirmed.** With **Accepted (queued)**, success means the transaction is queued for sending, not that it is mined, and `txHash` can still be empty when the next step runs. Pick **Confirmed on-chain** when the later steps should run only after the transaction is mined.
{% endhint %}

## Waiting for confirmation

With **Confirmed on-chain**, the action waits for the on-chain receipt before it succeeds. The run stays **Running** through the wait.

The wait ends in one of three ways:

* The transaction is confirmed on-chain: the step succeeds, and `status` reads `confirmed`.
* The transaction fails, is canceled, or expires: the action fails. It is not retried, so verify it on-chain, fix the cause, then trigger the automation again.
* Ten minutes pass and the transaction is still pending: the action fails with a confirmation timeout. It may still confirm later, so check it on-chain before triggering it again.

{% hint style="warning" %}
**`transaction_submission_unknown` means the outcome is unknown.** The answer was lost, so the transaction may or may not have gone out. The action is not retried. Check the key's transactions in the [Vault](/baas-console/vault.md) before triggering the run again, or you may send it twice.
{% endhint %}

## Next

* [API](/baas-console/automations/actions/api.md): report the result to your backend.
* [Deploy a contract](/baas-cli/deploy.md): register the contract to call.
* [Actions](/baas-console/automations/actions.md): back to the section overview.
