Partner Events

Create campaign rules with the LitVMSwap subgraph

Use our Goldsky subgraph endpoint to find wallets that swapped, added V2 liquidity, or added V3 liquidity. This page gives you the exact queries and flow a partner needs to launch an event quickly.

Goldsky GraphQL Endpoint
https://api.goldsky.com/api/public/project_cmrgg88kjt8sw01wxhc9476jr/subgraphs/flipswap-v2/1.0.3/gn

How event setup works

The easiest pattern is: define the rule, query eligible wallets from the subgraph, dedupe them in your backend, then store the campaign result in your own database or reward system.

1

Pick the event rule

Examples: do 3 swaps, add V2 liquidity once, add V3 liquidity once.

You can also combine rules, like at least 3 swaps and at least 1 V2 liquidity add.

2

Query the subgraph

Send a GraphQL POST request to the Goldsky endpoint. Query either user summary entities or the unified liquidityProvisions entity for campaign-ready liquidity checks across V2 and V3.

3

Verify and reward

Your backend should dedupe wallet addresses, check timestamps if your campaign has a start date, then mark users as eligible for rewards, whitelists, points, or NFTs.

Protocol addresses

For transparency, here are the main LitVMSwap contracts used in the partner event flow. Each address can be copied separately.

V2 Factory0x4680BCe1632824d30D2F53656dD610736c3e312e
V2 Router0xF456737D17C2Bbb348fd4F7D1b000D62A46FB3b5
Aggregator Router0x9A3158beBDEFd2C9DD9D00e6B14F66E1c5E7d514
Aggregator Entrypoint0x5E19EB2A6BA30892CCe33f93D7Fb24D498512266
Aggregator Points Wrapper0xF664B56933f3cF0d7d69982b5A8eC9101b80059D
V3 Factory0xde6763a041f8fc94ca2ee5933736f78f6d1a11c5
V3 Router0x60F8A7642F0aeC06cE628224E743326B23Fe5208
V3 NFT Descriptor0xe8ceA54a982665C4E75fD00B6de5d515313d9BA3
V3 NFT Position Descriptor0xEC66f561432c3205838127fFa108877e421dC16a
V3 Position Manager0x1089f046B597f259BeFDC15Bf9C90E33616BA366
V3 Migrator0x89dd9B1757C94b1F570090cc6C74B1dE2910429c

Ready event recipes

These are the most common partner campaign patterns for your DEX.

Event 1: Do 3 swaps, any amount

This uses the aggregated users entity and checksaggregatorSwapCount_gte: "3".

GraphQL Query
query CampaignUsers {
  users(
    first: 100
    orderBy: aggregatorSwapCount
    orderDirection: desc
    where: { aggregatorSwapCount_gte: "3" }
  ) {
    id
    aggregatorSwapCount
    lastSeenTimestamp
  }
}

Event 2: Add liquidity on V2

Use liquidityProvisions with protocolVersion: "V2" to get the user wallet, the two tokens, the market id, and the added amounts.

GraphQL Query
query V2LiquidityProviders {
  liquidityProvisions(
    first: 100
    orderBy: timestamp
    orderDirection: desc
    where: { protocolVersion: "V2" }
  ) {
    id
    user {
      id
    }
    marketId
    token0 {
      symbol
    }
    token1 {
      symbol
    }
    amount0Decimal
    amount1Decimal
    timestamp
  }
}

If you want to verify whether one wallet added liquidity, query liquidityProvisions with where: { protocolVersion: "V2", user: "0xUSER_ADDRESS" }.

Single Wallet V2 Check
query V2LiquidityUserCheck {
  liquidityProvisions(
    first: 100
    orderBy: timestamp
    orderDirection: desc
    where: {
      protocolVersion: "V2"
      user: "0xUSER_ADDRESS"
    }
  ) {
    id
    user {
      id
    }
    marketId
    token0 { symbol }
    token1 { symbol }
    amount0Decimal
    amount1Decimal
    timestamp
  }
}

Event 3: Add liquidity on V3

Use liquidityProvisions with protocolVersion: "V3" to get the wallet, tokens, market id, and amounts added.

GraphQL Query
query V3LiquidityProviders {
  liquidityProvisions(
    first: 100
    orderBy: timestamp
    orderDirection: desc
    where: { protocolVersion: "V3" }
  ) {
    id
    user {
      id
    }
    marketId
    token0 {
      symbol
    }
    token1 {
      symbol
    }
    amount0Decimal
    amount1Decimal
    timestamp
  }
}

For a single wallet check, query liquidityProvisions with where: { protocolVersion: "V3", user: "0xUSER_ADDRESS" }. Any returned row means that wallet added V3 liquidity.

Single Wallet V3 Check
query V3LiquidityUserCheck {
  liquidityProvisions(
    first: 100
    orderBy: timestamp
    orderDirection: desc
    where: {
      protocolVersion: "V3"
      user: "0xUSER_ADDRESS"
    }
  ) {
    id
    user {
      id
    }
    marketId
    token0 { symbol }
    token1 { symbol }
    amount0Decimal
    amount1Decimal
    timestamp
  }
}

Token-specific campaigns

If a partner wants to reward users for interacting with a specific token, queryuserTokenStats using the token address.

Token Interaction Query
query TokenCampaign {
  userTokenStats(
    first: 100
    orderBy: aggregatorSwapInCount
    orderDirection: desc
    where: {
      token: "0xTOKEN_ADDRESS"
      aggregatorSwapInCount_gte: "1"
    }
  ) {
    user {
      id
    }
    token {
      symbol
    }
    aggregatorSwapInCount
    aggregatorSwapOutCount
    v2SwapCount
    v3SwapCount
  }
}

How to call the endpoint

You can call the subgraph from your backend, partner dashboard, or event automation service.

cURL Example
curl -X POST "https://api.goldsky.com/api/public/project_cmrgg88kjt8sw01wxhc9476jr/subgraphs/flipswap-v2/1.0.3/gn" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query CampaignUsers { users(first: 100, orderBy: aggregatorSwapCount, orderDirection: desc, where: { aggregatorSwapCount_gte: \"3\" }) { id aggregatorSwapCount lastSeenTimestamp } }"
  }'
JavaScript Example
const endpoint = "https://api.goldsky.com/api/public/project_cmrgg88kjt8sw01wxhc9476jr/subgraphs/flipswap-v2/1.0.3/gn";

const query = `
  query CampaignUsers {
    users(
      first: 100
      orderBy: aggregatorSwapCount
      orderDirection: desc
      where: { aggregatorSwapCount_gte: "3" }
    ) {
      id
      aggregatorSwapCount
      lastSeenTimestamp
    }
  }
`;

const response = await fetch(endpoint, {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ query })
});

const data = await response.json();
console.log(data.data.users);
Raw JSON Body
{
  "query": "query CampaignUsers {\n  users(\n    first: 100\n    orderBy: aggregatorSwapCount\n    orderDirection: desc\n    where: { aggregatorSwapCount_gte: \"3\" }\n  ) {\n    id\n    aggregatorSwapCount\n    lastSeenTimestamp\n  }\n}"
}

Practical notes

Use a new subgraph versionWhen you change schema, mappings, or start block, deploy a new Goldsky version so you are not reading stale indexing state.
Filter by campaign windowFor time-based events, query raw event entities like aggregatorSwaps or use liquidityProvisions with timestamp filtering in your own backend flow.
Dedupe walletsRaw event entities can return multiple records per user. Always dedupe by wallet address before final eligibility checks.
Pair and pool targetingIf you want a campaign for one pair or one V3 pool only, add a pair or pool filter in the query before rewarding users.
V2 and V3 liquidity checks need pair or pool discoveryLiquidity add filters come from liquidityProvisions, which are built from V2 and V3 mint events. For them to exist, the subgraph must have seen the relevant V2 PairCreated or V3 PoolCreated event first, or you must register older existing pairs or pools in the subgraph config.