Skip to content

Commit

Permalink
Merge pull request #141 from balancer-labs/develop
Browse files Browse the repository at this point in the history
Release 0.1.22
  • Loading branch information
johngrantuk authored Sep 9, 2022
2 parents e30fd02 + 9467444 commit f77290f
Show file tree
Hide file tree
Showing 125 changed files with 10,318 additions and 1,598 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/balancer-js.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Install node
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 14
node-version: 18
- name: Cache
uses: actions/cache@v2
id: cache
Expand All @@ -40,9 +40,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Install node
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 14
node-version: 18
- name: Cache
uses: actions/cache@v2
id: cache
Expand All @@ -62,9 +62,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Install node
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 14
node-version: 18
- name: Cache
uses: actions/cache@v2
id: cache
Expand All @@ -79,7 +79,7 @@ jobs:
- name: Compile
run: yarn build
- name: Run node in background for integration tests
run: npx hardhat node --hostname 127.0.0.1 &
run: npx hardhat node --hostname 127.0.0.1 --fork ${{ secrets.ALCHEMY_URL }} &
- name: Test
run: yarn test

Expand Down
1 change: 1 addition & 0 deletions balancer-js/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v18.3.0
98 changes: 66 additions & 32 deletions balancer-js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@

A JavaScript SDK which provides commonly used utilties for interacting with Balancer Protocol V2.

## How to run the examples (Javascript)?

**In order to run the examples provided, you need to follow the next steps:**

1. git clone https://github.com/balancer-labs/balancer-sdk.git
2. cd balancer-sdk
3. cd balancer-js
4. Create a .env file in the balancer-js folder
5. In the .env file you will need to define and initialize the following variables

ALCHEMY_URL=[ALCHEMY HTTPS ENDPOINT]
INFURA=[Infura API KEY]
TRADER_KEY=[MetaMask PRIVATE KEY]
We have defined both Alchemy and Infura, because some of the examples use Infura, others use Alchemy. However, feel free to modify accordingly and use your favourite one.

6. Run 'npm run node', this runs a local Hardhat Network
7. Open a new terminal
8. cd to balancer-js
9. Install ts-node using: npm install ts-node
10. Install tsconfig-paths using: npm install --save-dev tsconfig-paths
11. Run one of the provided examples (eg: npm run examples:run -- examples/join.ts)

## Installation

## Getting Started
Expand All @@ -10,8 +32,8 @@ A JavaScript SDK which provides commonly used utilties for interacting with Bala
import { BalancerSDK, BalancerSdkConfig, Network } from '@balancer-labs/sdk';

const config: BalancerSdkConfig = {
network: Network.MAINNET,
rpcUrl: `https://mainnet.infura.io/v3/${process.env.INFURA}`,
network: Network.MAINNET,
rpcUrl: `https://mainnet.infura.io/v3/${process.env.INFURA}`,
};
const balancer = new BalancerSDK(config);
```
Expand All @@ -20,16 +42,18 @@ In some examples we present a way to make end to end trades against mainnet stat

Installation instructions for:

* [Hardhat](https://hardhat.org/getting-started/#installation)
- [Hardhat](https://hardhat.org/getting-started/#installation)

To start a forked node:

```
npm run node
```

* [Anvil](https://github.com/foundry-rs/foundry/tree/master/anvil#installation) - use with caution, still experimental.
- [Anvil](https://github.com/foundry-rs/foundry/tree/master/anvil#installation) - use with caution, still experimental.

To start a forked node:

```
anvil -f FORKABLE_RPC_URL (optional pinned block: --fork-block-number XXX)
```
Expand All @@ -41,30 +65,29 @@ Exposes complete functionality for token swapping. An example of using the modul
```js
// Uses SOR to find optimal route for a trading pair and amount
const route = balancer.swaps.findRouteGivenIn({
tokenIn,
tokenOut,
amount,
gasPrice,
maxPools,
})
tokenIn,
tokenOut,
amount,
gasPrice,
maxPools,
});

// Prepares transaction attributes based on the route
const transactionAttributes = balancer.swaps.buildSwap({
userAddress,
swapInfo: route,
kind: 0, // 0 - givenIn, 1 - givenOut
deadline,
maxSlippage,
})
userAddress,
swapInfo: route,
kind: 0, // 0 - givenIn, 1 - givenOut
deadline,
maxSlippage,
});

// Extract parameters required for sendTransaction
const { to, data, value } = transactionAttributes
const { to, data, value } = transactionAttributes;

// Execution with ethers.js
const transactionResponse = await signer.sendTransaction({ to, data, value })
const transactionResponse = await signer.sendTransaction({ to, data, value });
```


## SwapsService

The SwapsService provides function to query and make swaps using Balancer V2 liquidity.
Expand Down Expand Up @@ -168,9 +191,9 @@ complex flash swaps, you will have to use batch swap directly.

Gotchas:

- Both pools must have both assets (tokens) for swaps to work
- No pool token balances can be zero
- If the flash swap isn't profitable, the internal flash loan will fail.
- Both pools must have both assets (tokens) for swaps to work
- No pool token balances can be zero
- If the flash swap isn't profitable, the internal flash loan will fail.

### #encodeSimpleFlashSwap

Expand Down Expand Up @@ -218,29 +241,40 @@ swaps.querySimpleFlashSwap(batchSwap: {

[Example](./examples/querySimpleFlashSwap.ts)

## Pricing Module
## Pricing

Spot Price functionality allowing user to query spot price for token pair.

### calcSpotPrice

Exposes Spot Price functionality allowing user to query spot price for token pair.
Find Spot Price for pair in specific pool.

```js
const pricing = new Pricing(sdkConfig);
const balancer = new BalancerSDK(sdkConfig);
const pool = await balancer.pools.find(poolId);
const spotPrice = await pool.calcSpotPrice(
ADDRESSES[network].DAI.address,
ADDRESSES[network].BAL.address,
);
```

### #getSpotPrice

Calculates Spot Price for a token pair - for specific pool if ID otherwise finds most liquid path and uses this as reference SP.
Find Spot Price for a token pair - finds most liquid path and uses this as reference SP.

```js
const pricing = new Pricing(sdkConfig);
```

@param { string } tokenIn Token in address.
@param { string } tokenOut Token out address.
@param { string } poolId Optional - if specified this pool will be used for SP calculation.
@param { SubgraphPoolBase[] } pools Optional - Pool data. Will be fetched via dataProvider if not supplied.
@returns { string } Spot price.
@returns { string } Spot price.

```js
async getSpotPrice(
tokenIn: string,
tokenOut: string,
poolId = '',
pools: SubgraphPoolBase[] = []
): Promise<string>
```
Expand All @@ -253,7 +287,7 @@ Exposes Join functionality allowing user to join pools.

```js
const balancer = new BalancerSDK(sdkConfig);
const pool = await balancer.poolsProvider.find(poolId);
const pool = await balancer.pools.find(poolId);
const { to, functionName, attributes, data } = pool.buildJoin(params);
```

Expand Down Expand Up @@ -285,7 +319,7 @@ Exposes Exit functionality allowing user to exit pools.

```js
const balancer = new BalancerSDK(sdkConfig);
const pool = await balancer.poolsProvider.find(poolId);
const pool = await balancer.pools.find(poolId);
const { to, functionName, attributes, data } = pool.buildExitExactBPTIn(params);
```

Expand Down
17 changes: 17 additions & 0 deletions balancer-js/examples/data/token-yields.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Display APRs for pool ids hardcoded under `const ids`
* Run command: yarn examples:run ./examples/data/token-yields.ts
*/
import { BalancerSDK } from '../../src/modules/sdk.module';
import { yieldTokens } from '../../src/modules/data/token-yields/tokens/aave';

const sdk = new BalancerSDK({ network: 1, rpcUrl: '' });
const { data } = sdk;

const main = async () => {
const tokenYield = await data.tokenYields.find(yieldTokens.waDAI);

console.log(yieldTokens.waDAI, tokenYield);
};

main();
4 changes: 2 additions & 2 deletions balancer-js/examples/exitExactBPTIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
BalancerErrorCode,
BalancerSDK,
Network,
PoolModel,
PoolWithMethods,
} from '../src/index';
import { parseFixed } from '@ethersproject/bignumber';
import { forkSetup, getBalances } from '../src/test/lib/utils';
Expand Down Expand Up @@ -40,7 +40,7 @@ async function exitExactBPTIn() {
const balancer = new BalancerSDK(sdkConfig);

// Use SDK to find pool info
const pool: PoolModel | undefined = await balancer.poolsProvider.find(poolId);
const pool: PoolWithMethods | undefined = await balancer.pools.find(poolId);
if (!pool) throw new BalancerError(BalancerErrorCode.POOL_DOESNT_EXIST);

// Sets up local fork granting signer initial balances and token approvals
Expand Down
10 changes: 7 additions & 3 deletions balancer-js/examples/exitExactTokensOut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
BalancerErrorCode,
BalancerSDK,
Network,
PoolModel,
PoolWithMethods,
} from '../src/index';
import { forkSetup, getBalances } from '../src/test/lib/utils';
import { ADDRESSES } from '../src/test/lib/constants';
Expand Down Expand Up @@ -40,7 +40,7 @@ async function exitExactTokensOut() {
const balancer = new BalancerSDK(sdkConfig);

// Use SDK to find pool info
const pool: PoolModel | undefined = await balancer.poolsProvider.find(poolId);
const pool: PoolWithMethods | undefined = await balancer.pools.find(poolId);
if (!pool) throw new BalancerError(BalancerErrorCode.POOL_DOESNT_EXIST);

const tokensOut = [
Expand Down Expand Up @@ -87,7 +87,11 @@ async function exitExactTokensOut() {
console.log('Balances before exit: ', tokenBalancesBefore);
console.log('Balances after exit: ', tokenBalancesAfter);
console.log('Max BPT input: ', [maxBPTIn.toString()]);
console.log('Actual BPT input: ', [BigNumber.from(tokenBalancesBefore[0]).sub(BigNumber.from(tokenBalancesAfter[0])).toString()]);
console.log('Actual BPT input: ', [
BigNumber.from(tokenBalancesBefore[0])
.sub(BigNumber.from(tokenBalancesAfter[0]))
.toString(),
]);
}

// yarn examples:run ./examples/exitExactTokensOut.ts
Expand Down
4 changes: 2 additions & 2 deletions balancer-js/examples/join.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
BalancerErrorCode,
BalancerSDK,
Network,
PoolModel,
PoolWithMethods,
} from '../src/index';
import { forkSetup, getBalances } from '../src/test/lib/utils';
import { ADDRESSES } from '../src/test/lib/constants';
Expand Down Expand Up @@ -56,7 +56,7 @@ async function join() {
);

// Use SDK to find pool info
const pool: PoolModel | undefined = await balancer.poolsProvider.find(poolId);
const pool: PoolWithMethods | undefined = await balancer.pools.find(poolId);
if (!pool) throw new BalancerError(BalancerErrorCode.POOL_DOESNT_EXIST);

// Checking balances to confirm success
Expand Down
31 changes: 31 additions & 0 deletions balancer-js/examples/pools/aprs.polygon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Display APRs for pool ids hardcoded under `const ids`
* Run command: yarn examples:run ./examples/pools/aprs.ts
*/
import dotenv from 'dotenv';
import { BalancerSDK } from '../../src/modules/sdk.module';

dotenv.config();

const sdk = new BalancerSDK({
network: 137,
rpcUrl: `${process.env.ALCHEMY_URL?.replace(
'eth-mainnet',
'polygon-mainnet.g'
)}`,
});

const { pools } = sdk;

const main = async () => {
const pool = await pools.find(
'0x0297e37f1873d2dab4487aa67cd56b58e2f27875000100000000000000000002'
);

if (pool) {
const apr = await pools.apr(pool);
console.log(pool.id, apr);
}
};

main();
39 changes: 39 additions & 0 deletions balancer-js/examples/pools/aprs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Display APRs for pool ids hardcoded under `const ids`
* Run command: yarn examples:run ./examples/pools/aprs.ts
*/
import dotenv from 'dotenv';
import { BalancerSDK } from '../../src/modules/sdk.module';

dotenv.config();

const sdk = new BalancerSDK({
network: 1,
rpcUrl: `${process.env.ALCHEMY_URL}`,
});

const { pools } = sdk;

const main = async () => {
const list = (
await pools.where(
(pool) =>
pool.poolType != 'Element' &&
pool.poolType != 'AaveLinear' &&
pool.poolType != 'LiquidityBootstrapping'
)
)
.sort((a, b) => parseFloat(b.totalLiquidity) - parseFloat(a.totalLiquidity))
.slice(0, 30);

list.forEach(async (pool) => {
try {
const apr = await pools.apr(pool);
console.log(pool.id, apr);
} catch (e) {
console.log(e);
}
});
};

main();
Loading

0 comments on commit f77290f

Please sign in to comment.