---
description: You can code an adapter for your project by simply following these steps.
---

# How to code an adapter?



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

### Step #1: Repository setup

1. The first thing you have to do is to fork the spock-adapters repo on your GitHub workspace.\
   [Fork spock-adapters repo](https://github.com/xorddotcom/spock-adapters/fork)
2. You have to clone the forked repo in your local machine.&#x20;
3. Install dependencies through `yarn install.`
4. Prepare adapters through `yarn prepare.`

### 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 lineNumbers="true" %}
```typescript
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.

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

export default uniswapAdapter;
```

{% 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.

```typescript
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;
}
```

### 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). \


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

## Need Help? Contact Our Team

If you are stuck anywhere or have a suggestion or feedback, you can fill out the form [here](https://docs.google.com/forms/d/e/1FAIpQLSfbhYn6JJmU658df6aJnhoQ8COR47mhZDXw6L370IxOL7L6cA/viewform), or reach out to our team at support@spockanalytics.xyz.
