{"id":26162494,"url":"https://github.com/balancer/backend","last_synced_at":"2025-04-14T13:30:24.978Z","repository":{"id":216312467,"uuid":"737739413","full_name":"balancer/backend","owner":"balancer","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-10T11:35:21.000Z","size":10465,"stargazers_count":35,"open_issues_count":74,"forks_count":13,"subscribers_count":2,"default_branch":"v3-canary","last_synced_at":"2025-04-10T11:46:49.301Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"beethovenxfi/beethovenx-backend","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/balancer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-01T10:06:33.000Z","updated_at":"2025-04-10T11:03:31.000Z","dependencies_parsed_at":"2024-12-23T17:36:39.512Z","dependency_job_id":"9af0b73b-ef8c-4bba-9b41-71f6d6ecfcd7","html_url":"https://github.com/balancer/backend","commit_stats":null,"previous_names":["balancer/beethovenx-backend","balancer/backend"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Fbackend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Fbackend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Fbackend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Fbackend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/balancer","download_url":"https://codeload.github.com/balancer/backend/tar.gz/refs/heads/v3-canary","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248888519,"owners_count":21178073,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-11T13:54:42.476Z","updated_at":"2025-04-14T13:30:24.900Z","avatar_url":"https://github.com/balancer.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Balancer API\n\nWelcome to Balancer's API. This guide will help you get started with using the API and accessing the data locked in Balancer's contracts.\n\n## Getting started\n\nThe API is running as a graphql server and is deployed at: [https://api-v3.balancer.fi](https://api-v3.balancer.fi)\n\n## Use cases\n\nQueries are organised around these main domains:\n\n-   Pools\n    -   poolGetPool\n    -   poolGetPools\n-   Gauges\n    -   veBalGetUser\n    -   veBalGetUserBalance\n    -   veBalGetVotingList\n-   Events\n    -   poolGetEvents\n-   Users\n    -   userGetPoolBalances\n    -   userGetStaking\n-   Tokens\n    -   tokenGetTokens\n    -   tokenGetTokenDynamicData\n    -   tokenGetTokensDynamicData\n    -   tokenGetTokenData\n    -   tokenGetTokensData\n-   Prices\n    -   tokenGetCurrentPrices\n    -   tokenGetHistoricalPrices\n-   SOR\n    -   sorGetSwapPaths\n\nTo query specific data refer to the [API's documentation](https://api-v3.balancer.fi/). Click top left to show the Documentation Explorer.\n\nMost of the queries will take one or multiple `chain` as an argument. The usage of the `chainId` header is deprecated!\n\n## Examples\n\nHow to get the pool's details including APRs.\n\n```\n{\n  poolGetPool(id: \"0x7f2b3b7fbd3226c5be438cde49a519f442ca2eda00020000000000000000067d\", chain:MAINNET) {\n    id\n    name\n    type\n    version\n    allTokens {\n      address\n      name\n    }\n    poolTokens {\n      address\n      symbol\n      balance\n      hasNestedPool\n    }\n    dynamicData {\n      totalLiquidity\n      aprItems {\n        title\n        type\n        apr\n      }\n    }\n  }\n}\n```\n\nQuery all pools on Arbitrum and Avalanche that have TVL greater than $10k:\n\n```\n{\n  poolGetPools(where: {chainIn: [AVALANCHE, ARBITRUM], minTvl: 10000}) {\n    id\n    address\n    name\n  }\n}\n```\n\nQuery the SOR to swap 1 WETH to USDC\n\n```\n{\n  sorGetSwapPaths(\n    chain: MAINNET\n    swapAmount: \"1\"\n    swapType: EXACT_IN\n    tokenIn: \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\"\n    tokenOut: \"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\"\n  ) {\n    swapAmountRaw\n    returnAmountRaw\n    priceImpact {\n      priceImpact\n      error\n    }\n  }\n}\n```\n\n## Pricing of tokens\n\nFirst of all, for a token to be able to have a price it must be allowed, meaning it must be added to the [tokenlist](https://github.com/balancer/tokenlists). This must happen _before_ any pricing can occur.\n\nTo price a token there are various handlers that will try to price a token. These handlers take priority over each other. This means that as soon\nas a handler can price a token, it will not be price by another handler. These handlers, order by priority, are:\n\n1. Protocol specific handlers such as Aave or fbeets where prices can be infered via on-chain calls and underlying token prices\n2. Coingecko\n3. BPT price handler ($TVL/totalShares)\n4. Swaps (When ever a token is swapped with a token that has a price, the original token's price is inferred relative to the swapped token)\n\nIn addition to this, there are manual interventions possible:\n\n1. If a token has a wrong Coingecko feed, it can be excluded by adding [an override](https://github.com/balancer/tokenlists/blob/main/src/tokenlists/balancer/overwrites.ts#L406) like this `extensions: { coingeckoId: null, },`.\n2. If a token does not have a Coingecko feed on a specific chain, or can be priced using a different token's Coingecko feed, the Coingecko ID can [be overridden](https://github.com/balancer/tokenlists/blob/main/src/tokenlists/balancer/overwrites.ts#L393) with another ID like this `extensions: { coingeckId: 'gyroscope-gyd', },`.\n\n# Development\n\n## Project setup\n\n### Prepare .env file\n\nRename `env.local` file to `.env`.\n\nFor the sanity content to work, you need to set\nthe `SANITY_API_TOKEN`.\n\n### Generate gql types\n\nThere are 2 kinds of graphql types to generate. We have types for interacting with the different subgraphs, and the types\nfor our exposed graphql api schema.\nRun `yarn generate` to generate all gql types\n\n### Setup empty database \u0026 Prisma\n\n#### Start docker container and manually set up your database (For setup from backup, read below)\n\nFirst we need to spin up the database, there is a `docker-compose` file with a postgres\ndatabase configured. Spin it up by running `docker-compose up -d`.\n\n#### Apply prisma migrations\n\nRun `yarn prisma migrate dev` to apply all database migrations.\n\n#### Generate prisma client\n\nRun `yarn prisma generate` to generate the prisma client. Usually this is already\ndone by applying the migrations\n\n#### Run mutations to initialize fill database with intial data\n\nTrigger the following mutations when you start from a clean DB:\n\n```\npoolSyncAllPoolsFromSubgraph\npoolReloadStakingForAllPools\nuserInitWalletBalancesForAllPools\nuserInitStakedBalances\n```\n\nYou can do that by starting the server in development mode with hot reloading and calling the methods via API playground, or curl from the shell:\n\n```\ncurl -d '{\"query\":\"mutation { poolSyncAllPoolsFromSubgraph }\"}' -H 'Content-Type: application/json' -H 'chainId: 1' -H \"AdminApiKey: $(grep '^ADMIN_API_KEY=' .env | cut -d '=' -f2)\" http://localhost:4000/graphql\n```\n\n### Setup database \u0026 Prisma from backup\n\nRetrieve the current pg_dump file under `https://api-db-dump.s3.eu-central-1.amazonaws.com/canary/api-dump.YYYYMMDD`.\nDatabase dumps are kept for the previous 7 days, replace YYYYMMDD in the URL above (ie: 20230317) to download a db dump.\n\nRun `docker-compose up -d` to start the database via docker compose.\n\nRun `docker exec -i $(docker ps -qf \"name=balancer-backend\") /bin/bash -c \"PGPASSWORD=let-me-in psql --username backend database\" \u003c /path/on/your/machine/dump`\n\nThe output at the very end saying `ERROR: role \"rdsadmin\" does not exist` is normal and can be ignored.\n\n## Run locally\n\n`yarn dev`\n\n## Branching and deployment environments\n\nWe run a canary and a production (called main) deployment environment.\nThe canary environment is built from the `v3-canary` branch and the production deployment\nis built from the `v3-main` branch. The environments can be accessed through the following links:\n\nhttps://backend-v3.beets-ftm-node.com/\n\nhttps://api-v3.balancer.fi/\n\n## Contributing\n\nTo contribute, branch from `v3-canary` (which is our development branch) and open a PR against `v3-canary` once the feature is complete. It will be reviewed and eventually merged into v2-canary.\n\n### Database Updates\n\nIf you make any changes to the database schema be sure to run `yarn prisma migrate dev --name \u003cchange_name\u003e` which will create a new file in `prisma/migrations` that contains all the database changes you've made as an SQL update script.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbalancer%2Fbackend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbalancer%2Fbackend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbalancer%2Fbackend/lists"}