langchain-ai/langchainjs

Tool Support for Hedera Integration

Opened this issue · 0 comments

Privileged issue

  • I am a LangChain maintainer, or was asked directly by a LangChain maintainer to create an issue here.

Issue Content

This is a continuation of the discussion post #7097 .
We would like to add support for interaction with the Hedera network, including smart contracts, wallet interactions, and access to information through the Mirror Node API. This improvement allows LangChain users to interact with the Hedera network to provide access to verified data, make and record transactions.

We intend to make extensive use of the Hedera REST API, providing features including but not necessarily limited to:

Query Accounts and their balances
List NFTs and Tokens owned by an account
Make and Schedule transactions
Query information from Smart Contracts including execution results and state.

The above could theoretically be equally accomplished with a Document Loader, but the reason for implementation as a Tool is that we also intend to allow agentic behaviour by providing the AI with the ability to interface with the Hedera network:

Prerequisite: The Agent must be provided with a Hedera Account on the same network as defined in baseURL; functioning analogous to an API key, and distinct from the traditional definition of an account as it is closer to a blockchain address/wallet.

Query balance of the provided wallet
Read the Transaction History
Make Transactions
Interact with Smart Contracts (Depending on the implementation of the contract)

Since the tool is multifunctional, we intend to follow a similar general structure to the Gmail tool described in https://js.langchain.com/docs/integrations/tools/gmail/

i.e. We intend to define a directory for our tool that defines each functionality we implement, with each file defining a subset of functionality relating to either smart contracts, wallets, or the REST API.

Since some of these actions are sensitive, e.g. making transactions, which could cost real money, we intend to implement a permissioning system such that upon initialisation of the tool, its capabilities must be defined by the developer initialising it and providing it to their agent. These permissions will be the following:

-> REST API permissions
-> Smart Contract Query permissions
-> Smart Contract Create/Update permissions
-> Wallet Read Permissions (Query Balance, etc.)
-> Wallet Write Permissions (Posting Transactions, etc.)

An agent provided with a tool with sufficient permissions may then call a given tool like so:

import { initializeAgentExecutorWithOptions } from "langchain/agents";
import { OpenAI } from "@langchain/openai";
import {
  HederaQueryBalance,
  HederaTransactionHistory,
  HederaSendTransaction,
  HederaSmartContractQuery,
} from "@langchain/community/tools/hedera";
import { StructuredTool } from "@langchain/core/tools";

export async function run() {
  const model = new OpenAI({
    temperature: 0,
    apiKey: process.env.OPENAI_API_KEY,
  });

  // Hedera account credentials and base URL for the network
  const hederaParams = {
    accountId: process.env.HEDERA_ACCOUNT_ID,
    privateKey: process.env.HEDERA_PRIVATE_KEY,
    baseURL: "https://testnet.mirrornode.hedera.com", // or mainnet for production
  };

  // Initialize the Hedera tools with custom parameters
  const tools: StructuredTool[] = [
    new HederaQueryBalance(hederaParams),
    new HederaTransactionHistory(hederaParams),
    new HederaSendTransaction(hederaParams),
    new HederaSmartContractQuery(hederaParams),
  ];

  const hederaAgent = await initializeAgentExecutorWithOptions(tools, model, {
    agentType: "structured-chat-zero-shot-react-description",
    verbose: true,
  });

  const balanceInput = `Query the balance of my Hedera wallet.`;
  const balanceResult = await hederaAgent.invoke({ input: balanceInput });
  console.log("Balance Result", balanceResult);

  const transactionInput = `Fetch the last 5 transactions from my account history.`;
  const transactionResult = await hederaAgent.invoke({ input: transactionInput });
  console.log("Transaction History Result", transactionResult);

  const sendTransactionInput = `Send 10 HBAR to account 0.0.12345 as a test transaction.`;
  const sendTransactionResult = await hederaAgent.invoke({ input: sendTransactionInput });
  console.log("Send Transaction Result", sendTransactionResult);

  const smartContractInput = `Query my smart contract for the latest state.`;
  const smartContractResult = await hederaAgent.invoke({ input: smartContractInput });
  console.log("Smart Contract Query Result", smartContractResult);
}

If anyone has suggestions, feedback, or tips, we'd greatly appreciate them.