> For the complete documentation index, see [llms.txt](https://fortress-labs.gitbook.io/snakepath/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://fortress-labs.gitbook.io/snakepath/relayer/relayer-interface-architecture.md).

# Relayer Interface Architecture

Each chain is defined by a chain interface and contract interface, which are defined by the following abstract base classes:

```python
class BaseChainInterface(abc.ABC):
    """
    Base class for all chain interfaces
    Governs transaction retrieval and creation
    """

    @abc.abstractmethod
    def sign_and_send_transaction(self, tx):
        """
        Given a raw transaction, signs it and sends it to the chain
        Args:
            tx: the raw transaction to be sent to the chain
        """
        pass

    @abc.abstractmethod
    def get_transactions(self, address, height=None):
        """
            Retrieves all transactions from the chain that fit interface-dependent filters
        """
        pass

    @abc.abstractmethod
    def get_last_block(self):
        """
            Retrieves the current block height of the chain
        """
        pass


class BaseContractInterface(abc.ABC):
    """
    Base class for all contract interfaces
    Governs contract interaction, execution, and event parsing.
    """
    address = None

    @abc.abstractmethod
    def call_function(self, function_name, *args):
        """
        Given a function in a contract, and the arguments to that function,
        calls it on chain
        Args:
            function_name: the name of the contract function to call
            *args: the (potentially many) arguments to pass to that function
        """
        pass

    @abc.abstractmethod
    def parse_event_from_txn(self, event_name, txn) -> List[Task]:
        """
        Given a transaction, outputs all the events of a particular name
        that were emitted in that transaction
        Args:
            event_name: the event to look for
            txn: the transaction to parse
        Returns: a list of Tasks corresponding to the events
        """
        pass
```

Any chain that implements these python interfaces can connect to the relayer, by modifying the config generation function, the current implementation of which is given below:

```python
def generate_eth_config(config_dict, provider=None):
    """
    Converts a config dict into a tuple of (chain_interface, contract_interface, event_name, function_name)
    for ethereum
    Args:
        config_dict: a dict containing contract address, contract schema, and wallet address
        provider: an optional API client

    Returns: the relevant tuple of chain, contract, event, and function

    """
    priv_key = bytes.fromhex(os.environ['ethereum-private-key'])
    address = config_dict['wallet_address']
    contract_address = config_dict['contract_address']
    contract_schema = config_dict['contract_schema']
    event_name = 'logNewTask'
    function_name = 'postExecution'
    initialized_chain = EthInterface(private_key=priv_key, address=address, provider=provider)
    initialized_contract = EthContract(interface=initialized_chain, address=contract_address,
                                       abi=contract_schema)
    eth_tuple = (initialized_chain, initialized_contract, event_name, function_name)
    return eth_tuple


def generate_scrt_config(config_dict, provider=None):
    """
        Converts a config dict into a tuple of (chain_interface, contract_interface, event_name, function_name)
        for secret
        Args:
            config_dict: a dict containing contract address, contract schema, and wallet address
            provider: an optional API client

        Returns: the relevant tuple of chain, contract, event, and function

    """
    priv_key = bytes.fromhex(os.environ['secret-private-key'])
    address = config_dict['wallet_address']
    contract_address = config_dict['contract_address']
    with open(f'{Path(__file__).parent.absolute()}/secret_abi.json') as f:
        contract_schema = f.read()
    event_name = 'wasm'
    function_name = list(json.loads(contract_schema).keys())[0]
    initialized_chain = SCRTInterface(private_key=priv_key, address=address, provider=provider)
    initialized_contract = SCRTContract(interface=initialized_chain, address=contract_address,
                                        abi=contract_schema)
    scrt_tuple = (initialized_chain, initialized_contract, event_name, function_name)
    return scrt_tuple


def generate_full_config(config_file, provider_pair=None):
    """
    Takes in a yaml filepath and generates a config dict for eth and scrt relays
    Args:
        config_file: the path to the relevant config file
        provider_pair: a pair of scrt and eth providers, optional

    Returns:
            a dict mapping scrt and eth to their respective configs

    """
    with open(config_file) as f:
        config_dict = safe_load(f)
    if provider_pair is None:
        provider_eth, provider_scrt = None, None
    else:
        provider_eth, provider_scrt = provider_pair
    eth_config = generate_eth_config(config_dict['ethereum'], provider=provider_eth)
    scrt_config = generate_scrt_config(config_dict['secret'], provider=provider_scrt)
    keys_dict = {'secret': {'verification': config_dict['secret']['contract_eth_address'],
                            'encryption': config_dict['secret']['contract_encryption_key']}}
    return {'ethereum': eth_config, 'secret': scrt_config}, keys_dict

```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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://fortress-labs.gitbook.io/snakepath/relayer/relayer-interface-architecture.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.
