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

use info endpoint for getPairsFn in router sdk #461

Merged
merged 8 commits into from
Jun 21, 2024
Merged
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
1 change: 0 additions & 1 deletion cypress/e2e/connectWallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ describe('Connect Wallet', () => {
}
//write logs to a file on cypress/logs/logs.txt
cy.writeFile('cypress/logs/logs.txt', logs.join('\n'));
cy.screenshot();
});
// cy.contains('Public Key: publicKey')
});
Expand Down
62 changes: 57 additions & 5 deletions cypress/e2e/flows.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// cypress/integration/navigation.ts

import { is } from "cypress/types/bluebird"


//Bridge flow
describe('Bridge flow', () => {
Expand All @@ -17,7 +19,59 @@ describe('Bridge flow', () => {

// Swap flow
describe('Select tokens & input ammount', () => {
it('should select token in, select token out and type an input ammount', () => {
it('should navigate to swap', () => {
cy.visit('/swap')
cy.contains('You sell')
})
it('should select token in', () => {
cy.visit('/swap')
cy.get('[data-testid="swap__input__panel"]').within(()=>{
cy.get('[data-testid="swap__token__select"]').click()
})
cy.get('[data-testid="token-search-input"]').type('usdc')
cy.get('[data-testid="currency__list__USDC"]').click()
})
it('should select token out', () => {
cy.visit('/swap')
cy.get('[data-testid="swap__output__panel"]').within(()=>{
cy.get('[data-testid="swap__token__select"]').click()
})
cy.get('[data-testid="token-search-input"]').type('xlm')
cy.get('[data-testid="currency__list__XLM"]').click()

})
it('should type an input ammount & expect for a token out', () => {
cy.visit('/swap')
//Select input asset
cy.get('[data-testid="swap__input__panel"]').within(()=>{
cy.get('[data-testid="swap__token__select"]').click()
})
cy.get('[data-testid="token-search-input"]').type('usdc')
cy.get('[data-testid="currency__list__USDC"]').click()

//Select output asset
cy.get('[data-testid="swap__output__panel"]').within(()=>{
cy.get('[data-testid="swap__token__select"]').click()
})
cy.get('[data-testid="currency__list__XLM"]').click()

//Input amount
cy.get('[data-testid="swap__input__panel"]').within(()=>{
cy.get('.token-amount-input').type('32456')
})
//await for calcs
cy.wait(5000)

//Get the output ammount
cy.get('[data-testid="swap__output__panel"]').within(()=>{
cy.get('.token-amount-input').invoke('val').as('outputAmount')
})
cy.get('@outputAmount').should('not.be.empty')
cy.get('@outputAmount').should('have.length.greaterThan', 7)


})
it('should display more details of the swap in dropdown', () => {
cy.visit('/swap')
//Select input asset
cy.get('[data-testid="swap__input__panel"]').within(()=>{
Expand All @@ -38,7 +92,7 @@ describe('Select tokens & input ammount', () => {
})

//await for calcs
cy.wait(1500)
cy.wait(2500)

//Get the output ammount
cy.get('[data-testid="swap__output__panel"]').within(()=>{
Expand All @@ -47,6 +101,7 @@ describe('Select tokens & input ammount', () => {
cy.get('@outputAmount').should('not.be.empty')
cy.get('@outputAmount').should('have.length.greaterThan', 7)

//Show more details
cy.get('[data-testid="swap-details-header-row"]').click()

cy.contains('Price Impact')
Expand All @@ -65,8 +120,6 @@ describe('Select tokens & input ammount', () => {
cy.get('@expectedOutput').contains('XLM')
cy.get('@path').contains('XLM')
cy.get('@path').contains('USDC')

cy.screenshot()
})
})

Expand Down Expand Up @@ -107,6 +160,5 @@ describe('Navigation flow', () => {
cy.get('a[href*="https://info.soroswap.finance"]').click()
cy.wait(1500)
cy.url().should('match', /https:\/\/info\.soroswap\.finance\//)
cy.screenshot()
})
})
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
"react-virtualized-auto-sizer": "^1.0.20",
"react-window": "^1.8.9",
"redux": "^4.2.1",
"soroswap-router-sdk": "^1.2.4",
"soroswap-router-sdk": "^1.2.8",
"swr": "^2.2.0",
"typescript": "5.3.3",
"use-resize-observer": "^9.1.0"
Expand Down
36 changes: 21 additions & 15 deletions src/functions/generateRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ import { useFactory } from 'hooks';
import { useContext, useMemo } from 'react';
import { CurrencyAmount, Networks, Protocols, Router, Token, TradeType } from 'soroswap-router-sdk';
import { AppContext } from 'contexts';

const backendUrl = process.env.NEXT_PUBLIC_SOROSWAP_BACKEND_URL;
const backendApiKey = process.env.NEXT_PUBLIC_SOROSWAP_BACKEND_API_KEY;
const shouldUseBackend = process.env.NEXT_PUBLIC_SOROSWAP_BACKEND_ENABLED === 'true';
import { fetchAllPhoenixPairs, fetchAllSoroswapPairs } from 'services/pairs';

export interface GenerateRouteProps {
amountTokenAddress: string;
Expand All @@ -15,6 +12,13 @@ export interface GenerateRouteProps {
tradeType: TradeType;
}

const queryNetworkDict: { [x: string]: 'MAINNET' | 'TESTNET' } = {
[Networks.PUBLIC]: 'MAINNET',
[Networks.TESTNET]: 'TESTNET',
};

const shouldUseBackend = process.env.NEXT_PUBLIC_SOROSWAP_BACKEND_ENABLED === 'true';

export const useRouterSDK = () => {
const sorobanContext = useSorobanReact();
const { factory } = useFactory(sorobanContext);
Expand All @@ -25,19 +29,22 @@ export const useRouterSDK = () => {
const network = sorobanContext.activeChain?.networkPassphrase as Networks;

const router = useMemo(() => {
if (!backendUrl || !backendApiKey) {
throw new Error(
'NEXT_PUBLIC_SOROSWAP_BACKEND_URL and NEXT_PUBLIC_SOROSWAP_BACKEND_API_KEY must be set in the environment variables.',
);
}

return new Router({
backendUrl,
backendApiKey,
getPairsFns: shouldUseBackend
? [
{
protocol: Protocols.SOROSWAP,
fn: async () => fetchAllSoroswapPairs(network),
},
// {
// protocol: Protocols.PHOENIX,
// fn: async () => fetchAllPhoenixPairs(network),
// },
]
: undefined,
pairsCacheInSeconds: 60,
protocols: [Protocols.SOROSWAP],
protocols: [Protocols.SOROSWAP], //, Protocols.PHOENIX],
network,
shouldUseBackend,
maxHops,
});
}, [network, maxHops]);
Expand All @@ -62,7 +69,6 @@ export const useRouterSDK = () => {
tradeType,
}: GenerateRouteProps) => {
if (!factory) throw new Error('Factory address not found');

const currencyAmount = fromAddressAndAmountToCurrencyAmount(amountTokenAddress, amount);
const quoteCurrency = fromAddressToToken(quoteTokenAddress);

Expand Down
25 changes: 14 additions & 11 deletions src/functions/getLpTokens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { SorobanContextType } from '@soroban-react/core';
import { tokenBalance } from 'hooks';
import { TokenMapType, TokenType } from 'interfaces';
import BigNumber from 'bignumber.js';
import { getTotalShares } from './LiquidityPools';

export type LpTokensObj = {
token_0: TokenType | undefined;
Expand Down Expand Up @@ -35,38 +36,40 @@ const getLpResultsFromBackendPairs = async (

for (const element of pairsBackend) {
const pairLpTokens = await tokenBalance(
element.contractId,
element.address,
sorobanContext.address,
sorobanContext,
);

if (pairLpTokens != 0) {
const token_0 = await findToken(element.token0, tokensAsMap, sorobanContext);
const token_1 = await findToken(element.token1, tokensAsMap, sorobanContext);
const token_0 = await findToken(element.tokenA, tokensAsMap, sorobanContext);
const token_1 = await findToken(element.tokenB, tokensAsMap, sorobanContext);

const totalShares = await getTotalShares(element.address, sorobanContext);

const lpPercentage = BigNumber(pairLpTokens as BigNumber)
.dividedBy(Number(element.totalShares))
.dividedBy(Number(totalShares))
.multipliedBy(100)
.decimalPlaces(7);

if (!token_0 || !token_1) return;

const myReserve0 = BigNumber(pairLpTokens as BigNumber)
?.multipliedBy(BigNumber(element.reserve0))
.dividedBy(Number(element.totalShares));
?.multipliedBy(BigNumber(element.reserveA))
.dividedBy(Number(totalShares));
const myReserve1 = BigNumber(pairLpTokens as BigNumber)
?.multipliedBy(BigNumber(element.reserve1))
.dividedBy(Number(element.totalShares));
?.multipliedBy(BigNumber(element.reserveB))
.dividedBy(Number(totalShares));

const toReturn = {
token_0,
token_1,
balance: pairLpTokens,
lpPercentage: lpPercentage.toString(),
status: 'Active',
reserve0: BigNumber(element.reserve0),
reserve1: BigNumber(element.reserve1),
totalShares: element.totalShares,
reserve0: BigNumber(element.reserveA),
reserve1: BigNumber(element.reserveB),
totalShares: totalShares,
myReserve0,
myReserve1,
};
Expand Down
11 changes: 6 additions & 5 deletions src/hooks/useGetNativeTokenBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ const fetchBalance = async ({ sorobanContext, address }: FetchBalanceProps) => {
return { data: 0, validAccount: false };
}

try {
const balance = await tokenBalance(networkNativeToken.address, address, sorobanContext);
return { data: balance, validAccount: true };
} catch (error) {
return { data: 0, validAccount: true };
const balance = await tokenBalance(networkNativeToken.address, address, sorobanContext);

if (balance === null) {
throw new Error('Failed to fetch balance');
}

return { data: balance, validAccount: true };
};

const useGetNativeTokenBalance = () => {
Expand Down
35 changes: 22 additions & 13 deletions src/services/pairs.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import axios from 'axios';
import { Networks } from '@stellar/stellar-sdk';
interface SubscribedPair {
contractId: string;
token0: string;
token1: string;
reserve0: string;
reserve1: string;
totalShares: string;
protocol: string;

interface MercuryPair {
tokenA: string;
tokenB: string;
address: string;
reserveA: string;
reserveB: string;
}

const passphraseToBackendNetworkName: { [x: string]: string } = {
Expand All @@ -18,12 +17,22 @@ const passphraseToBackendNetworkName: { [x: string]: string } = {
export const fetchAllSoroswapPairs = async (networkPassphrase: string) => {
const networkName = passphraseToBackendNetworkName[networkPassphrase];

const { data } = await axios.post<SubscribedPair[]>(
`${process.env.NEXT_PUBLIC_SOROSWAP_BACKEND_URL}/pairs/all?network=${networkName}&protocols=soroswap`,
undefined,
const { data } = await axios.get<MercuryPair[]>(`https://info.soroswap.finance/api/pairs/plain`, {
params: {
network: networkName,
},
});
return data;
};

export const fetchAllPhoenixPairs = async (networkPassphrase: string) => {
const networkName = passphraseToBackendNetworkName[networkPassphrase];

const { data } = await axios.get<MercuryPair[]>(
`https://info.soroswap.finance/api/pairs/phoenix`,
{
headers: {
apiKey: process.env.NEXT_PUBLIC_SOROSWAP_BACKEND_API_KEY,
params: {
network: networkName,
},
},
);
Expand Down
Loading