@rango-dev/widget-embedded 0.1.10-next.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.d.ts +9 -0
- package/dist/App.d.ts.map +1 -0
- package/dist/QueueManager.d.ts +4 -0
- package/dist/QueueManager.d.ts.map +1 -0
- package/dist/components/AppRouter.d.ts +9 -0
- package/dist/components/AppRouter.d.ts.map +1 -0
- package/dist/components/AppRoutes.d.ts +8 -0
- package/dist/components/AppRoutes.d.ts.map +1 -0
- package/dist/components/BottomLogo.d.ts +3 -0
- package/dist/components/BottomLogo.d.ts.map +1 -0
- package/dist/components/ChangeSlippageButton.d.ts +3 -0
- package/dist/components/ChangeSlippageButton.d.ts.map +1 -0
- package/dist/components/ConfirmSwapErrors.d.ts +4 -0
- package/dist/components/ConfirmSwapErrors.d.ts.map +1 -0
- package/dist/components/ConfirmSwapWarnings.d.ts +4 -0
- package/dist/components/ConfirmSwapWarnings.d.ts.map +1 -0
- package/dist/components/Footer.d.ts +2 -0
- package/dist/components/Footer.d.ts.map +1 -0
- package/dist/components/Header.d.ts +10 -0
- package/dist/components/Header.d.ts.map +1 -0
- package/dist/components/HeaderButtons.d.ts +4 -0
- package/dist/components/HeaderButtons.d.ts.map +1 -0
- package/dist/components/Layout.d.ts +7 -0
- package/dist/components/Layout.d.ts.map +1 -0
- package/dist/components/RoutesOverview.d.ts +10 -0
- package/dist/components/RoutesOverview.d.ts.map +1 -0
- package/dist/components/SwitchFromAndTo.d.ts +4 -0
- package/dist/components/SwitchFromAndTo.d.ts.map +1 -0
- package/dist/components/TokenInfo.d.ts +18 -0
- package/dist/components/TokenInfo.d.ts.map +1 -0
- package/dist/components/TokenPreview.d.ts +20 -0
- package/dist/components/TokenPreview.d.ts.map +1 -0
- package/dist/components/UpdateUrl.d.ts +2 -0
- package/dist/components/UpdateUrl.d.ts.map +1 -0
- package/dist/components/warnings/BalanceWarnings.d.ts +7 -0
- package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -0
- package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts +7 -0
- package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts.map +1 -0
- package/dist/components/warnings/HighSlippageWarning.d.ts +7 -0
- package/dist/components/warnings/HighSlippageWarning.d.ts.map +1 -0
- package/dist/components/warnings/MinRequiredSlippage.d.ts +7 -0
- package/dist/components/warnings/MinRequiredSlippage.d.ts.map +1 -0
- package/dist/constants/errors.d.ts +4 -0
- package/dist/constants/errors.d.ts.map +1 -0
- package/dist/constants/navigationRoutes.d.ts +15 -0
- package/dist/constants/navigationRoutes.d.ts.map +1 -0
- package/dist/constants/numbers.d.ts +3 -0
- package/dist/constants/numbers.d.ts.map +1 -0
- package/dist/constants/searchParams.d.ts +8 -0
- package/dist/constants/searchParams.d.ts.map +1 -0
- package/dist/constants/swapSettings.d.ts +6 -0
- package/dist/constants/swapSettings.d.ts.map +1 -0
- package/dist/globalStyles.d.ts +3 -0
- package/dist/globalStyles.d.ts.map +1 -0
- package/dist/hooks/useConfirmSwap.d.ts +11 -0
- package/dist/hooks/useConfirmSwap.d.ts.map +1 -0
- package/dist/hooks/useCopyToClipboard.d.ts +2 -0
- package/dist/hooks/useCopyToClipboard.d.ts.map +1 -0
- package/dist/hooks/useNavigateBack.d.ts +4 -0
- package/dist/hooks/useNavigateBack.d.ts.map +1 -0
- package/dist/hooks/usePrevious.d.ts +2 -0
- package/dist/hooks/usePrevious.d.ts.map +1 -0
- package/dist/hooks/useSelectLanguage.d.ts +5 -0
- package/dist/hooks/useSelectLanguage.d.ts.map +1 -0
- package/dist/hooks/useTheme.d.ts +8 -0
- package/dist/hooks/useTheme.d.ts.map +1 -0
- package/dist/i18n.d.ts +3 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/lib.d.ts +8 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/mockData/pendingSwap.d.ts +2 -0
- package/dist/mockData/pendingSwap.d.ts.map +1 -0
- package/dist/pages/ConfirmSwapPage.d.ts +3 -0
- package/dist/pages/ConfirmSwapPage.d.ts.map +1 -0
- package/dist/pages/ConfirmWalletsPage.d.ts +3 -0
- package/dist/pages/ConfirmWalletsPage.d.ts.map +1 -0
- package/dist/pages/HistoryPage.d.ts +3 -0
- package/dist/pages/HistoryPage.d.ts.map +1 -0
- package/dist/pages/Home.d.ts +9 -0
- package/dist/pages/Home.d.ts.map +1 -0
- package/dist/pages/LiquiditySourcesPage.d.ts +8 -0
- package/dist/pages/LiquiditySourcesPage.d.ts.map +1 -0
- package/dist/pages/SelectChainPage.d.ts +9 -0
- package/dist/pages/SelectChainPage.d.ts.map +1 -0
- package/dist/pages/SelectTokenPage.d.ts +15 -0
- package/dist/pages/SelectTokenPage.d.ts.map +1 -0
- package/dist/pages/SettingsPage.d.ts +8 -0
- package/dist/pages/SettingsPage.d.ts.map +1 -0
- package/dist/pages/SwapDetailsPage.d.ts +3 -0
- package/dist/pages/SwapDetailsPage.d.ts.map +1 -0
- package/dist/pages/WalletsPage.d.ts +9 -0
- package/dist/pages/WalletsPage.d.ts.map +1 -0
- package/dist/services/httpService.d.ts +3 -0
- package/dist/services/httpService.d.ts.map +1 -0
- package/dist/store/bestRoute.d.ts +28 -0
- package/dist/store/bestRoute.d.ts.map +1 -0
- package/dist/store/meta.d.ts +9 -0
- package/dist/store/meta.d.ts.map +1 -0
- package/dist/store/selectors.d.ts +11 -0
- package/dist/store/selectors.d.ts.map +1 -0
- package/dist/store/settings.d.ts +17 -0
- package/dist/store/settings.d.ts.map +1 -0
- package/dist/store/ui.d.ts +2 -0
- package/dist/store/ui.d.ts.map +1 -0
- package/dist/store/wallets.d.ts +28 -0
- package/dist/store/wallets.d.ts.map +1 -0
- package/dist/types/config.d.ts +40 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/routing.d.ts +45 -0
- package/dist/types/routing.d.ts.map +1 -0
- package/dist/types/swap.d.ts +11 -0
- package/dist/types/swap.d.ts.map +1 -0
- package/dist/utils/common.d.ts +4 -0
- package/dist/utils/common.d.ts.map +1 -0
- package/dist/utils/numbers.d.ts +14 -0
- package/dist/utils/numbers.d.ts.map +1 -0
- package/dist/utils/queue.d.ts +4 -0
- package/dist/utils/queue.d.ts.map +1 -0
- package/dist/utils/routing.d.ts +18 -0
- package/dist/utils/routing.d.ts.map +1 -0
- package/dist/utils/swap.d.ts +45 -0
- package/dist/utils/swap.d.ts.map +1 -0
- package/dist/utils/wallets.d.ts +29 -0
- package/dist/utils/wallets.d.ts.map +1 -0
- package/dist/widget-embedded.cjs.development.js +3101 -0
- package/dist/widget-embedded.cjs.development.js.map +1 -0
- package/dist/widget-embedded.cjs.production.min.js +3101 -0
- package/dist/widget-embedded.cjs.production.min.js.map +1 -0
- package/dist/widget-embedded.esm.js +3092 -0
- package/dist/widget-embedded.esm.js.map +1 -0
- package/package.json +55 -0
- package/readme.md +2 -0
- package/src/App.tsx +91 -0
- package/src/QueueManager.tsx +94 -0
- package/src/app.css +27 -0
- package/src/components/AppRouter.tsx +60 -0
- package/src/components/AppRoutes.tsx +105 -0
- package/src/components/BottomLogo.tsx +47 -0
- package/src/components/ChangeSlippageButton.tsx +19 -0
- package/src/components/ConfirmSwapErrors.tsx +38 -0
- package/src/components/ConfirmSwapWarnings.tsx +35 -0
- package/src/components/Footer.tsx +8 -0
- package/src/components/Header.tsx +37 -0
- package/src/components/HeaderButtons.tsx +47 -0
- package/src/components/Layout.tsx +96 -0
- package/src/components/RoutesOverview.tsx +60 -0
- package/src/components/SwitchFromAndTo.tsx +30 -0
- package/src/components/TokenInfo.tsx +311 -0
- package/src/components/TokenPreview.tsx +175 -0
- package/src/components/UpdateUrl.tsx +162 -0
- package/src/components/warnings/BalanceWarnings.tsx +39 -0
- package/src/components/warnings/ConfirmSwapExtraMessages.tsx +20 -0
- package/src/components/warnings/HighSlippageWarning.tsx +18 -0
- package/src/components/warnings/MinRequiredSlippage.tsx +18 -0
- package/src/constants/errors.ts +3 -0
- package/src/constants/navigationRoutes.ts +14 -0
- package/src/constants/numbers.ts +3 -0
- package/src/constants/searchParams.ts +7 -0
- package/src/constants/swapSettings.ts +9 -0
- package/src/globalStyles.ts +26 -0
- package/src/hooks/useConfirmSwap.ts +260 -0
- package/src/hooks/useCopyToClipboard.ts +23 -0
- package/src/hooks/useNavigateBack.ts +40 -0
- package/src/hooks/usePrevious.ts +13 -0
- package/src/hooks/useSelectLanguage.ts +15 -0
- package/src/hooks/useTheme.ts +127 -0
- package/src/i18n.js +30 -0
- package/src/index.tsx +14 -0
- package/src/languages/en.json +14 -0
- package/src/languages/tr.json +11 -0
- package/src/lib.tsx +119 -0
- package/src/mockData/pendingSwap.ts +607 -0
- package/src/pages/ConfirmSwapPage.tsx +72 -0
- package/src/pages/ConfirmWalletsPage.tsx +127 -0
- package/src/pages/HistoryPage.tsx +29 -0
- package/src/pages/Home.tsx +228 -0
- package/src/pages/LiquiditySourcesPage.tsx +64 -0
- package/src/pages/SelectChainPage.tsx +42 -0
- package/src/pages/SelectTokenPage.tsx +64 -0
- package/src/pages/SettingsPage.tsx +98 -0
- package/src/pages/SwapDetailsPage.tsx +38 -0
- package/src/pages/WalletsPage.tsx +119 -0
- package/src/services/httpService.ts +5 -0
- package/src/store/bestRoute.ts +245 -0
- package/src/store/meta.ts +35 -0
- package/src/store/selectors.ts +19 -0
- package/src/store/settings.ts +84 -0
- package/src/store/ui.ts +21 -0
- package/src/store/wallets.ts +190 -0
- package/src/types/config.ts +44 -0
- package/src/types/index.ts +3 -0
- package/src/types/routing.ts +60 -0
- package/src/types/swap.ts +13 -0
- package/src/utils/common.ts +35 -0
- package/src/utils/numbers.ts +133 -0
- package/src/utils/queue.ts +24 -0
- package/src/utils/routing.ts +150 -0
- package/src/utils/swap.ts +552 -0
- package/src/utils/wallets.ts +481 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { SelectableWallet } from '@rango-dev/ui';
|
|
2
|
+
import { WalletType } from '@rango-dev/wallets-shared';
|
|
3
|
+
import { create } from 'zustand';
|
|
4
|
+
import { subscribeWithSelector } from 'zustand/middleware';
|
|
5
|
+
import { httpService } from '../services/httpService';
|
|
6
|
+
import {
|
|
7
|
+
getRequiredChains,
|
|
8
|
+
getTokensWithBalance,
|
|
9
|
+
isAccountAndBalanceMatched,
|
|
10
|
+
makeBalanceFor,
|
|
11
|
+
resetBalanceState,
|
|
12
|
+
SelectedWallet,
|
|
13
|
+
sortTokens,
|
|
14
|
+
} from '../utils/wallets';
|
|
15
|
+
import { useBestRouteStore } from './bestRoute';
|
|
16
|
+
import { useMetaStore } from './meta';
|
|
17
|
+
import createSelectors from './selectors';
|
|
18
|
+
import { shallow } from 'zustand/shallow';
|
|
19
|
+
|
|
20
|
+
export interface Account {
|
|
21
|
+
chain: string;
|
|
22
|
+
address: string;
|
|
23
|
+
walletType: WalletType;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type TokenBalance = {
|
|
27
|
+
chain: string;
|
|
28
|
+
symbol: string;
|
|
29
|
+
ticker: string;
|
|
30
|
+
address: string | null;
|
|
31
|
+
rawAmount: string;
|
|
32
|
+
decimal: number | null;
|
|
33
|
+
amount: string;
|
|
34
|
+
logo: string | null;
|
|
35
|
+
usdPrice: number | null;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export interface Balance {
|
|
39
|
+
balances: TokenBalance[] | null;
|
|
40
|
+
address: string;
|
|
41
|
+
chain: string;
|
|
42
|
+
loading: boolean;
|
|
43
|
+
walletType: WalletType;
|
|
44
|
+
error: boolean;
|
|
45
|
+
explorerUrl: string | null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface WalletsStore {
|
|
49
|
+
accounts: Account[];
|
|
50
|
+
balances: Balance[];
|
|
51
|
+
selectedWallets: SelectedWallet[];
|
|
52
|
+
connectWallet: (accounts: Account[]) => void;
|
|
53
|
+
disconnectWallet: (walletType: WalletType) => void;
|
|
54
|
+
initSelectedWallets: () => void;
|
|
55
|
+
setSelectedWallet: (wallet: SelectableWallet) => void;
|
|
56
|
+
clearConnectedWallet: () => void;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const useWalletsStore = createSelectors(
|
|
60
|
+
create<WalletsStore>()(
|
|
61
|
+
subscribeWithSelector((set) => ({
|
|
62
|
+
accounts: [],
|
|
63
|
+
balances: [],
|
|
64
|
+
selectedWallets: [],
|
|
65
|
+
connectWallet: (accounts) => {
|
|
66
|
+
const tokens = useMetaStore.getState().meta.tokens;
|
|
67
|
+
|
|
68
|
+
set((state) => ({
|
|
69
|
+
accounts: state.accounts.concat(accounts),
|
|
70
|
+
balances: state.balances.concat(
|
|
71
|
+
accounts.map((account) => ({
|
|
72
|
+
balances: [],
|
|
73
|
+
address: account.address,
|
|
74
|
+
chain: account.chain,
|
|
75
|
+
loading: true,
|
|
76
|
+
walletType: account.walletType,
|
|
77
|
+
error: false,
|
|
78
|
+
explorerUrl: null,
|
|
79
|
+
}))
|
|
80
|
+
),
|
|
81
|
+
}));
|
|
82
|
+
accounts.forEach(async (account) => {
|
|
83
|
+
try {
|
|
84
|
+
const response = await httpService.getWalletsDetails([
|
|
85
|
+
{ address: account.address, blockchain: account.chain },
|
|
86
|
+
]);
|
|
87
|
+
const retrivedBalance = response.wallets[0];
|
|
88
|
+
if (retrivedBalance) {
|
|
89
|
+
set((state) => ({
|
|
90
|
+
balances: state.balances.map((balance) => {
|
|
91
|
+
return isAccountAndBalanceMatched(account, balance)
|
|
92
|
+
? makeBalanceFor(account, retrivedBalance, tokens)
|
|
93
|
+
: balance;
|
|
94
|
+
}),
|
|
95
|
+
}));
|
|
96
|
+
} else throw new Error('Wallet not found');
|
|
97
|
+
} catch (error) {
|
|
98
|
+
set((state) => ({
|
|
99
|
+
balances: state.balances.map((balance) => {
|
|
100
|
+
return isAccountAndBalanceMatched(account, balance)
|
|
101
|
+
? resetBalanceState(balance)
|
|
102
|
+
: balance;
|
|
103
|
+
}),
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
disconnectWallet: (walletType) => {
|
|
109
|
+
set((state) => ({
|
|
110
|
+
accounts: state.accounts.filter(
|
|
111
|
+
(account) => account.walletType !== walletType
|
|
112
|
+
),
|
|
113
|
+
balances: state.balances.filter(
|
|
114
|
+
(balance) => balance.walletType !== walletType
|
|
115
|
+
),
|
|
116
|
+
selectedWallets: state.selectedWallets.filter(
|
|
117
|
+
(wallet) => wallet.walletType != walletType
|
|
118
|
+
),
|
|
119
|
+
}));
|
|
120
|
+
},
|
|
121
|
+
initSelectedWallets: () =>
|
|
122
|
+
set((state) => {
|
|
123
|
+
const requiredChains = getRequiredChains(
|
|
124
|
+
useBestRouteStore.getState().bestRoute
|
|
125
|
+
);
|
|
126
|
+
const connectedWallets = state.accounts;
|
|
127
|
+
const selectedWallets: SelectedWallet[] = [];
|
|
128
|
+
requiredChains.forEach((chain) => {
|
|
129
|
+
const anyWalletSelected = !!state.selectedWallets.find(
|
|
130
|
+
(wallet) => wallet.chain === chain
|
|
131
|
+
);
|
|
132
|
+
if (!anyWalletSelected) {
|
|
133
|
+
const firstWalletWithMatchedChain = connectedWallets.find(
|
|
134
|
+
(wallet) => wallet.chain === chain
|
|
135
|
+
);
|
|
136
|
+
if (!!firstWalletWithMatchedChain)
|
|
137
|
+
selectedWallets.push({
|
|
138
|
+
address: firstWalletWithMatchedChain.address,
|
|
139
|
+
chain: firstWalletWithMatchedChain.chain,
|
|
140
|
+
walletType: firstWalletWithMatchedChain.walletType,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
return {
|
|
145
|
+
selectedWallets: state.selectedWallets.concat(selectedWallets),
|
|
146
|
+
};
|
|
147
|
+
}),
|
|
148
|
+
setSelectedWallet: (wallet) =>
|
|
149
|
+
set((state) => ({
|
|
150
|
+
selectedWallets: state.selectedWallets
|
|
151
|
+
.filter((selectedWallet) => selectedWallet.chain !== wallet.chain)
|
|
152
|
+
.concat({
|
|
153
|
+
chain: wallet.chain,
|
|
154
|
+
address: wallet.address,
|
|
155
|
+
walletType: wallet.walletType,
|
|
156
|
+
}),
|
|
157
|
+
})),
|
|
158
|
+
|
|
159
|
+
clearConnectedWallet: () =>
|
|
160
|
+
set(() => ({
|
|
161
|
+
accounts: [],
|
|
162
|
+
balances: [],
|
|
163
|
+
selectedWallets: [],
|
|
164
|
+
})),
|
|
165
|
+
}))
|
|
166
|
+
)
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
useWalletsStore.subscribe(
|
|
170
|
+
(state) => state.balances,
|
|
171
|
+
(balances) => {
|
|
172
|
+
useBestRouteStore.setState(({ sourceTokens, destinationTokens }) => {
|
|
173
|
+
const sourceTokensWithBalance = getTokensWithBalance(
|
|
174
|
+
sourceTokens,
|
|
175
|
+
balances
|
|
176
|
+
);
|
|
177
|
+
const destinationTokensWithBalance = getTokensWithBalance(
|
|
178
|
+
destinationTokens,
|
|
179
|
+
balances
|
|
180
|
+
);
|
|
181
|
+
return {
|
|
182
|
+
sourceTokens: sortTokens(sourceTokensWithBalance),
|
|
183
|
+
destinationTokens: sortTokens(destinationTokensWithBalance),
|
|
184
|
+
};
|
|
185
|
+
});
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
equalityFn: shallow,
|
|
189
|
+
}
|
|
190
|
+
);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { BlockchainMeta, Token } from 'rango-sdk';
|
|
2
|
+
import { WalletType } from '@rango-dev/wallets-shared';
|
|
3
|
+
export interface Source {
|
|
4
|
+
title: string;
|
|
5
|
+
type: 'BRIDGE' | 'AGGREGATOR' | 'DEX';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type Colors = {
|
|
9
|
+
background?: string;
|
|
10
|
+
// inputBackground?: string;
|
|
11
|
+
// icons?: string;
|
|
12
|
+
primary?: string;
|
|
13
|
+
foreground?: string;
|
|
14
|
+
// text?: string;
|
|
15
|
+
success?: string;
|
|
16
|
+
error?: string;
|
|
17
|
+
warning?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type Configs = {
|
|
21
|
+
fromChain: BlockchainMeta | null;
|
|
22
|
+
fromToken: Token | null;
|
|
23
|
+
toChain: BlockchainMeta | null;
|
|
24
|
+
toToken: Token | null;
|
|
25
|
+
fromAmount: number;
|
|
26
|
+
fromChains: 'all' | BlockchainMeta[];
|
|
27
|
+
fromTokens: 'all' | Token[];
|
|
28
|
+
toChains: 'all' | BlockchainMeta[];
|
|
29
|
+
toTokens: 'all' | Token[];
|
|
30
|
+
liquiditySources: 'all' | Source[];
|
|
31
|
+
wallets: 'all' | WalletType[];
|
|
32
|
+
multiWallets: boolean;
|
|
33
|
+
customeAddress: boolean;
|
|
34
|
+
theme: 'dark' | 'light' | 'auto';
|
|
35
|
+
title: string;
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
languege: string;
|
|
39
|
+
borderRadius: number;
|
|
40
|
+
fontFamily: string;
|
|
41
|
+
titleSize: number;
|
|
42
|
+
titleWeight: number;
|
|
43
|
+
colors: Colors;
|
|
44
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { RouteState } from '../store/bestRoute';
|
|
2
|
+
import { SettingsState } from '../store/settings';
|
|
3
|
+
|
|
4
|
+
export interface BestRouteParams {
|
|
5
|
+
fromChain?: RouteState['fromChain'];
|
|
6
|
+
toChain?: RouteState['toChain'];
|
|
7
|
+
fromToken?: RouteState['fromToken'];
|
|
8
|
+
toToken?: RouteState['toToken'];
|
|
9
|
+
inputAmount?: RouteState['inputAmount'];
|
|
10
|
+
slippage?: SettingsState['slippage'];
|
|
11
|
+
customSlippage?: SettingsState['customSlippage'];
|
|
12
|
+
disabledLiquiditySources?: SettingsState['disabledLiquiditySources'];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export enum ConfirmSwapErrorTypes {
|
|
16
|
+
NO_ROUTE,
|
|
17
|
+
ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS,
|
|
18
|
+
REQUEST_FAILED,
|
|
19
|
+
INSUFFICIENT_SLIPPAGE,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type ConfirmSwapError =
|
|
23
|
+
| {
|
|
24
|
+
type: ConfirmSwapErrorTypes.REQUEST_FAILED;
|
|
25
|
+
status?: number;
|
|
26
|
+
}
|
|
27
|
+
| {
|
|
28
|
+
type: ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE;
|
|
29
|
+
minRequiredSlippage: number | null;
|
|
30
|
+
}
|
|
31
|
+
| {
|
|
32
|
+
type: Exclude<
|
|
33
|
+
ConfirmSwapErrorTypes,
|
|
34
|
+
| ConfirmSwapErrorTypes.REQUEST_FAILED
|
|
35
|
+
| ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE
|
|
36
|
+
>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type ConfirmSwapWarnings =
|
|
40
|
+
| {
|
|
41
|
+
type: ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED;
|
|
42
|
+
newOutputAmount: string;
|
|
43
|
+
percentageChange: string;
|
|
44
|
+
}
|
|
45
|
+
| { type: ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE; messages: string[] }
|
|
46
|
+
| {
|
|
47
|
+
type: Exclude<
|
|
48
|
+
ConfirmSwapWarningTypes,
|
|
49
|
+
| ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED
|
|
50
|
+
| ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE
|
|
51
|
+
>;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export enum ConfirmSwapWarningTypes {
|
|
55
|
+
ROUTE_UPDATED,
|
|
56
|
+
ROUTE_SWAPPERS_UPDATED,
|
|
57
|
+
ROUTE_COINS_UPDATED,
|
|
58
|
+
ROUTE_AND_OUTPUT_AMOUNT_UPDATED,
|
|
59
|
+
INSUFFICIENT_BALANCE,
|
|
60
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SwapSavedSettings } from '@rango-dev/ui/dist/types/swaps';
|
|
2
|
+
|
|
3
|
+
export type PendingSwapSettings = Omit<
|
|
4
|
+
SwapSavedSettings,
|
|
5
|
+
'disabledSwappersIds'
|
|
6
|
+
>;
|
|
7
|
+
|
|
8
|
+
export type SwapButtonState = (
|
|
9
|
+
| { disabled: true }
|
|
10
|
+
| { disabled: false; hasWarning?: boolean }
|
|
11
|
+
) & {
|
|
12
|
+
title: string;
|
|
13
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function removeDuplicateFrom<T>(array: T[]): T[] {
|
|
2
|
+
return Array.from(new Set(array));
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function areEqual(
|
|
6
|
+
array1: (number | string)[],
|
|
7
|
+
array2: (number | string)[]
|
|
8
|
+
) {
|
|
9
|
+
return (
|
|
10
|
+
array1.length === array2.length && array1.every((v, i) => v === array2[i])
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
export function shadeColor(color: string, percent: number) {
|
|
14
|
+
var R = parseInt(color.substring(1, 3), 16);
|
|
15
|
+
var G = parseInt(color.substring(3, 5), 16);
|
|
16
|
+
var B = parseInt(color.substring(5, 7), 16);
|
|
17
|
+
|
|
18
|
+
R = (R * (100 + percent)) / 100;
|
|
19
|
+
G = (G * (100 + percent)) / 100;
|
|
20
|
+
B = (B * (100 + percent)) / 100;
|
|
21
|
+
|
|
22
|
+
R = R < 255 ? R : 255;
|
|
23
|
+
G = G < 255 ? G : 255;
|
|
24
|
+
B = B < 255 ? B : 255;
|
|
25
|
+
|
|
26
|
+
R = Math.round(R);
|
|
27
|
+
G = Math.round(G);
|
|
28
|
+
B = Math.round(B);
|
|
29
|
+
|
|
30
|
+
var RR = R.toString(16).length == 1 ? '0' + R.toString(16) : R.toString(16);
|
|
31
|
+
var GG = G.toString(16).length == 1 ? '0' + G.toString(16) : G.toString(16);
|
|
32
|
+
var BB = B.toString(16).length == 1 ? '0' + B.toString(16) : B.toString(16);
|
|
33
|
+
|
|
34
|
+
return '#' + RR + GG + BB;
|
|
35
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { BigNumber } from 'bignumber.js';
|
|
2
|
+
import { BestRouteResponse } from 'rango-sdk';
|
|
3
|
+
|
|
4
|
+
export const percentToString = (p: number, fractions = 0): string =>
|
|
5
|
+
(p * 100).toFixed(fractions);
|
|
6
|
+
export const secondsToString = (s: number): string => {
|
|
7
|
+
const seconds = (s % 60).toString().padStart(2, '0');
|
|
8
|
+
const minutes = parseInt((s / 60).toString())
|
|
9
|
+
.toString()
|
|
10
|
+
.padStart(2, '0');
|
|
11
|
+
return `${minutes}:${seconds}`;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const numberToString = (
|
|
15
|
+
number: BigNumber | string | null,
|
|
16
|
+
minDecimals: number | null = null,
|
|
17
|
+
maxDecimals: number | null = null
|
|
18
|
+
): string => {
|
|
19
|
+
if (number === null) return '';
|
|
20
|
+
if (number === '') return '';
|
|
21
|
+
const n = new BigNumber(number);
|
|
22
|
+
const roundingMode = 1;
|
|
23
|
+
let maxI = 1000;
|
|
24
|
+
for (let i = 0; i < 60; i++) {
|
|
25
|
+
if (new BigNumber(n.toFixed(i, roundingMode)).eq(n)) {
|
|
26
|
+
maxI = i;
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (n.gte(10000)) return n.toFormat(0, roundingMode);
|
|
32
|
+
if (n.gte(1000))
|
|
33
|
+
return n.toFormat(
|
|
34
|
+
Math.min(
|
|
35
|
+
maxI,
|
|
36
|
+
Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))
|
|
37
|
+
),
|
|
38
|
+
roundingMode
|
|
39
|
+
);
|
|
40
|
+
if (n.gte(100))
|
|
41
|
+
return n.toFormat(
|
|
42
|
+
Math.min(
|
|
43
|
+
maxI,
|
|
44
|
+
Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))
|
|
45
|
+
),
|
|
46
|
+
roundingMode
|
|
47
|
+
);
|
|
48
|
+
if (n.gte(1))
|
|
49
|
+
return n.toFormat(
|
|
50
|
+
Math.min(
|
|
51
|
+
maxI,
|
|
52
|
+
Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 2))
|
|
53
|
+
),
|
|
54
|
+
roundingMode
|
|
55
|
+
);
|
|
56
|
+
if (n.gte(0.01))
|
|
57
|
+
return n.toFormat(
|
|
58
|
+
Math.min(
|
|
59
|
+
maxI,
|
|
60
|
+
Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 4))
|
|
61
|
+
),
|
|
62
|
+
roundingMode
|
|
63
|
+
);
|
|
64
|
+
for (let i = minDecimals || 4; i < 17; i++)
|
|
65
|
+
if (n.gte(Math.pow(10, -i)))
|
|
66
|
+
return n.toFormat(
|
|
67
|
+
Math.min(
|
|
68
|
+
maxI,
|
|
69
|
+
Math.min(maxDecimals || 100, Math.max(minDecimals || 0, i))
|
|
70
|
+
),
|
|
71
|
+
roundingMode
|
|
72
|
+
);
|
|
73
|
+
if (n.isEqualTo(0)) return '0';
|
|
74
|
+
|
|
75
|
+
return n.toFormat(
|
|
76
|
+
Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 8))),
|
|
77
|
+
roundingMode
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const convertBigNumberToHex = (
|
|
82
|
+
value: BigNumber,
|
|
83
|
+
decimals: number
|
|
84
|
+
): string => {
|
|
85
|
+
return '0x' + value.shiftedBy(decimals).toString(16);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const uint8ArrayToHex = (buffer: Uint8Array): string => {
|
|
89
|
+
// buffer is an ArrayBuffer
|
|
90
|
+
// @ts-ignore
|
|
91
|
+
return [...buffer].map((x) => x.toString(16).padStart(2, '0')).join('');
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export function dollarToConciseString(num: number | undefined): string {
|
|
95
|
+
if (!num) return '-';
|
|
96
|
+
if (num < 1) return ' < 1$';
|
|
97
|
+
if (num < 1000) return numberToString(new BigNumber(num)) + '$';
|
|
98
|
+
if (num < 10_000) return parseInt((num / 100).toString()) / 10 + 'K';
|
|
99
|
+
if (num < 1_000_000) return parseInt((num / 1000).toString()) + 'K';
|
|
100
|
+
if (num < 100_000_000) return parseInt((num / 100000).toString()) / 10 + 'M';
|
|
101
|
+
return parseInt((num / 1000000).toString()) + 'M';
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function removeExtraDecimals(num: string, maxDecimals: number): string {
|
|
105
|
+
try {
|
|
106
|
+
if (!num.includes('.')) return num;
|
|
107
|
+
const [b, f] = num.split('.');
|
|
108
|
+
if (f && f.length > maxDecimals) {
|
|
109
|
+
return `${b}.${f.substring(0, maxDecimals)}`;
|
|
110
|
+
}
|
|
111
|
+
return num;
|
|
112
|
+
} catch (e) {
|
|
113
|
+
return num;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export const totalArrivalTime = (data: BestRouteResponse | null) =>
|
|
118
|
+
data?.result?.swaps?.reduce((a, b) => a + b.estimatedTimeInSeconds, 0) || 0;
|
|
119
|
+
|
|
120
|
+
export const rawFees = (data: BestRouteResponse): string =>
|
|
121
|
+
(
|
|
122
|
+
data?.result?.swaps?.flatMap((s) =>
|
|
123
|
+
s.fee.map((f) => ({ swapperId: s.swapperId, fee: f }))
|
|
124
|
+
) || []
|
|
125
|
+
)
|
|
126
|
+
.reduce((partialSum, a) => partialSum + parseFloat(a.fee.amount), 0)
|
|
127
|
+
.toFixed(3);
|
|
128
|
+
|
|
129
|
+
export const decimalNumber = (number = '0', toFixed: number) =>
|
|
130
|
+
parseFloat(number).toFixed(toFixed);
|
|
131
|
+
|
|
132
|
+
export const containsText = (text: string, searchText: string) =>
|
|
133
|
+
text.toLowerCase().indexOf(searchText.toLowerCase()) > -1;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Manager } from '@rango-dev/queue-manager-core';
|
|
2
|
+
import {
|
|
3
|
+
PendingSwapWithQueueID,
|
|
4
|
+
SwapStorage,
|
|
5
|
+
} from '@rango-dev/queue-manager-rango-preset';
|
|
6
|
+
|
|
7
|
+
export const getPendingSwaps = (manager: Manager | undefined) => {
|
|
8
|
+
const result: PendingSwapWithQueueID[] = [];
|
|
9
|
+
|
|
10
|
+
manager?.getAll().forEach((q, id) => {
|
|
11
|
+
const storage = q.list.getStorage() as SwapStorage;
|
|
12
|
+
|
|
13
|
+
if (storage?.swapDetails) {
|
|
14
|
+
result.push({
|
|
15
|
+
id,
|
|
16
|
+
swap: storage?.swapDetails,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return result.sort(
|
|
22
|
+
(a, b) => Number(b.swap.creationTime) - Number(a.swap.creationTime)
|
|
23
|
+
);
|
|
24
|
+
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SimulationAssetAndAmount,
|
|
3
|
+
SimulationValidationStatus,
|
|
4
|
+
} from '@rango-dev/ui/dist/types/swaps';
|
|
5
|
+
import BigNumber from 'bignumber.js';
|
|
6
|
+
import { BestRouteResponse, BlockchainMeta, Token } from 'rango-sdk';
|
|
7
|
+
import { areEqual } from './common';
|
|
8
|
+
import { SelectedWallet } from './wallets';
|
|
9
|
+
import { BestRouteParams } from '../types';
|
|
10
|
+
import { TokenMeta } from '@rango-dev/ui/dist/types/meta';
|
|
11
|
+
import { numberToString } from './numbers';
|
|
12
|
+
import { getUsdFeeOfStep } from './swap';
|
|
13
|
+
import { BestRouteWithFee } from '@rango-dev/ui';
|
|
14
|
+
|
|
15
|
+
export function searchParamsToToken(
|
|
16
|
+
tokens: Token[],
|
|
17
|
+
searchParams: string | null,
|
|
18
|
+
chain: BlockchainMeta | null
|
|
19
|
+
): Token | null {
|
|
20
|
+
if (!chain) return null;
|
|
21
|
+
return (
|
|
22
|
+
tokens.find((token) => {
|
|
23
|
+
const symbolAndAddress = searchParams?.split('--');
|
|
24
|
+
if (symbolAndAddress?.length === 1)
|
|
25
|
+
return (
|
|
26
|
+
token.symbol === symbolAndAddress[0] &&
|
|
27
|
+
token.address === null &&
|
|
28
|
+
token.blockchain === chain.name
|
|
29
|
+
);
|
|
30
|
+
return (
|
|
31
|
+
token.symbol === symbolAndAddress?.[0] &&
|
|
32
|
+
token.address === symbolAndAddress?.[1] &&
|
|
33
|
+
token.blockchain === chain.name
|
|
34
|
+
);
|
|
35
|
+
}) || null
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getBestRouteToTokenUsdPrice(
|
|
40
|
+
bestRoute: BestRouteResponse | null
|
|
41
|
+
): number | null | undefined {
|
|
42
|
+
return bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1].to
|
|
43
|
+
.usdPrice;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function isNumberOfSwapsChanged(
|
|
47
|
+
route1: BestRouteResponse,
|
|
48
|
+
route2: BestRouteResponse
|
|
49
|
+
) {
|
|
50
|
+
const route1Swaps = route1.result?.swaps || [];
|
|
51
|
+
const route2Swaps = route2.result?.swaps || [];
|
|
52
|
+
return route1Swaps.length !== route2Swaps.length;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function isRouteSwappersUpdated(
|
|
56
|
+
route1: BestRouteResponse,
|
|
57
|
+
route2: BestRouteResponse
|
|
58
|
+
) {
|
|
59
|
+
const route1Swappers =
|
|
60
|
+
route1.result?.swaps.map((swap) => swap.swapperId) || [];
|
|
61
|
+
const route2Swappers =
|
|
62
|
+
route2.result?.swaps.map((swap) => swap.swapperId) || [];
|
|
63
|
+
return !areEqual(route1Swappers, route2Swappers);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function isRouteInternalCoinsUpdated(
|
|
67
|
+
route1: BestRouteResponse,
|
|
68
|
+
route2: BestRouteResponse
|
|
69
|
+
) {
|
|
70
|
+
const route1InternalCoins =
|
|
71
|
+
route1.result?.swaps.map((swap) => swap.to.symbol) || [];
|
|
72
|
+
const route2InternalCoins =
|
|
73
|
+
route2.result?.swaps.map((swap) => swap.to.symbol) || [];
|
|
74
|
+
return !areEqual(route1InternalCoins, route2InternalCoins);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function isRouteChanged(
|
|
78
|
+
route1: BestRouteResponse,
|
|
79
|
+
route2: BestRouteResponse
|
|
80
|
+
): boolean {
|
|
81
|
+
return (
|
|
82
|
+
isNumberOfSwapsChanged(route1, route2) ||
|
|
83
|
+
isRouteSwappersUpdated(route1, route2) ||
|
|
84
|
+
isRouteInternalCoinsUpdated(route1, route2)
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function outToRatioHasWarning(
|
|
89
|
+
fromUsdValue: BigNumber | null,
|
|
90
|
+
outToInRatio: BigNumber | 0
|
|
91
|
+
) {
|
|
92
|
+
return (
|
|
93
|
+
(parseInt(outToInRatio?.toFixed(2) || '0') <= -10 &&
|
|
94
|
+
(fromUsdValue === null || fromUsdValue.gte(new BigNumber(200)))) ||
|
|
95
|
+
(parseInt(outToInRatio?.toFixed(2) || '0') <= -5 &&
|
|
96
|
+
(fromUsdValue === null || fromUsdValue.gte(new BigNumber(1000))))
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function getRequiredBalanceOfWallet(
|
|
101
|
+
selectedWallet: SelectedWallet,
|
|
102
|
+
fee: SimulationValidationStatus[] | null
|
|
103
|
+
): SimulationAssetAndAmount[] | null {
|
|
104
|
+
if (fee === null) return null;
|
|
105
|
+
const relatedFeeStatus = fee
|
|
106
|
+
?.find((item) => item.blockchain === selectedWallet.chain)
|
|
107
|
+
?.wallets.find(
|
|
108
|
+
(wallet) =>
|
|
109
|
+
wallet.address?.toLowerCase() === selectedWallet.address.toLowerCase()
|
|
110
|
+
);
|
|
111
|
+
if (!relatedFeeStatus) return null;
|
|
112
|
+
return relatedFeeStatus.requiredAssets;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function isRouteParametersChanged(
|
|
116
|
+
prevParams: BestRouteParams,
|
|
117
|
+
currentParams: BestRouteParams
|
|
118
|
+
) {
|
|
119
|
+
return (
|
|
120
|
+
prevParams.fromChain?.name !== currentParams.fromChain?.name ||
|
|
121
|
+
prevParams.toChain?.name !== currentParams.toChain?.name ||
|
|
122
|
+
prevParams.fromToken?.symbol !== currentParams.fromToken?.symbol ||
|
|
123
|
+
prevParams.toToken?.symbol !== currentParams.toToken?.symbol ||
|
|
124
|
+
prevParams.fromToken?.blockchain !== currentParams.fromToken?.blockchain ||
|
|
125
|
+
prevParams.toToken?.blockchain !== currentParams.toToken?.blockchain ||
|
|
126
|
+
prevParams.fromToken?.address !== currentParams.fromToken?.address ||
|
|
127
|
+
prevParams.toToken?.address !== currentParams.toToken?.address ||
|
|
128
|
+
prevParams.inputAmount !== currentParams.inputAmount ||
|
|
129
|
+
prevParams.slippage !== currentParams.slippage ||
|
|
130
|
+
prevParams.customSlippage !== currentParams.customSlippage ||
|
|
131
|
+
prevParams.disabledLiquiditySources?.length !==
|
|
132
|
+
currentParams.disabledLiquiditySources?.length
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function getBestRouteWithCalculatedFees(
|
|
137
|
+
bestRoute: BestRouteResponse | null,
|
|
138
|
+
tokens: TokenMeta[]
|
|
139
|
+
): BestRouteWithFee | null {
|
|
140
|
+
if (!bestRoute || !bestRoute.result) return null;
|
|
141
|
+
const swapsWithFee = (bestRoute?.result?.swaps || []).map((swap) => ({
|
|
142
|
+
...swap,
|
|
143
|
+
feeInUsd: numberToString(getUsdFeeOfStep(swap, tokens), 0, 2),
|
|
144
|
+
}));
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
...bestRoute,
|
|
148
|
+
result: { ...bestRoute.result, swaps: swapsWithFee },
|
|
149
|
+
};
|
|
150
|
+
}
|