-
Notifications
You must be signed in to change notification settings - Fork 5
feat: add router capabilities for swapping with the sdk #66
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
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
a1fb131
feat: integrate router in SDK
bowd 104ff6a
fix: invert path if needed
bowd ed8cb78
feat: change interface to make it backwards compatible
bowd 76b76f0
Update scripts/swap.ts
bowd d7e9b6c
chore: remove unused function param
philbow61 e2b403d
chore: remove params
philbow61 60b7d12
fix: check correct addresses variable
philbow61 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| const rpcUrls = { | ||
| 42220: 'https://forno.celo.org', | ||
| 62320: 'https://baklava-forno.celo-testnet.org', | ||
| 44787: 'https://alfajores-forno.celo-testnet.org', | ||
| } | ||
|
|
||
| import { providers } from 'ethers' | ||
| import { Mento } from '../src/mento' | ||
| import fs from 'fs' | ||
| import path from 'path' | ||
|
|
||
| async function getTradablePairsForNetwork(rpcUrl: string) { | ||
| const provider = new providers.JsonRpcProvider(rpcUrl) | ||
| const mento = await Mento.create(provider) | ||
| return await mento.getTradablePairs(true) | ||
| } | ||
|
|
||
| async function main() { | ||
| const results: Record<number, any> = {} | ||
|
|
||
| // Get pairs for each network | ||
| for (const [chainId, rpcUrl] of Object.entries(rpcUrls)) { | ||
| console.log(`Fetching pairs for chain ${chainId}...`) | ||
| try { | ||
| results[Number(chainId)] = await getTradablePairsForNetwork(rpcUrl) | ||
| } catch (e) { | ||
| console.error(`Error fetching pairs for chain ${chainId}:`, e) | ||
| } | ||
| } | ||
|
|
||
| // Generate TypeScript file content | ||
| const fileContent = `// THIS FILE IS AUTO-GENERATED. DO NOT EDIT DIRECTLY. | ||
| import { TradablePair } from '../mento' | ||
|
|
||
| export const TRADABLE_PAIRS: Record<number, TradablePair[]> = ${JSON.stringify( | ||
| results, | ||
| null, | ||
| 2 | ||
| )}; | ||
|
|
||
| export function getCachedTradablePairs(chainId: number): TradablePair[] | undefined { | ||
| return TRADABLE_PAIRS[chainId] | ||
| } | ||
| ` | ||
|
|
||
| // Ensure constants directory exists | ||
| const constantsDir = path.join(__dirname, '../src/constants') | ||
| if (!fs.existsSync(constantsDir)) { | ||
| fs.mkdirSync(constantsDir, { recursive: true }) | ||
| } | ||
|
|
||
| // Write the file | ||
| const filePath = path.join(constantsDir, 'tradablePairs.ts') | ||
| fs.writeFileSync(filePath, fileContent) | ||
| console.log(`Generated ${filePath}`) | ||
| } | ||
|
|
||
| main() | ||
| .then(() => process.exit(0)) | ||
| .catch((error) => { | ||
| console.error(error) | ||
| process.exit(1) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| import { providers } from 'ethers' | ||
| import { Mento } from '../src/mento' | ||
|
|
||
| const rpcUrls: Record<number, string> = { | ||
| 42220: 'https://forno.celo.org', | ||
| 62320: 'https://baklava-forno.celo-testnet.org', | ||
| 44787: 'https://alfajores-forno.celo-testnet.org', | ||
| } | ||
|
|
||
| async function main() { | ||
| // Expect the chain id as the first command-line argument. | ||
| const args = process.argv.slice(2) | ||
| if (args.length < 1) { | ||
| console.error('Usage: ts-node printTradablePairs.ts <chainId>') | ||
| process.exit(1) | ||
| } | ||
|
|
||
| const chainId = Number(args[0]) | ||
| if (!rpcUrls[chainId]) { | ||
| console.error( | ||
| `Chain id ${chainId} not supported. Supported chain ids: ${Object.keys( | ||
| rpcUrls | ||
| ).join(', ')}` | ||
| ) | ||
| process.exit(1) | ||
| } | ||
|
|
||
| const rpcUrl = rpcUrls[chainId] | ||
| const provider = new providers.JsonRpcProvider(rpcUrl) | ||
|
|
||
| // Create a Mento instance using the provider | ||
| const mento = await Mento.create(provider) | ||
|
|
||
| // Optional: verify that the provider's network matches the requested chain id. | ||
| const network = await provider.getNetwork() | ||
| if (network.chainId !== chainId) { | ||
| console.warn( | ||
| `Warning: provider network chain id (${network.chainId}) does not match requested chain id (${chainId})` | ||
| ) | ||
| } | ||
|
|
||
| // Fetch tradable pairs. Here, we pass "true" to use the cached pairs as defined in getTradablePairs. | ||
| const pairs = await mento.getTradablePairs(true) | ||
|
|
||
| console.log(`Tradable pairs for chain ${chainId}:\n`) | ||
| for (const pair of pairs) { | ||
| const [asset1, asset2] = pair.assets | ||
| console.log(`${pair.id}:`) | ||
| console.log(` Assets:`) | ||
| console.log(` ${asset1.symbol}: ${asset1.address}`) | ||
| console.log(` ${asset2.symbol}: ${asset2.address}`) | ||
| console.log(` Exchange Path:`) | ||
| for (const hop of pair.path) { | ||
| console.log(` Provider: ${hop.providerAddr}`) | ||
| console.log(` Exchange ID: ${hop.id}`) | ||
| console.log(` Assets: ${hop.assets[0]} -> ${hop.assets[1]}`) | ||
| console.log() | ||
| } | ||
| console.log('---') | ||
| } | ||
| } | ||
|
|
||
| main().catch((error) => { | ||
| console.error('Error:', error) | ||
| process.exit(1) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| import { BigNumber, Contract, providers, utils, Wallet } from 'ethers' | ||
| import { Mento } from '../src/mento' | ||
|
|
||
| // Start Generation Here | ||
| const rpcUrls: Record<number, string> = { | ||
| 42220: 'https://forno.celo.org', | ||
| 62320: 'https://baklava-forno.celo-testnet.org', | ||
| 44787: 'https://alfajores-forno.celo-testnet.org', | ||
| } | ||
|
|
||
| async function main() { | ||
| // Read command-line arguments | ||
| const args = process.argv.slice(2) | ||
| if (args.length < 4) { | ||
| console.error( | ||
| 'Usage: ts-node swap.ts <chainId> <pairId> <direction> <amount>' | ||
| ) | ||
| process.exit(1) | ||
| } | ||
|
|
||
| const [chainIdStr, pairId, direction, amountStr] = args | ||
| const chainId = Number(chainIdStr) | ||
|
|
||
| if (!rpcUrls[chainId]) { | ||
| console.error( | ||
| `Chain id ${chainId} not supported. Supported chain ids: ${Object.keys( | ||
| rpcUrls | ||
| ).join(', ')}` | ||
| ) | ||
| process.exit(1) | ||
| } | ||
|
|
||
| // Read private key from environment | ||
| const privateKey = process.env.PRIVATE_KEY | ||
| if (!privateKey) { | ||
| console.error('Error: PRIVATE_KEY environment variable not set.') | ||
| process.exit(1) | ||
| } | ||
|
|
||
| // Create provider and signer | ||
| const provider = new providers.JsonRpcProvider(rpcUrls[chainId]) | ||
| const wallet = new Wallet(privateKey, provider) | ||
|
|
||
| // Create Mento instance | ||
| const mento = await Mento.create(wallet) | ||
|
|
||
| // Fetch tradable pairs | ||
| const pairs = await mento.getTradablePairsWithPath(true) | ||
|
|
||
| // Find the specified tradable pair | ||
| const tradablePair = pairs.find((p) => p.id === pairId) | ||
| if (!tradablePair) { | ||
| console.error(`Tradable pair ${pairId} not found.`) | ||
| process.exit(1) | ||
| } | ||
|
|
||
| // Determine tokenIn and tokenOut based on direction | ||
| let tokenIn = tradablePair.assets[0].address | ||
| let tokenOut = tradablePair.assets[1].address | ||
| if (direction.toLowerCase() === 'reverse') { | ||
| ;[tokenIn, tokenOut] = [tokenOut, tokenIn] | ||
| } | ||
| // Get token decimals | ||
| const tokenInContract = new Contract( | ||
| tokenIn, | ||
| [ | ||
| { | ||
| name: 'decimals', | ||
| type: 'function', | ||
| inputs: [], | ||
| outputs: [{ type: 'uint8' }], | ||
| stateMutability: 'view', | ||
| }, | ||
| ], | ||
| provider | ||
| ) | ||
| const decimals = await tokenInContract.decimals() | ||
|
|
||
| // Parse amount and scale by decimals | ||
| const amountIn = utils.parseUnits(amountStr, decimals) | ||
|
|
||
| // Get amountOut from Mento | ||
| const amountOut = await mento.getAmountOut( | ||
| tokenIn, | ||
| tokenOut, | ||
| amountIn, | ||
| ) | ||
|
|
||
| // Calculate minAmountOut with 5% slippage | ||
| const minAmountOut = amountOut.mul(95).div(100) | ||
|
|
||
| // Increase trading allowance | ||
| console.log('Increasing trading allowance...') | ||
| const allowanceTxReq = await mento.increaseTradingAllowance( | ||
| tokenIn, | ||
| amountIn, | ||
| tradablePair | ||
| ) | ||
| const allowanceTx = await wallet.sendTransaction(allowanceTxReq) | ||
| console.log(`Allowance transaction sent: ${allowanceTx.hash}`) | ||
| await allowanceTx.wait() | ||
| console.log('Allowance transaction confirmed.') | ||
|
|
||
| // Perform swap | ||
| console.log('Performing swap...') | ||
| const swapTxReq = await mento.swapIn( | ||
| tokenIn, | ||
| tokenOut, | ||
| amountIn, | ||
| minAmountOut, | ||
| ) | ||
| const swapTx = await wallet.sendTransaction(swapTxReq) | ||
| console.log(`Swap transaction sent: ${swapTx.hash}`) | ||
| await swapTx.wait() | ||
| console.log('Swap transaction confirmed.') | ||
| } | ||
|
|
||
| main().catch((error) => { | ||
| console.error('Error:', error) | ||
| process.exit(1) | ||
| }) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: would be nice to make this an optional param