# Defining Actions in Blockflow Instances

Actions in Blockflow Instances are defined using TypeScript, allowing you to write powerful and expressive code to handle blockchain events and perform desired tasks. Before you start coding your actions, it's essential to understand the following concepts:

1. Context
2. Database Interactions
3. Secrets
4. Available Libraries

## Context

The `context` variable is injected into the action function as a parameter, providing you with crucial information about the event that triggered the action. It includes details such as:

* Event arguments
* Contract address
* Transaction details
* Block details

The `context` object has the following schema:

```
// schema
context: {
    event: { 
       <arg1 name> : String,
       <arg2 name> : String,
       .
       .
    },
    log: {
      log_index: String,
      log_transaction_hash: String,
      log_transaction_index: String,
      log_address: String
    },
    transaction: {
      transaction_hash: String,
      transaction_nonce: String,
      transaction_index: String,
      transaction_from_address: String,
      transaction_to_address: String,
      transaction_value: String,
      transaction_gas: String,
      transaction_gas_price: String,
      transaction_input: String,
      transaction_receipt_cumulative_gas_used: String,
      transaction_receipt_gas_used: String,
      transaction_receipt_status: String,
      max_fee_per_gas: String,
      max_priority_fee_per_gas: String,
      transaction_type: String,
      receipt_effective_gas_price: String
    },
    block: {
      block_timestamp: String,
      block_number: String,
      block_hash: String,
      parent_hash: String,
      nonce: String,
      sha3_uncles: String,
      logs_bloom: String,
      transactions_root: String,
      state_root: String,
      receipts_root: String,
      miner: String,
      difficulty: Number,
      total_difficulty: String,
      size: String,
      extra_data: String,
      gas_limit: String,
      gas_used: String,
      transaction_count: String,
      base_fee_per_gas: String,
      withdrawals_root: String
    }
  }
```

You can access the event arguments using the `context.event` object. For example, if the event has an argument named `from`, you can access it as follows:

<pre class="language-typescript"><code class="lang-typescript"><strong>// reading data
</strong>let fromAddr = context.event.from; // if the argument name is 'from' as per the ABI
</code></pre>

## Database Interactions

Blockflow provides a seamless way to interact with your managed databases within your action code. To learn how to read from and write to your databases, refer to this guide.

{% content-ref url="/pages/EF48HJGMwYz8GNGSYLG6" %}
[Working with Managed Database](/guides/creating-a-database/working-with-managed-database.md)
{% endcontent-ref %}

## Secrets

Secrets allow you to securely store and access sensitive information, such as API keys or private keys, without hardcoding them in your action code. You can access secrets using the `secret` variable.

For example, to access a private key stored as a secret:

```typescript
// accessing a secret
const wallet = new ethers.Wallet(secret.Private_Key);
```

Secrets can be maintained using Blockflow's secret manager. Check out the secret manager section to know more:

{% content-ref url="/pages/GgExXh3QJzesy7wGhA86" %}
[Secret Manager](/overview/secret-manager.md)
{% endcontent-ref %}

## Libraries

Blockflow provides several pre-imported libraries that you can use in your action code:

1. **Ethers.js**: A popular Ethereum library for interacting with the Ethereum blockchain and smart contracts

You can check out the library [here](https://www.npmjs.com/package/ethers).

Example usage:

```typescript
const wallet = new ethers.Wallet(secret.Private_Key);
```

2. **BigNumber.js**: A library for handling large numbers and performing arithmetic operations.&#x20;

You can check out the library [here](https://www.npmjs.com/package/bignumber.js/v/4.0.4).

Example usage:

<pre class="language-typescript"><code class="lang-typescript"><strong>let fromAmt = new BigNumber(context.event.from);
</strong></code></pre>

3. **PushUtils**: A utility library provided by Blockflow for interacting with the Push API.&#x20;

You can check out the library [here](https://www.npmjs.com/package/@pushprotocol/restapi).

Example usage:

```typescript
const user = await PushUtils.PushAPI.initialize(
    wallet, 
    {
        env: PushUtils.CONSTANTS.ENV.PROD
    }
);
```

### Writing Your Action Code

Now that you understand the key concepts, you can start writing your action code. Here's a basic template to get you started:

```typescript
import { IEventContext } from "@blockflow-labs/utils";

export const handler = async (context: IEventContext) => {
  // Access event arguments
  const fromAddress = context.event.from;
  const amount = new BigNumber(context.event.amount);

  // Interact with databases
  const balancesDB = bind("Balances");
  const userBalance = await balancesDB.findOne({ id: fromAddress.toLowerCase() });

  // Perform desired actions
  // ...

  // Return a result (optional)
};
```

In the `handler` function, you can access the `context` variable to retrieve event details, interact with databases using the `bind` function, and perform any desired actions based on the event.

Remember to handle errors appropriately and return a result if needed.

### Deploying Your Action

Once you have written your action code, you can deploy it to your Blockflow Instance by saving the code in the appropriate event file within the Instance's action definition interface.

Blockflow will automatically compile and deploy your action code, making it ready to handle incoming events.

Defining actions in Blockflow Instances using TypeScript provides a flexible and powerful way to automate workflows and respond to blockchain events. By leveraging the `context` variable, database interactions, secrets, and available libraries, you can create sophisticated actions that suit your specific needs.

<br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.blockflow.network/guides/creating-an-instance/defining-actions-in-blockflow-instances.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
