# 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
}
}
}
}
}
```