Overview

The Github Contributor Reward Agent is an AI Agent that rewards Github Contributors with SOL based on their contributions.

Getting Started

1

Installation

install dependencies
pip install composio-llamaindex python-dotenv
2

Connecting to tools and models

connect to required tools
composio add github

export OPENAI_API_KEY="<your-openai-api-key>"
3

Importing the required libraries

import required libraries
from composio_llamaindex import ComposioToolSet, App, Action
from llama_index.core.agent import FunctionCallingAgentWorker
from llama_index.core.llms import ChatMessage
from llama_index.llms.openai import OpenAI
from dotenv import load_dotenv

load_dotenv()
4

Creating Solana Transfer Action

create solana transfer action
from solders.keypair import Keypair
from solders.pubkey import Pubkey
from solana.rpc.api import Client
from solders.system_program import TransferParams, transfer
from solders.transaction import Transaction
from solders.message import Message
from composio import action
import base58
from solders.signature import Signature

@action(toolname='solanakit', requires=['solana','solders'])
def send_sol(sender_private_key: str, receiver_public_key: str, amount: str, network: str = "devnet") -> str:
    """
    Send SOL to a wallet
    :param sender_private_key: private key of the sender
    :param receiver_public_key: address of the wallet to send SOL to
    :param amount: amount of SOL to send, should be in lamports
    :param network: network to send the transaction on
    :return transaction_hash: transaction hash
    """
    try:
        # Create keypair for sender
        # Use a valid Base58-encoded private key for the sender
        sender_keypair = Keypair.from_base58_string(sender_private_key)
        sender_public_key = sender_keypair.pubkey()

        # Define receiver's public key
        receiver_public_key_ = Pubkey.from_string(receiver_public_key)

        # Build the transfer instruction
        ixns = [
            transfer(
                TransferParams(
                    from_pubkey=sender_public_key,
                    to_pubkey=receiver_public_key_,
                    lamports=int(amount)
                )
            )
        ]

        # Create a message with the transaction
        msg = Message(ixns, sender_public_key)

        # Connect to a Solana client
        client = Client(f"https://api.{network}.solana.com")  # Using Devnet RPC endpoint

        # Fetch the latest blockhash
        latest_blockhash = client.get_latest_blockhash().value.blockhash

        # Create the transaction
        transaction = Transaction([sender_keypair], msg, latest_blockhash)

        # Send the transaction
        response = client.send_transaction(transaction)
        print("Transaction response:", response)
        return "Transaction sent successfully: "+str(response)
    except ValueError as e:
        return f"Error: Invalid key format - {str(e)}"
    except Exception as e:
        return f"Error sending transaction: {str(e)}"

5

Initializing the Tools and the LLM

initialize toolset and llm
toolset = ComposioToolSet(api_key="")
tools = toolset.get_tools(actions=[send_sol, Action.GITHUB_LIST_REPOSITORY_CONTRIBUTORS])

llm = OpenAI(model="gpt-4o")
6

Setting up Function Calling Worker

setup function calling worker
prefix_messages = [
    ChatMessage(
        role="system",
        content=(
              "You are a solana agent that can execute actions with Solana Kit"
              "You have access to Github and can list repository contributors"
        ),
    )
]

agent = FunctionCallingAgentWorker(
    tools=tools,
    llm=llm,
    prefix_messages=prefix_messages,
    max_function_calls=10,
    allow_parallel_tool_calls=False,
    verbose=True,
).as_agent()
7

Executing the Agent

run the agent
agent.chat("Find the most active contributor to the composiohq/composio repository and print their username.")
wallet_address = input("Enter the wallet address of the most active contributor: ")
private_key = os.getenv('SOLANA_PRIVATE_KEY')
my_wallet_address = os.getenv('SOLANA_WALLET_ADDRESS')
agent.chat(f"""send 1 SOL from my wallet {my_wallet_address}, my private key is {private_key} to {wallet_address} on devnet using send sol action""")
8

Final Code

final code
from composio_llamaindex import ComposioToolSet, App, Action
from llama_index.core.agent import FunctionCallingAgentWorker
from llama_index.core.llms import ChatMessage
from llama_index.llms.openai import OpenAI
from dotenv import load_dotenv
from solders.keypair import Keypair
from solders.pubkey import Pubkey
from solana.rpc.api import Client
from solders.system_program import TransferParams, transfer
from solders.transaction import Transaction
from solders.message import Message
from composio import action
import base58
from solders.signature import Signature

load_dotenv()

@action(toolname='solanakit', requires=['solana','solders'])
def send_sol(sender_private_key: str, receiver_public_key: str, amount: str, network: str = "devnet") -> str:
    """
    Send SOL to a wallet
    :param sender_private_key: private key of the sender
    :param receiver_public_key: address of the wallet to send SOL to
    :param amount: amount of SOL to send, should be in lamports
    :param network: network to send the transaction on
    :return transaction_hash: transaction hash
    """
    try:
        # Create keypair for sender
        # Use a valid Base58-encoded private key for the sender
        sender_keypair = Keypair.from_base58_string(sender_private_key)
        sender_public_key = sender_keypair.pubkey()

        # Define receiver's public key
        receiver_public_key_ = Pubkey.from_string(receiver_public_key)

        # Build the transfer instruction
        ixns = [
            transfer(
                TransferParams(
                    from_pubkey=sender_public_key,
                    to_pubkey=receiver_public_key_,
                    lamports=int(amount)
                )
            )
        ]

        # Create a message with the transaction
        msg = Message(ixns, sender_public_key)

        # Connect to a Solana client
        client = Client(f"https://api.{network}.solana.com")  # Using Devnet RPC endpoint

        # Fetch the latest blockhash
        latest_blockhash = client.get_latest_blockhash().value.blockhash

        # Create the transaction
        transaction = Transaction([sender_keypair], msg, latest_blockhash)

        # Send the transaction
        response = client.send_transaction(transaction)
        print("Transaction response:", response)
        return "Transaction sent successfully: "+str(response)
    except ValueError as e:
        return f"Error: Invalid key format - {str(e)}"
    except Exception as e:
        return f"Error sending transaction: {str(e)}"

toolset = ComposioToolSet(api_key="")
tools = toolset.get_tools(actions=[send_sol, Action.GITHUB_LIST_REPOSITORY_CONTRIBUTORS])

llm = OpenAI(model="gpt-4o")

prefix_messages = [
    ChatMessage(
        role="system",
        content=(
              "You are a solana agent that can execute actions with Solana Kit"
              "You have access to Github and can list repository contributors"
        ),
    )
]

agent = FunctionCallingAgentWorker(
    tools=tools,
    llm=llm,
    prefix_messages=prefix_messages,
    max_function_calls=10,
    allow_parallel_tool_calls=False,
    verbose=True,
).as_agent()

agent.chat("Find the most active contributor to the composiohq/composio repository and print their username.")
wallet_address = input("Enter the wallet address of the most active contributor: ")
private_key = os.getenv('SOLANA_PRIVATE_KEY')
my_wallet_address = os.getenv('SOLANA_WALLET_ADDRESS')
agent.chat(f"""send 1 SOL from my wallet {my_wallet_address}, my private key is {private_key} to {wallet_address} on devnet using send sol action""")