> ## Documentation Index
> Fetch the complete documentation index at: https://composio-27-feat-docs-revamp.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Github Contributor Reward Agent

> This project demonstrates how to use Composio to create a Github Contributor Reward Agent.

## Overview

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

## Getting Started

<Tabs>
  <Tab title="Python">
    <Steps>
      <Step title="Installation">
        ```bash install dependencies
        pip install composio-llamaindex python-dotenv
        ```
      </Step>

      <Step title="Connecting to tools and models">
        ```bash connect to required tools
        composio add github

        export OPENAI_API_KEY="<your-openai-api-key>"
        ```
      </Step>

      <Step title="Importing the required libraries">
        ```python 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()
        ```
      </Step>

      <Step title="Creating Solana Transfer Action">
        ```python 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)}"

        ```
      </Step>

      <Step title="Initializing the Tools and the LLM">
        ```python 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")
        ```
      </Step>

      <Step title="Setting up Function Calling Worker">
        ```python 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()
        ```
      </Step>

      <Step title="Executing the Agent">
        ```python 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""")
        ```
      </Step>

      <Step title="Final Code">
        ```python 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""")
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>
