{"id":26162506,"url":"https://github.com/balancer/balancer-api","last_synced_at":"2025-04-14T13:30:34.459Z","repository":{"id":36966539,"uuid":"431901370","full_name":"balancer/balancer-api","owner":"balancer","description":null,"archived":false,"fork":false,"pushed_at":"2024-05-07T10:58:38.000Z","size":1727,"stargazers_count":15,"open_issues_count":4,"forks_count":16,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-05-07T11:49:22.637Z","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":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/balancer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","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":"2021-11-25T15:56:26.000Z","updated_at":"2024-05-20T14:46:39.783Z","dependencies_parsed_at":"2023-02-17T05:00:20.044Z","dependency_job_id":"6419c430-0d0a-498b-bce6-507b99d55ce4","html_url":"https://github.com/balancer/balancer-api","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Fbalancer-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Fbalancer-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Fbalancer-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Fbalancer-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/balancer","download_url":"https://codeload.github.com/balancer/balancer-api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248888526,"owners_count":21178075,"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:45.990Z","updated_at":"2025-04-14T13:30:34.426Z","avatar_url":"https://github.com/balancer.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ⛔️ This API is now deprecated\n\nWe have a new API for the Balancer protocol, which is available here\n[https://github.com/balancer/backend](https://github.com/balancer/backend). Or\nsee the docs here [https://docs-v3.balancer.fi/data-and-analytics/data-and-analytics/balancer-api.html](https://docs-v3.balancer.fi/data-and-analytics/data-and-analytics/balancer-api.html).\n\n1. There will be no more support or fixes to this API.\n2. We will gradually decrease rate limits starting from the end of October.\n3. The deployed API at https://api.balancer.fi will be shutdown by the end of\n   November.\n\nIf you have any questions please ask in Discord: [https://discord.balancer.fi/](https://discord.balancer.fi/)\n\n# Balancer Pools API\n\nA service that acts as a caching layer for Balancer Pools information. This service runs using AWS Lambda, DynamoDB, API Gateway and AppSync.\nThis was built to speed up frontend queries, and for services such as Gnosis to use to route orders through Balancer pools.\n\nThis package consists of CDK scripts that setup all the required infrastructure, and code for all the lambdas and services involved.\n\nIt has the following components:\n\n- A DynamoDB database that hold Balancer pool information with tokens and current balances.\n- A Lambda that fetches the latest data from the graph / infura and updates the database.\n- An API Gateway server and set of lambdas that handle user requests.\n- An AppSync GraphQL endpoint for loading decorated pools.\n\n## Disclaimers\n\nThis software is in Alpha and may have breaking changes at any time. There is little security implemented on the Lambda\nfunctions or GraphQL interface so anyone can call them.\n\n## Requirements\n\n- NodeJS 14.X (others may work, not tested yet)\n- An Infura Account (for retrieving pool information, this is free to create)\n- Docker + Docker Compose (for local development)\n- An AWS Account (for AWS development)\n\n## Usage\n\nThis package can be run locally for development, or deployed to an AWS account. AppSync cannot be used locally.\n\n### Initial Setup\n\n```bash\nnpm install\nnpm run build\ncp .env.example .env\n```\n\nOpen the `.env` file and set `INFURA_PROJECT_ID` to your personal [Infura](https://infura.io/) project ID.\n\n### Local Development\n\nThis runs a local DynamoDB in a docker container, a worker process that polls for new information, and an express server to handle requests.\n\n```sh\n# Run a local DynamoDB Database\nnpm run dynamodb\n\n# Create Tables\nnpm run init\n\n# NOTE: If the init command hangs, you may need to fix permissions on your dynamodb data folder. You can do this with:\nsudo chown -R $(whoami):docker ./docker\n\n# Run Worker\nnpm run worker\n\n# In another terminal, Run API Server\nnpm start\n```\n\nThe API server runs on port 8090, you can run queries against the endpoint `http://localhost:8090/`\n\n### AWS Development\n\nInstall AWS SDK\n\n```sh\nnpm install -g aws-cdk\n```\n\nYou may also need to install the [AWS CLI](https://aws.amazon.com/cli/) and [configure your credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) if you have not already done so.\n\n#### (Optional) Creating a scoped-down deployer user\n\nIf you wish to create an AWS user with the bare minimum permissions required to deploy this stack, see the [deployer permissions json file](./config/deployer-permissions.json). Copy this into a new policy, then create a new user and attach that policy to them, and use their credentials for deploying.\n\n#### Bootstraping + Deploying CDK\n\nIf you've never used CDK before in your account you need to run the following bootstrap command with your account id and region.\n\n```sh\ncdk bootstrap aws://$AWS_ACCOUNT_ID/$AWS_REGION\n```\n\nDeploy / Redeploy all AWS Services to your account.\n\n```sh\nnpm run build # Compile the CDK index.ts to javascript, must be run after changes are made\nnpm run deploy # Run CDK to create/update your infrastructure\n```\n\nAfter the deployment you will get an API URL that looks similar to `https://gtrabwaex9.execute-api.ap-southeast-2.amazonaws.com/prod/` this is\nyour API Gateway URL, all endpoints below should be appended to this. Run `export ENDPOINT_URL=\u003cyour API url\u003e` to be able to copy and paste the example queries below.\n\n## Tests\n\n### Unit Tests\n\n```\nnpm run test\n```\n\n### E2E Tests\n\nThese E2E tests perform SOR requests to the /sor and /order endpoints, then run that swap on-chain using a Hardhat forked environment. They require you to have the\nAPI running somewhere, and a Hardhat network running.\n\nBefore Starting set the following variables in your .env file:\n\n- `RPC_URL` - URL to your ETH node or Infura/Alchemy/etc. Will use infura with `INFURA_PROJECT_ID` if set.\n- `ENDPOINT_URL` - URL of your API instance - Defaults to `https://api.balancer.fi/`\n\nThen run the following:\n\n```\n# This starts the forked hardhat\nnpm run node\n\n# In another terminal\nnpm run test:e2e\n```\n\n## Infrastructure Overview\n\nNote: Everything inside the AWS container is setup by the CDK scripts in this repository. You'll need to manually configure any external services, such as Alchemy event triggers.\n\n![](./pools-api-diagram.png)\n\n## API Gateway Endpoints\n\nThe `{chainId}` in each endpoint is the chain/network number you wish to request from. 1 for Mainnet, 137 for Polygon, 42161 for Arbitrum etc.\n\n- `/graphql` - GraphQL endpoint for retrieving pools with filters / queries. Forwards requests to Appsync. See 'GraphQL Requests' section for more info.\n- `/pools/{chainId}/update` - Runs the worker lambda that fetches the latest pool information from the graph and saves it in the database.\n- `/pools/{chainId}` - Returns a JSON array of all Balancer pools of that chain\n- `/pools/{chainId}/{id}` - Returns JSON information about a pool of a specific `id`.\n- `/sor/{chainId}` - Run a SOR (Smart Order Router) query against the balancer pools and returns [SerializedSwapInfo](./src/modules/sor/types.ts).\n- `/order/{chainId}` - Run a SOR (Smart Order Router) query against the balancer pools and returns a [SorOrderResponse](./src/modules/sor/types.ts).\n- `/tokens/{chainId}` - Returns a JSON array of all known tokens of that chain\n- `/tokens/update/` - Runs the worker lambda that for every known token, fetches the latest price (in the chains native asset) from coingecko and saves it in the database.\n\n- `/check-wallet` - Used to perform sanctions checks with TRM.\n- `/tenderly/contracts/encode-states` - Encodes state information with Tenderly\n- `/tenderly/simulate` - Simulate a transaction with Tenderly\n\n### Update Pools Lambda\n\nThe update lambda is not called automatically, you must call it to initially poplate the database. We recommend connecting a webhook to\nthis endpoint that runs with every new Ethereum block, or whenever a transaction is made to the [Balancer Vault Contract](https://etherscan.io/address/0xba12222222228d8ba445958a75a0704d566bf2c8).\n\nOnly one instance of this lambda can run at a time per network. If you attempt to run it twice the second call will return a 500 Internal Server Error.\n\nUpdate for Ethereum Mainnet\n\n```sh\ncurl -X POST $ENDPOINT_URL/pools/1/update\n```\n\nUpdate pools for Polygon PoS\n\n```sh\ncurl -X POST $ENDPOINT_URL/pools/137/update\n```\n\nOn success this will return a 201 code and no other data.\n\n### Decorate Pools Lambda\n\nThis lambda runs on a timer controlled by the environment variable `DECORATE_POOLS_INTERVAL_IN_MINUTES`, defaulting to 5 minutes.\nIt loads all the latest token and pool data and calculates the following for each pool:\n\n- Total Liquidity\n- APR information\n- Volume in last 24hrs\n- Fees in last 24hrs\n\nIt then saves this information back out to the database. This is so that pools can be fetched in one call to the GraphQL API and contain\nall neccessary data to display them in the Balancer App.\n\n### Get Pools Lambda\n\nRetrieve JSON array of all pools\n\n```sh\ncurl $ENDPOINT_URL/pools/1\n```\n\n### Get Single Pool Lambda\n\nRetrieve JSON object describing a single pool\n\n```sh\ncurl $ENDPOINT_URL/pools/1/0x5aa90c7362ea46b3cbfbd7f01ea5ca69c98fef1c000200000000000000000020\n```\n\n### Update Token Prices Lambda\n\nThe lambda is automatically called every 30 seconds.\n\nExample token prices update\n\n```sh\ncurl -X POST $ENDPOINT_URL/tokens/update/\n```\n\nOn success this will return a 201 code and no other data.\n\n### Smart Order Router Queries\n\nThe [Smart Order Router](https://github.com/balancer-labs/balancer-sor) is a package created by Balancer that, for any given\ninput and output token, finds you the best trade path across all Balancer pools. It is used by the Balancer frontend to calculate\ntrades.\n\nYou can POST the following JSON content to the endpoints `/sor` or `/order` to return smart order router information.\n\n```js\n{\n    sellToken: string\u003cAddress\u003e, # The address of the token you wish to sell\n    buyToken: string\u003cAddress\u003e, # The address of the token you wish to buy\n    orderKind: string\u003cbuy|sell\u003e, # Either 'buy' or 'sell', described further below\n    amount: int, # The amount in sellToken or buyToken that you wish to sell/buy\n    gasPrice: int, # The current gas price in wei, this is used to ensure your trade is most efficient considering the gas cost of performing multiple swaps.\n\n    # The following are for /order only\n    sender: string\u003cAddress\u003e, # The address of the wallet sending sellToken.\n    receiver: string\u003cAddress\u003e, # The address of the wallet which should receive buyToken.\n    slippagePercentage: float (default 0.01), # The total slippage to allow in this order. 0.01 = 1%.\n}\n```\n\nOrder Kind - Set to 'buy' to buy the exact amount of your `buyToken` and sell as little as possible to get that. Set to 'sell' to sell the exact amount of your `sellToken` and buy as much as you can with that.\n\n#### Return Values\n\n##### /sor Endpoint\n\nThe `/sor` endpoint returns [SerializedSwapInfo](./src/modules/sor/types.ts) which contains all the swaps and order information, but you must assemble the transaction to make this swap yourself.\n\n##### /order Endpoint\n\nThe `/order` endpoint returns a [SorOrderResponse](./src/modules/sor/types.ts) which contains transaction data that you can immediately post to chain.\n\nSometimes the returned order needs to be sent to the Balancer Batch Relayer (the `to` address will be the batch relayer). When this happens you must first approve the relayer with the Balancer vault so that it can make swaps on your behalf. You can do this by calling `setRelayerApproval(walletAddress, relayerAddress, true)` on the Balancer vault, see an example in the [E2E Test Helpers](./tests/lib/helpers.ts) file.\n\n### Smart Order Router Examples\n\n#### Swap BAL for DAI\n\n```sh\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"sellToken\":\"0xba100000625a3754423978a60c9317c58a424e3d\",\"buyToken\":\"0x6b175474e89094c44da98b954eedeac495271d0f\",\"orderKind\":\"sell\", \"amount\":\"1000000000000000000\", \"gasPrice\":\"10000000\"}' $ENDPOINT_URL/sor/1\n```\n\n#### Swap USDC for DAI\n\n```sh\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"sellToken\":\"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\",\"buyToken\":\"0x6b175474e89094c44da98b954eedeac495271d0f\",\"orderKind\":\"sell\", \"amount\":\"100000\", \"gasPrice\":\"10000000\"}' $ENDPOINT_URL/sor/1\n```\n\n#### Swap WETH for an exact amount of BAL\n\n```sh\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"sellToken\":\"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\",\"buyToken\":\"0xba100000625a3754423978a60c9317c58a424e3d\",\"orderKind\":\"buy\", \"amount\":\"1000000000000000000\", \"gasPrice\":\"10000000\"}' $ENDPOINT_URL/sor/1\n```\n\n#### Swap BAL for DAI on the Polygon network\n\n```sh\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"sellToken\":\"0x9a71012B13CA4d3D0Cdc72A177DF3ef03b0E76A3\",\"buyToken\":\"0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174\",\"orderKind\":\"sell\", \"amount\":\"1000000000000000000\", \"gasPrice\":\"10000000\"}' $ENDPOINT_URL/sor/137\n```\n\n#### Swap WETH for BAL on the Arbitrum network\n\n```sh\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"sellToken\":\"0x82af49447d8a07e3bd95bd0d56f35241523fbab1\",\"buyToken\":\"0x040d1EdC9569d4Bab2D15287Dc5A4F10F56a56B8\",\"orderKind\":\"sell\", \"amount\":\"1000000000000000000\", \"gasPrice\":\"10000000\"}' $ENDPOINT_URL/sor/42161\n```\n\n#### Swap WXDAI for USDC on the Gnosis Chain network\n\n```sh\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"sellToken\":\"0xe91d153e0b41518a2ce8dd3d7944fa863463a97d\",\"buyToken\":\"0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83\",\"orderKind\":\"sell\", \"amount\":\"1000000000000000000\", \"gasPrice\":\"100000\"}' $ENDPOINT_URL/sor/100\n```\n\n## GraphQL Requests\n\nYou can run `npx tsx scripts/graphql-query.ts` to see example requests fetching pools from the API.\n\n## Options\n\n### Environment Variables\n\nYou can customize your deployment with env variables. See .env.example for all possible variables. They are described below:\n\n#### General Settings\n\n- DEBUG - Used by the [npm debug package](https://www.npmjs.com/package/debug) Can be used for showing debug information.\n- PORT - default: 8090 - Port to run the local server on\n- INFURA_PROJECT_ID - Your infura project ID. Used for loading data across all networks.\n- NETWORKS - default: 1,137,42161 - A comma separated list of networks ID's or names to run the API on.\n\n#### Testing Related\n\n- RPC_URL - Used for E2E tests. This can be a local node or an Infura/Alchemy like service.\n- ENDPOINT_URL - Used for E2E tests. Specifies the Balancer API URL you'll be running the tests against.\n- HARDHAT_URL - Used for E2E tests. Defaults to 127.0.0.1.\n\n#### Capacity Related\n\n- UPDATE_POOLS_INTERVAL_IN_MINUTES - default: 5 - How frequently to run the update pools lambda.\n- DECORATE_POOLS_INTERVAL_IN_MINUTES - default: 5 - How frequently to run the decorate pools lambda.\n- DYNAMODB_POOLS_READ_CAPACITY - default: 25 - The read capacity of the `pools` DynamoDB table.\n- DYNAMODB_POOLS_WRITE_CAPACITY - default: 25 - The write capacity of the `pools` DynamoDB table.\n- DYNAMODB_POOLS_IDX_READ_CAPACITY - default: 10 - The read capacity of the secondary indexes on the `pools` DynamoDB table.\n- DYNAMODB_POOLS_WRITE_CAPACITY - default: 10 - The write capacity of the secondary indexes on the `pools` DynamoDB table.\n- DYNAMODB_TOKENS_READ_CAPACITY - default: 10 - The read capcity of the `tokens` DynamoDB table.\n- DYNAMODB_TOKENS_WRITE_CAPACITY - default: 10 - The write capacity of the `tokens` DynamoDB tbale.\n- DYNAMODB_AUTOSCALE_MAX_MULTIPLIER - default: 1 - Increasing this causes your tables to autoscale their capacity up to CAPACITY \\* MULTIPLIER\n\n#### Additional Settings - Rarely used\n\n- DOMAIN_NAME - The domain that API Gateway will run on. If specified a random AWS domain will be created.\n- TENDERLY_USER - Your Tenderly user id, used by the `/tenderly` endpoints.\n- TENDERLY_PROJECT - Your Tenderly project id, used by the `/tenderly` endpoints.\n- TENDERLY_ACCESS_KEY - Your tenderly access key, used by the `/tenderly` endpoints.\n- SENTRY_DSN - Your Sentry account DSN, if you'd like to send errors to Sentry\n- GH_WEBHOOK_PAT - A Github Personal Access Token, used to call webhooks on Balancer repositories\n\n## Common Issues\n\n- AWS error `Specified ReservedConcurrentExecutions for function decreases account's UnreservedConcurrentExecution below its minimum value of [10]`\n  - By default this package creates 13 lambdas while new AWS accounts are limited to 10. You can fix this by changing the `NETWORKS` environment variable to just `1` to only deploy lambdas for Mainnet instead of all networks.\n\n## Tips\n\nIf you encounter any unexpected issues during deployment, please ensure that:\n\n- you are using NodeJS version 14.X\n- the AWS region you are trying to deploy is exactly the same one that was used during the bootstrapping process.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbalancer%2Fbalancer-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbalancer%2Fbalancer-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbalancer%2Fbalancer-api/lists"}