Skip to content

Commit

Permalink
Merge pull request #461 from soroswap/feat/router-sdk-use-info-endpoint
Browse files Browse the repository at this point in the history
use info endpoint for getPairsFn in router sdk
  • Loading branch information
joaquinsoza authored Jun 21, 2024
2 parents 487a0e6 + 92e057f commit 5e4d0e4
Show file tree
Hide file tree
Showing 8 changed files with 706 additions and 258 deletions.
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

0 comments on commit 5e4d0e4

Please sign in to comment.