---
# System prepended metadata

title: Untitled

---

# Subquery Integration Tutorial

SubQuery provides a [quick start tutorial](https://academy.subquery.network/quickstart/quickstart_chains/cosmos-osmosis.html) that indexes all swaps on Osmosis' on chain DEX. This tutorial builds on the quickstart and adds indexing for `SwapExactAmountOut`.

There are 3 steps when creating a SubQuery project. 
* Update the schema file
* Update the project manifest file
* Update the mappings file

## 0. Update end point & block height

endpoint to be used can be found in project.ts
query latest block height and make sure node has the block information


https://rpc.osmosis.zone/status?


edit startBlock to latest height


## 1. Update `graphql` schema

Add new types we want to be parsing to the existing schema.graphql file.

```
type SwapOut @entity {
  id: ID!
  sender: String!
  txHash: String!
  blockHeight: BigInt!
  tokenOutDenom: String
  tokenOutAmount: BigInt
  tokenInMax: BigInt!
  swapOutRoutes: [SwapOutRoute] @derivedFrom(field: "swap") #This is virtual field
}

type SwapOutRoute @entity {
  id: ID!
  pool: Pool!
  swap: SwapOut!
  tokenInDenom: String!
  tokenOutDenom: String
}

type PoolOut @entity {
  id: ID!
  swapOutRoutes: [SwapOutRoute] @derivedFrom(field: "pool") #This is virtual field
}
```

Then run `yarn codegen` to generate code based off this new schema.

> When you make any changes to the schema file, do not forget to regenerate your types directory.

## 2. Update the project manifest file (`project.ts`)

a) Declare the chain types. These point to protobuf files that defines the format of the message to help the SubQuery project understand how to parse the data.

The following chain types should be added to the existing chain types. Double check that the various .proto files are available and accessible by the project. 

https://github.com/osmosis-labs/osmosis/blob/main/proto/osmosis/gamm/v1beta1/tx.proto#L16

```
chaintypes: new Map([
      [
        "osmosis.gamm.v1beta1",
        {
          file: "./proto/osmosis/gamm/v1beta1/tx.proto",
          messages: ["MsgSwapExactAmountIn", "MsgSwapExactAmountOut"],
        },
      ],
      [
        " osmosis.poolmanager.v1beta1",
        {
          // needed by SwapAmountOutRoute
          file: "./proto/osmosis/poolmanager/v1beta1/swap_route.proto",
          messages: ["SwapAmountOutRoute"],
        },
      ],
      [
        " osmosis.poolmanager.v1beta1",
        {
          // needed by MsgSwapExactAmountIn
          file: "./proto/osmosis/poolmanager/v1beta1/swap_route.proto",
          messages: ["SwapAmountInRoute"],
        },
      ],
      [
        "cosmos.base.v1beta1",
        {
          // needed by MsgSwapExactAmountIn
          file: "./proto/cosmos/base/v1beta1/coin.proto",
          messages: ["Coin"],
        },
      ],
    ]),
  },
```



Add a handler in `dataSources`. This handler will be triggered when the filter criteria is met. 

```
{
            handler: "handleOutMsg",
            kind: CosmosHandlerKind.Message,
            filter: {
              type: "/osmosis.gamm.v1beta1.MsgSwapExactAmountOut",
            },
          },
          
          
```

## 3. Update the mappings file (`mappingHandlers.ts`)

3. Define handler for swap out message. This is the function that will be executed when a swap out message is encountered in the manifest file. 

```


export async function handleOutMsg(
  msg: MsgSwapExactAmountOutMessage
): Promise<void> {
  // You can see an example record here https://www.mintscan.io/osmosis/txs/6A22C6C978A96D99FCB08826807C6EB1DCBDCEC6044C35105B624A81A1CB6E24?height=9798771
  logger.info(`New Swap Out Message received at block ${msg.block.header.height}`);
  // logger.info(JSON.stringify(msg.tx.tx.events)); // You can use this to preview the data

  // We first create a new swap record
  const swap = SwapOut.create({
    id: `${msg.tx.hash}-${msg.idx}`,
    txHash: msg.tx.hash,
    blockHeight: BigInt(msg.block.block.header.height),
    sender: msg.msg.decodedMsg.sender,
    tokenOutDenom: msg.msg.decodedMsg.tokenOut?.denom,
    tokenOutAmount: msg.msg.decodedMsg.tokenOut
      ? BigInt(msg.msg.decodedMsg.tokenOut.amount)
      : undefined,
    tokenInMax: BigInt(msg.msg.decodedMsg.tokenInMaxAmount),
  });

  // Save this to the DB
  await swap.save();

  // Create swap routes from the array on the message
  let lastTokenOutDenom = swap.tokenOutDenom;
  for (const route of msg.msg.decodedMsg.routes) {
    const index = msg.msg.decodedMsg.routes.indexOf(route);
    // Check that the pool aready exists
    const pool = await checkGetPoolOut(route.poolId.toString());

    const swapRoute = SwapOutRoute.create({
      id: `${msg.tx.hash}-${msg.idx}-${index}`,
      poolId: pool.id,
      swapId: swap.id,
      tokenInDenom: route.tokenInDenom,
      tokenOutDenom: lastTokenOutDenom,
    });
    lastTokenOutDenom = route.tokenInDenom;
    await swapRoute.save();
  }
}
```

yarn codegen
yarn build

Once all the changes have been completed, build the project with the command `yarn build` and then start the project with the command `yard start:docker`. (Ensure Docker is running).

To test the project, open up the playground at `http://localhost:3000/` and run the following graphql query:

```
{
  query {
    swaps(first: 5) {
      nodes {
        id
        sender
        tokenOutDenom
        tokenOutAmount
        tokenInMax
        swapRoutes(first: 5) {
          totalCount
        }
      }
    }
  }
}
```