Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update SDK examples to use buildCallWithPermit2 #409

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions examples/approvals/approveSpenderOnToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { erc20Abi, MaxUint256 } from '../../src';

import { Address } from 'viem';

export const approveSpenderOnToken = async (
client: any,
account: Address,
token: Address,
spender: Address,
) => {
await client.writeContract({
account,
address: token,
abi: erc20Abi,
functionName: 'approve',
args: [spender, MaxUint256],
});
console.log('Approved spender on token');
};
2 changes: 2 additions & 0 deletions examples/approvals/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './signPermit2';
export * from './approveSpenderOnToken';
44 changes: 44 additions & 0 deletions examples/approvals/signPermit2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {
AllowanceTransfer,
Permit2Batch,
PermitDetails,
PERMIT2,
BALANCER_ROUTER,
MaxSigDeadline,
ChainId,
} from '../../src';

import { Address } from 'viem';

export const signPermit2 = async (
client: any,
account: Address,
chainId: ChainId,
details: PermitDetails[],
) => {
const spender = BALANCER_ROUTER[chainId];

const batch: Permit2Batch = {
details,
spender,
sigDeadline: MaxSigDeadline,
};

const { domain, types, values } = AllowanceTransfer.getPermitData(
batch,
PERMIT2[chainId],
chainId,
);

await client.impersonateAccount({ address: account });

const signature = await client.signTypedData({
account: account,
message: { ...values },
domain,
primaryType: 'PermitBatch',
types,
});

return { signature, batch };
};
87 changes: 87 additions & 0 deletions examples/swaps/queryCustomPath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// use custom path to query and return the queryOutput
/**
* Example showing how to query swap using paths from the SOR
*
* Run with:
* pnpm example ./examples/swaps/queryCustomPath.ts
*/
import { config } from 'dotenv';
config();

import {
ChainId,
SwapKind,
Swap,
ExactInQueryOutput,
ExactOutQueryOutput,
} from '../../src';

import { Address, parseUnits } from 'viem';

const queryCustomPath = async () => {
// User defined
const rpcUrl = process.env.SEPOLIA_RPC_URL;
const chainId = ChainId.SEPOLIA;
const pool = '0xb27aC1DD8192163CFbD6F977C91D31A07E941B87' as Address; // Constant Product Pool from scaffold balancer v3
const tokenIn = {
address: '0x83f953D2461C6352120E06f5f8EcCD3e4d66d042' as Address, // MockToken1 from scaffold balancer v3
decimals: 18,
};
const tokenOut = {
address: '0x9d57eDCe10b7BdDA98997613c33ff7f3e34F4eAd' as Address,
decimals: 18,
};
const swapKind = SwapKind.GivenIn as SwapKind;
const tokens = [tokenIn, tokenOut];
const protocolVersion = 3 as const;
const inputAmountRaw = parseUnits('1', 18);
const outputAmountRaw = parseUnits('1', 18);

const customPaths = [
{
pools: [pool],
tokens,
protocolVersion,
inputAmountRaw,
outputAmountRaw,
},
];
const swapInput = { chainId, swapKind, paths: customPaths };

// Swap object provides useful helpers for re-querying, building call, etc
const swap = new Swap(swapInput);

if (swapKind === SwapKind.GivenIn) {
console.log('Given tokenIn:', {
address: tokenIn.address,
amount: inputAmountRaw,
});
} else {
console.log('Given tokenOut:', {
address: tokenOut.address,
amount: outputAmountRaw,
});
}

// Get up to date swap result by querying onchain
const queryOutput = (await swap.query(rpcUrl)) as
| ExactInQueryOutput
| ExactOutQueryOutput;

// Construct transaction to make swap
if (queryOutput.swapKind === SwapKind.GivenIn) {
console.log('tokenOut:', {
address: tokenOut.address,
expectedAmount: queryOutput.expectedAmountOut.amount,
});
} else {
console.log('tokenIn:', {
address: tokenIn.address,
expectedAmount: queryOutput.expectedAmountIn.amount,
});
}

return { swap, chainId, queryOutput };
};

export default queryCustomPath;
89 changes: 89 additions & 0 deletions examples/swaps/querySmartPath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* Example showing how to query swap using paths from the SOR
*
* Run with:
* pnpm example ./examples/swaps/querySmartPath.ts
*/
import { config } from 'dotenv';
config();

import {
BalancerApi,
API_ENDPOINT,
ChainId,
SwapKind,
Token,
TokenAmount,
Swap,
} from '../../src';

const querySmartPath = async () => {
// User defined
const rpcUrl = process.env.MAINNET_RPC_URL;
const chainId = ChainId.MAINNET;
const swapKind = SwapKind.GivenIn as SwapKind;
const tokenIn = new Token(
chainId,
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
6,
'USDC',
);
const tokenOut = new Token(
chainId,
'0xba100000625a3754423978a60c9317c58a424e3D',
18,
'BAL',
);
const swapAmount =
swapKind === SwapKind.GivenIn
? TokenAmount.fromHumanAmount(tokenIn, '100')
: TokenAmount.fromHumanAmount(tokenOut, '100');

// API is used to fetch best path from available liquidity
const balancerApi = new BalancerApi(API_ENDPOINT, chainId);

const sorPaths = await balancerApi.sorSwapPaths.fetchSorSwapPaths({
chainId,
tokenIn: tokenIn.address,
tokenOut: tokenOut.address,
swapKind,
swapAmount,
});

const swapInput = {
chainId,
paths: sorPaths,
swapKind,
};

// Swap object provides useful helpers for re-querying, building call, etc
const swap = new Swap(swapInput);

console.table({
Address: {
tokenIn: swap.inputAmount.token.address,
tokenOut: swap.outputAmount.token.address,
},
Amount: {
tokenIn: swap.inputAmount.amount,
tokenOut: swap.outputAmount.amount,
},
});

// Get up to date swap result by querying onchain
const queryOutput = await swap.query(rpcUrl);

// Construct transaction to make swap
if (queryOutput.swapKind === SwapKind.GivenIn) {
console.log(
'Expected Amount Out:',
queryOutput.expectedAmountOut.amount,
);
} else {
console.log('Expected Amount In:', queryOutput.expectedAmountIn.amount);
}

return { swap, chainId, queryOutput };
};

export default querySmartPath;
110 changes: 0 additions & 110 deletions examples/swaps/swap.ts

This file was deleted.

Loading
Loading