@@ -15,7 +15,11 @@ import { toRealSymbol } from '../../utils/token';
15
15
16
16
import { EstimateSwapView } from 'src/services/swap' ;
17
17
18
- import { getPoolAllocationPercents , percent } from '../../utils/numbers' ;
18
+ import {
19
+ getPoolAllocationPercents ,
20
+ percent ,
21
+ getRouteAllocationPercents ,
22
+ } from '../../utils/numbers' ;
19
23
import { Pool } from '../../services/pool' ;
20
24
import { FaAngleUp , FaAngleDown } from '../reactIcons' ;
21
25
import { Card } from '../card/Card' ;
@@ -72,8 +76,14 @@ import { displayNumberToAppropriateDecimals } from '../../services/commonV3';
72
76
import { numberWithCommas } from '../../pages/Orderly/utiles' ;
73
77
import { get_pool_name , openUrl } from '../../services/commonV3' ;
74
78
import getConfigV2 from '../../services/configV2' ;
79
+
75
80
import { REF_FI_BEST_MARKET_ROUTE } from '../../state/swap' ;
76
81
import { PolygonRight } from '../../pages/Orderly/components/Common/Icons' ;
82
+ import {
83
+ IEstimateSwapServerView ,
84
+ IServerRoute ,
85
+ getTokensOfRoute ,
86
+ } from '../../services/smartRouterFromServer' ;
77
87
const configV2 = getConfigV2 ( ) ;
78
88
export const GetPriceImpact = (
79
89
value : string ,
@@ -717,16 +727,23 @@ export const getDexAction = (market: SwapMarket) => {
717
727
718
728
export const SwapRoute = ( {
719
729
route,
720
- p,
721
730
market,
731
+ routeServer,
722
732
} : {
723
- route : EstimateSwapView [ ] ;
724
- p : string ;
725
- tokenIn : TokenMetadata ;
726
- tokenOut : TokenMetadata ;
733
+ route ?: EstimateSwapView [ ] ;
727
734
market : SwapMarket ;
735
+ routeServer ?: IServerRoute ;
728
736
} ) => {
729
- const tokens = route [ 0 ] . tokens ;
737
+ const [ tokens , setTokens ] = useState ( [ ] ) ;
738
+ useEffect ( ( ) => {
739
+ if ( route ) {
740
+ setTokens ( route [ 0 ] . tokens ) ;
741
+ } else if ( routeServer ) {
742
+ getTokensOfRoute ( routeServer ) . then ( ( res ) => {
743
+ setTokens ( res ) ;
744
+ } ) ;
745
+ }
746
+ } , [ route , routeServer ] ) ;
730
747
731
748
const { swapType } = useContext ( SwapProContext ) ;
732
749
@@ -771,6 +788,7 @@ export const SwapRoute = ({
771
788
tokens . map ( ( t , i ) => {
772
789
return (
773
790
< div
791
+ key = { i }
774
792
className = { `text-xs ${
775
793
tokens . length === 3 && toRealSymbol ( t . symbol ) . length > 7
776
794
? 'xsm:overflow-hidden'
@@ -802,9 +820,11 @@ export const SwapRoute = ({
802
820
export const SwapRouteMoreThan2 = ( {
803
821
market,
804
822
trade,
823
+ throughPools,
805
824
} : {
806
825
market : SwapMarket ;
807
826
trade : ExchangeEstimate ;
827
+ throughPools : number ;
808
828
} ) => {
809
829
const intl = useIntl ( ) ;
810
830
@@ -846,7 +866,7 @@ export const SwapRouteMoreThan2 = ({
846
866
id : 'steps_in_the_route_zh' ,
847
867
} ) }
848
868
< span className = { intl . locale === 'zh-CN' ? 'mr-0' : 'mr-1' } >
849
- { trade . estimates . length }
869
+ { throughPools }
850
870
</ span >
851
871
852
872
< FormattedMessage
@@ -1691,7 +1711,7 @@ export const TradeRouteHub = ({
1691
1711
>
1692
1712
< div className = "border-b pb-1 frcs border-primaryText border-opacity-30" >
1693
1713
< DisplayIcon token = { token } height = "14px" width = "14px" />
1694
- < span className = "ml-1 text-white text-xs w-10 mr-4 " >
1714
+ < span className = "block ml-1 text-white text-xs w-28 truncate " >
1695
1715
{ toRealSymbol ( token . symbol ) }
1696
1716
</ span >
1697
1717
</ div >
@@ -1742,7 +1762,7 @@ export const RightBracket = ({ size }: { size: number }) => {
1742
1762
< div
1743
1763
className = "w-4 mr-3 opacity-30 rounded-full relative z-10 border border-primaryText "
1744
1764
style = { {
1745
- height : `${ size * 35 } px` ,
1765
+ height : `${ size * 60 } px` ,
1746
1766
clipPath : `polygon(50% 0, 100% 0,100% 100%, 50% 100%)` ,
1747
1767
} }
1748
1768
> </ div >
@@ -1754,7 +1774,7 @@ export const LeftBracket = ({ size }: { size: number }) => {
1754
1774
< div
1755
1775
className = "w-4 ml-3 opacity-30 rounded-full relative z-10 border border-primaryText transform rotate-180"
1756
1776
style = { {
1757
- height : `${ size * 35 } px` ,
1777
+ height : `${ size * 60 } px` ,
1758
1778
clipPath : `polygon(50% 0, 100% 0,100% 100%, 50% 100%)` ,
1759
1779
} }
1760
1780
> </ div >
@@ -1770,6 +1790,47 @@ export const TradeRoute = ({
1770
1790
tokenIn : TokenMetadata ;
1771
1791
tokenOut : TokenMetadata ;
1772
1792
} ) => {
1793
+ const [ estimatesServerUI , setEstimatesServerUI ] =
1794
+ useState < IEstimateSwapServerView > ( ) ;
1795
+ const { estimates, estimatesServer } = trade || { } ;
1796
+ const identicalRoutes = estimates
1797
+ ? separateRoutes ( estimates , estimates [ estimates . length - 1 ] . outputToken )
1798
+ : [ ] ;
1799
+
1800
+ const pools = identicalRoutes . map ( ( r ) => r [ 0 ] ) . map ( ( hub ) => hub . pool ) ;
1801
+ useEffect ( ( ) => {
1802
+ if ( estimatesServer ) {
1803
+ getTokensDataOfEstimatesServer ( ) ;
1804
+ } else {
1805
+ setEstimatesServerUI ( undefined ) ;
1806
+ }
1807
+ } , [ JSON . stringify ( estimatesServer || { } ) ] ) ;
1808
+ async function getTokensDataOfEstimatesServer ( ) {
1809
+ const pending = estimatesServer . routes . map ( ( route ) =>
1810
+ getTokensOfRoute ( route )
1811
+ ) ;
1812
+ const tokens_of_routes = await Promise . all ( pending ) ;
1813
+ estimatesServer . routes . map ( ( route , index ) => {
1814
+ route . tokens = tokens_of_routes [ index ] ;
1815
+ } ) ;
1816
+ setEstimatesServerUI ( estimatesServer ) ;
1817
+ }
1818
+ const percents = useMemo ( ( ) => {
1819
+ try {
1820
+ return getPoolAllocationPercents ( pools ) ;
1821
+ } catch ( error ) {
1822
+ if ( identicalRoutes . length === 0 ) return [ '100' ] ;
1823
+ else return identicalRoutes . map ( ( r ) => r [ 0 ] . percent ) ;
1824
+ }
1825
+ } , [ identicalRoutes , pools ] ) ;
1826
+ const percentsServer = useMemo ( ( ) => {
1827
+ const routes = estimatesServer ?. routes || [ ] ;
1828
+ try {
1829
+ return getRouteAllocationPercents ( routes ) ;
1830
+ } catch ( error ) {
1831
+ return [ '100' ] ;
1832
+ }
1833
+ } , [ ( estimatesServer ?. routes || [ ] ) . length ] ) ;
1773
1834
if ( ! tokenIn || ! tokenOut ) return null ;
1774
1835
1775
1836
if ( ! trade || ! trade ?. availableRoute || tokenIn ?. id === tokenOut ?. id ) {
@@ -1801,85 +1862,119 @@ export const TradeRoute = ({
1801
1862
</ div >
1802
1863
) ;
1803
1864
}
1804
-
1805
- const { estimates } = trade ;
1806
-
1807
- const { market } = trade ;
1808
-
1809
- const identicalRoutes = separateRoutes (
1810
- estimates ,
1811
- estimates [ estimates . length - 1 ] . outputToken
1812
- ) ;
1813
-
1814
- const pools = identicalRoutes . map ( ( r ) => r [ 0 ] ) . map ( ( hub ) => hub . pool ) ;
1815
-
1816
- const percents = useMemo ( ( ) => {
1817
- try {
1818
- return getPoolAllocationPercents ( pools ) ;
1819
- } catch ( error ) {
1820
- if ( identicalRoutes . length === 0 ) return [ '100' ] ;
1821
- else return identicalRoutes . map ( ( r ) => r [ 0 ] . percent ) ;
1822
- }
1823
- } , [ identicalRoutes , pools ] ) ;
1824
-
1865
+ const routeLength =
1866
+ identicalRoutes . length || trade . estimatesServer ?. routes ?. length ;
1825
1867
return (
1826
1868
< div className = "frcb" >
1827
1869
< DisplayIcon token = { tokenIn } height = "26px" width = "26px" />
1828
- < LeftBracket size = { identicalRoutes . length } />
1829
- < div className = "w-full mx-2 xsm:overflow-x-auto hideScroll relative" >
1830
- { identicalRoutes . map ( ( route , j ) => {
1831
- return (
1832
- < div
1833
- className = "relative frcb my-3 "
1834
- style = { {
1835
- width : isMobile ( ) ? '460px' : '' ,
1836
- } }
1837
- >
1838
- < span className = "text-xs text-senderHot" > { percents [ j ] } %</ span >
1870
+ < LeftBracket size = { routeLength } />
1871
+ { /* from script routes */ }
1872
+ { trade . estimates ? (
1873
+ < div className = { `w-full mx-2 xsm:overflow-x-auto hideScroll relative` } >
1874
+ { identicalRoutes . map ( ( route , j ) => {
1875
+ return (
1839
1876
< div
1840
- className = "border border-dashed absolute left-5 opacity-30 border-primaryText w-full px-3"
1877
+ key = { j }
1878
+ className = "relative frcb my-3 "
1841
1879
style = { {
1842
- width : 'calc(100% - 32px) ',
1880
+ width : isMobile ( ) ? '460px' : ' ',
1843
1881
} }
1844
- > </ div >
1845
- < div className = "frcs" >
1846
- { route [ 0 ] . tokens
1847
- . slice ( 1 , route [ 0 ] . tokens . length )
1848
- . map ( ( t , i ) => {
1882
+ >
1883
+ < span className = "text-xs text-senderHot" > { percents [ j ] } %</ span >
1884
+ < div
1885
+ className = "border border-dashed absolute left-5 opacity-30 border-primaryText w-full px-3"
1886
+ style = { {
1887
+ width : 'calc(100% - 32px)' ,
1888
+ } }
1889
+ > </ div >
1890
+ < div className = "frcs" >
1891
+ { route [ 0 ] . tokens
1892
+ . slice ( 1 , route [ 0 ] . tokens . length )
1893
+ . map ( ( t , i ) => {
1894
+ return (
1895
+ < >
1896
+ < TradeRouteHub
1897
+ poolId = {
1898
+ route [ i ] . contract === 'Ref_DCL'
1899
+ ? getV3PoolId (
1900
+ tokenIn . id ,
1901
+ tokenOut . id ,
1902
+ trade . fee * 100
1903
+ )
1904
+ : route [ i ] . contract === 'Ref_Classic'
1905
+ ? Number ( route [ i ] . pool . id )
1906
+ : null
1907
+ }
1908
+ token = { t }
1909
+ contract = { route [ i ] . contract }
1910
+ />
1911
+ { t . id !==
1912
+ route [ 0 ] . tokens [ route [ 0 ] . tokens . length - 1 ] ?. id && (
1913
+ < div className = "mx-3" >
1914
+ < PolygonArrow />
1915
+ </ div >
1916
+ ) }
1917
+ </ >
1918
+ ) ;
1919
+ } ) }
1920
+ </ div >
1921
+
1922
+ < PolygonArrow />
1923
+ </ div >
1924
+ ) ;
1925
+ } ) }
1926
+ </ div >
1927
+ ) : null }
1928
+
1929
+ { /* from server routes */ }
1930
+ { estimatesServerUI ? (
1931
+ < div className = { `w-full mx-2 xsm:overflow-x-auto hideScroll relative` } >
1932
+ { estimatesServerUI . routes . map ( ( route , j ) => {
1933
+ const { pools, tokens } = route ;
1934
+ return (
1935
+ < div
1936
+ key = { j }
1937
+ className = "relative frcb my-3 "
1938
+ style = { {
1939
+ width : isMobile ( ) ? '620px' : '' ,
1940
+ } }
1941
+ >
1942
+ < span className = "text-xs text-senderHot" >
1943
+ { percentsServer [ j ] } %
1944
+ </ span >
1945
+ < div
1946
+ className = "border border-dashed absolute left-5 opacity-30 border-primaryText w-full px-3"
1947
+ style = { {
1948
+ width : 'calc(100% - 32px)' ,
1949
+ } }
1950
+ > </ div >
1951
+ < div className = "frcs" >
1952
+ { tokens ?. slice ( 1 , tokens . length ) . map ( ( t , i ) => {
1849
1953
return (
1850
1954
< >
1851
1955
< TradeRouteHub
1852
- poolId = {
1853
- route [ i ] . contract === 'Ref_DCL'
1854
- ? getV3PoolId (
1855
- tokenIn . id ,
1856
- tokenOut . id ,
1857
- trade . fee * 100
1858
- )
1859
- : route [ i ] . contract === 'Ref_Classic'
1860
- ? Number ( route [ i ] . pool . id )
1861
- : null
1862
- }
1956
+ poolId = { Number ( pools [ i ] . pool_id ) }
1863
1957
token = { t }
1864
- contract = { route [ i ] . contract }
1958
+ contract = "Ref_Classic"
1865
1959
/>
1866
- { t . id !==
1867
- route [ 0 ] . tokens [ route [ 0 ] . tokens . length - 1 ] ?. id && (
1960
+ { t . id !== tokens [ tokens . length - 1 ] ?. id && (
1868
1961
< div className = "mx-3" >
1869
1962
< PolygonArrow />
1870
1963
</ div >
1871
1964
) }
1872
1965
</ >
1873
1966
) ;
1874
1967
} ) }
1968
+ </ div >
1969
+
1970
+ < PolygonArrow />
1875
1971
</ div >
1972
+ ) ;
1973
+ } ) }
1974
+ </ div >
1975
+ ) : null }
1876
1976
1877
- < PolygonArrow />
1878
- </ div >
1879
- ) ;
1880
- } ) }
1881
- </ div >
1882
- < RightBracket size = { identicalRoutes . length } />
1977
+ < RightBracket size = { routeLength } />
1883
1978
1884
1979
< DisplayIcon token = { tokenOut } height = "26px" width = "26px" />
1885
1980
</ div >
@@ -1900,7 +1995,7 @@ export const TradeRouteModal = (
1900
1995
/>
1901
1996
}
1902
1997
{ ...props }
1903
- customWidth = { isMobile ( ) ? '95vw' : '700px ' }
1998
+ customWidth = { isMobile ( ) ? '95vw' : '800px ' }
1904
1999
>
1905
2000
< div className = "w-full mt-7" >
1906
2001
< TradeRoute
0 commit comments