🖊️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:

// reading data
let fromAddr = context.event.from; // if the argument name is 'from' as per the ABI

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.

🖊️Working with Managed Database

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:

// 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:

㊙️Secret Manager

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.

Example usage:

const wallet = new ethers.Wallet(secret.Private_Key);
  1. BigNumber.js: A library for handling large numbers and performing arithmetic operations.

You can check out the library here.

Example usage:

let fromAmt = new BigNumber(context.event.from);
  1. PushUtils: A utility library provided by Blockflow for interacting with the Push API.

You can check out the library here.

Example usage:

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:

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.