# How to code an adapter?

1. [Repository Setup](#step-1-repository-setup)
2. [Project Setup](#step-2-project-setup-step-2-project-setup)
3. [Code transformer](#step-03-code-transformer)
4. [Code TVL Extractor](#step-4-code-tvl-extractor)
5. [Testing](#step-5-testing)
6. [Submit PR](#step-6-submit-a-pr)

### Step #1: Repository setup

### Step #2: Project setup Step #2: Project setup&#x20;

Now you have to set up your project directory inside [src/projects](https://github.com/xorddotcom/spock-adapters/tree/main/src/projects). The file structure of the project directory will look like this.

```
projects
├── [PROJECT_NAME]
│   └── abis
│   │   ├── contract1.json
│   │   └── contract2.json
│   ├── types
│   ├── index.test.ts
│   ├── index.ts
|   ├── tvl.ts
│   └── utils.ts
└── index.ts
```

First of all, create an abis folder in your project directory and add all the required abis of JSON format in it.

After that, you have to execute the command `yarn generate PROJECT_NAME` which will generate the types of abis through typechain. \
\
Now you are ready to code the core logic of your adapter.&#x20;

### Step # 03: Code transformer

Let's start coding from the transformer. For that, you have to create event handler functions in the `index.ts` file and add them to the adapter object which will be exported in the end.

Here we have an example of a Uniswap V3 mint event handler.

{% code overflow="wrap" %}

```
export async function mintEvent(event: types.Event<MintEventObject>) {
  const pool = await uniswapV3Pool.getPool(event.address, event.chain);
  if (pool) {
    const [block, transaction] = await Promise.all([event.block, event.transaction]);
    const totalSum = await sumBalancesUSD(
      [
        { token: pool.token0, balance: event.params.amount0 },
        { token: pool.token1, balance: event.params.amount1 },
      ],
      event.chain,
      block.timestamp,
    );
    return utils.ProtocolValue.contribution({
      label: Label.DEPOSIT,
      value: parseFloat(totalSum.toString()),
      user: transaction.from,
    });
  }
}

```

{% endcode %}

In the end, return these events handlers w\.r.t to their contract and chain in transformers.

{% code overflow="wrap" %}

```
const uniswapAdapter: types.Adapter = {
  appKey: "70dbe55c4987d9ac9d84605d9edb8e6781bae2d631d649e176656e6bd3642fd9",
  transformers: {
    [constants.Chain.ETHEREUM]: [
      {
        contract: pool,
        eventHandlers: {
          [MINT]: mintEvent,
          [BURN]: burnEvent,
        },
        startBlock: 12369621,
      },
    ],
  },
};

export default uniswapAdapter;
```

{% endcode %}

{% hint style="info" %}
You can add all the helper functions, constants, types, and other coding stuff in the `utils.ts`of your project to keep them separate from more transformer codes.&#x20;
{% endhint %}

### Step #4: Code TVL Extractor

For the TVL tracking of your protocol, you have to create an extractor function in the `tvl.ts` which will return the balances of the asset locked inside your protocol. \
\
Here we have an example of BullionFx TVL computation.

{% code overflow="wrap" %}

```
export async function computeTVL(chain: constants.Chain, block: number, timestamp: number) {
  const balances: SummedBalances = {};

  const pairs = await pairAddresses(chain, block);
  if (pairs) {
    const calls = pairs.flatMap((pair) => [
      new abi.Call<BullPair>({ address: pair, contractInterface: bullPair, fragment: "token0" }),
      new abi.Call<BullPair>({ address: pair, contractInterface: bullPair, fragment: "token1" }),
      new abi.Call<BullPair>({ address: pair, contractInterface: bullPair, fragment: "getReserves" }),
    ]);

    const results = await abi.Multicall.execute({ chain, calls, blockNumber: block });

    utils.chunk(results, 3).forEach((result) => {
      sumSingleBalance(balances, result[0].output, result[2].output[0]);
      sumSingleBalance(balances, result[1].output, result[2].output[1]);
    });
  }

  return balances;
}
```

{% endcode %}

### Step #5: Testing

In the end, after you are done with the adapter development, you can write tests for validating the transformers and TVL extractors' logic. For that, you have to write tests in the `index.test.ts` file of your project.

### Step #6: Submit a PR

Once all the above steps are completed, your adapter is ready for syncing, push the code and create PR on the main branch of [xorddotcom/spock-adapters](https://github.com/xorddotcom/spock-adapters).&#x20;

A member of our team will then review and merge your code with the main branch.

## Need Help? Contact Our Team

If you encounter any difficulties, have suggestions, or would like to provide feedback, feel free to contact us [here](https://discord.gg/4pG5D2FN) or email our team at <support@spockanalytics.xyz>


---

# Agent Instructions: 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://spock-analytics.gitbook.io/introduction/configuration/adapter/how-to-code-an-adapter.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.
