@reown/appkit-core-react-native 0.0.0-canary-20241219175647 → 0.0.0-chore-builder-20250117182343

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.
Files changed (167) hide show
  1. package/lib/commonjs/controllers/AccountController.js.map +1 -1
  2. package/lib/commonjs/controllers/ApiController.js +1 -1
  3. package/lib/commonjs/controllers/ApiController.js.map +1 -1
  4. package/lib/commonjs/controllers/AssetController.js.map +1 -1
  5. package/lib/commonjs/controllers/BlockchainApiController.js +107 -21
  6. package/lib/commonjs/controllers/BlockchainApiController.js.map +1 -1
  7. package/lib/commonjs/controllers/ConnectionController.js +4 -2
  8. package/lib/commonjs/controllers/ConnectionController.js.map +1 -1
  9. package/lib/commonjs/controllers/ConnectorController.js.map +1 -1
  10. package/lib/commonjs/controllers/EnsController.js.map +1 -1
  11. package/lib/commonjs/controllers/EventsController.js.map +1 -1
  12. package/lib/commonjs/controllers/ModalController.js.map +1 -1
  13. package/lib/commonjs/controllers/NetworkController.js +6 -0
  14. package/lib/commonjs/controllers/NetworkController.js.map +1 -1
  15. package/lib/commonjs/controllers/OptionsController.js.map +1 -1
  16. package/lib/commonjs/controllers/PublicStateController.js.map +1 -1
  17. package/lib/commonjs/controllers/RouterController.js.map +1 -1
  18. package/lib/commonjs/controllers/SendController.js.map +1 -1
  19. package/lib/commonjs/controllers/SnackController.js +5 -0
  20. package/lib/commonjs/controllers/SnackController.js.map +1 -1
  21. package/lib/commonjs/controllers/SwapController.js +578 -6
  22. package/lib/commonjs/controllers/SwapController.js.map +1 -1
  23. package/lib/commonjs/controllers/ThemeController.js +1 -1
  24. package/lib/commonjs/controllers/ThemeController.js.map +1 -1
  25. package/lib/commonjs/controllers/TransactionsController.js.map +1 -1
  26. package/lib/commonjs/controllers/WebviewController.js.map +1 -1
  27. package/lib/commonjs/index.js +14 -0
  28. package/lib/commonjs/index.js.map +1 -1
  29. package/lib/commonjs/package.json +1 -0
  30. package/lib/commonjs/utils/ApiUtil.js.map +1 -1
  31. package/lib/commonjs/utils/AssetUtil.js.map +1 -1
  32. package/lib/commonjs/utils/ConnectionUtil.js +33 -0
  33. package/lib/commonjs/utils/ConnectionUtil.js.map +1 -0
  34. package/lib/commonjs/utils/ConstantsUtil.js +29 -0
  35. package/lib/commonjs/utils/ConstantsUtil.js.map +1 -1
  36. package/lib/commonjs/utils/CoreHelperUtil.js +12 -12
  37. package/lib/commonjs/utils/CoreHelperUtil.js.map +1 -1
  38. package/lib/commonjs/utils/EventUtil.js.map +1 -1
  39. package/lib/commonjs/utils/FetchUtil.js.map +1 -1
  40. package/lib/commonjs/utils/NetworkUtil.js +46 -0
  41. package/lib/commonjs/utils/NetworkUtil.js.map +1 -0
  42. package/lib/commonjs/utils/RouterUtil.js +1 -1
  43. package/lib/commonjs/utils/RouterUtil.js.map +1 -1
  44. package/lib/commonjs/utils/StorageUtil.js +1 -1
  45. package/lib/commonjs/utils/StorageUtil.js.map +1 -1
  46. package/lib/commonjs/utils/SwapApiUtil.js +58 -0
  47. package/lib/commonjs/utils/SwapApiUtil.js.map +1 -1
  48. package/lib/commonjs/utils/SwapCalculationUtil.js +73 -0
  49. package/lib/commonjs/utils/SwapCalculationUtil.js.map +1 -1
  50. package/lib/commonjs/utils/TypeUtil.js.map +1 -1
  51. package/lib/module/controllers/AccountController.js +2 -0
  52. package/lib/module/controllers/AccountController.js.map +1 -1
  53. package/lib/module/controllers/ApiController.js +3 -1
  54. package/lib/module/controllers/ApiController.js.map +1 -1
  55. package/lib/module/controllers/AssetController.js +2 -0
  56. package/lib/module/controllers/AssetController.js.map +1 -1
  57. package/lib/module/controllers/BlockchainApiController.js +109 -21
  58. package/lib/module/controllers/BlockchainApiController.js.map +1 -1
  59. package/lib/module/controllers/ConnectionController.js +6 -2
  60. package/lib/module/controllers/ConnectionController.js.map +1 -1
  61. package/lib/module/controllers/ConnectorController.js +2 -0
  62. package/lib/module/controllers/ConnectorController.js.map +1 -1
  63. package/lib/module/controllers/EnsController.js +2 -0
  64. package/lib/module/controllers/EnsController.js.map +1 -1
  65. package/lib/module/controllers/EventsController.js +2 -0
  66. package/lib/module/controllers/EventsController.js.map +1 -1
  67. package/lib/module/controllers/ModalController.js +2 -0
  68. package/lib/module/controllers/ModalController.js.map +1 -1
  69. package/lib/module/controllers/NetworkController.js +8 -0
  70. package/lib/module/controllers/NetworkController.js.map +1 -1
  71. package/lib/module/controllers/OptionsController.js +2 -0
  72. package/lib/module/controllers/OptionsController.js.map +1 -1
  73. package/lib/module/controllers/PublicStateController.js +2 -0
  74. package/lib/module/controllers/PublicStateController.js.map +1 -1
  75. package/lib/module/controllers/RouterController.js +2 -0
  76. package/lib/module/controllers/RouterController.js.map +1 -1
  77. package/lib/module/controllers/SendController.js +2 -0
  78. package/lib/module/controllers/SendController.js.map +1 -1
  79. package/lib/module/controllers/SnackController.js +7 -0
  80. package/lib/module/controllers/SnackController.js.map +1 -1
  81. package/lib/module/controllers/SwapController.js +580 -6
  82. package/lib/module/controllers/SwapController.js.map +1 -1
  83. package/lib/module/controllers/ThemeController.js +3 -1
  84. package/lib/module/controllers/ThemeController.js.map +1 -1
  85. package/lib/module/controllers/TransactionsController.js +2 -0
  86. package/lib/module/controllers/TransactionsController.js.map +1 -1
  87. package/lib/module/controllers/WebviewController.js +2 -0
  88. package/lib/module/controllers/WebviewController.js.map +1 -1
  89. package/lib/module/index.js +4 -0
  90. package/lib/module/index.js.map +1 -1
  91. package/lib/module/package.json +1 -0
  92. package/lib/module/utils/ApiUtil.js +2 -0
  93. package/lib/module/utils/ApiUtil.js.map +1 -1
  94. package/lib/module/utils/AssetUtil.js +2 -0
  95. package/lib/module/utils/AssetUtil.js.map +1 -1
  96. package/lib/module/utils/ConnectionUtil.js +29 -0
  97. package/lib/module/utils/ConnectionUtil.js.map +1 -0
  98. package/lib/module/utils/ConstantsUtil.js +31 -0
  99. package/lib/module/utils/ConstantsUtil.js.map +1 -1
  100. package/lib/module/utils/CoreHelperUtil.js +14 -12
  101. package/lib/module/utils/CoreHelperUtil.js.map +1 -1
  102. package/lib/module/utils/EventUtil.js +2 -0
  103. package/lib/module/utils/EventUtil.js.map +1 -1
  104. package/lib/module/utils/FetchUtil.js +2 -0
  105. package/lib/module/utils/FetchUtil.js.map +1 -1
  106. package/lib/module/utils/NetworkUtil.js +42 -0
  107. package/lib/module/utils/NetworkUtil.js.map +1 -0
  108. package/lib/module/utils/RouterUtil.js +3 -1
  109. package/lib/module/utils/RouterUtil.js.map +1 -1
  110. package/lib/module/utils/StorageUtil.js +2 -0
  111. package/lib/module/utils/StorageUtil.js.map +1 -1
  112. package/lib/module/utils/SwapApiUtil.js +60 -0
  113. package/lib/module/utils/SwapApiUtil.js.map +1 -1
  114. package/lib/module/utils/SwapCalculationUtil.js +75 -1
  115. package/lib/module/utils/SwapCalculationUtil.js.map +1 -1
  116. package/lib/module/utils/TypeUtil.js +2 -0
  117. package/lib/module/utils/TypeUtil.js.map +1 -1
  118. package/lib/typescript/controllers/ApiController.d.ts +1 -1
  119. package/lib/typescript/controllers/BlockchainApiController.d.ts +6 -1
  120. package/lib/typescript/controllers/BlockchainApiController.d.ts.map +1 -1
  121. package/lib/typescript/controllers/ConnectionController.d.ts +3 -1
  122. package/lib/typescript/controllers/ConnectionController.d.ts.map +1 -1
  123. package/lib/typescript/controllers/NetworkController.d.ts +1 -0
  124. package/lib/typescript/controllers/NetworkController.d.ts.map +1 -1
  125. package/lib/typescript/controllers/RouterController.d.ts +3 -2
  126. package/lib/typescript/controllers/RouterController.d.ts.map +1 -1
  127. package/lib/typescript/controllers/SnackController.d.ts +2 -1
  128. package/lib/typescript/controllers/SnackController.d.ts.map +1 -1
  129. package/lib/typescript/controllers/SwapController.d.ts +87 -0
  130. package/lib/typescript/controllers/SwapController.d.ts.map +1 -1
  131. package/lib/typescript/controllers/ThemeController.d.ts +2 -2
  132. package/lib/typescript/controllers/ThemeController.d.ts.map +1 -1
  133. package/lib/typescript/index.d.ts +2 -0
  134. package/lib/typescript/index.d.ts.map +1 -1
  135. package/lib/typescript/utils/ConnectionUtil.d.ts +4 -0
  136. package/lib/typescript/utils/ConnectionUtil.d.ts.map +1 -0
  137. package/lib/typescript/utils/ConstantsUtil.d.ts +4 -0
  138. package/lib/typescript/utils/ConstantsUtil.d.ts.map +1 -1
  139. package/lib/typescript/utils/CoreHelperUtil.d.ts +2 -2
  140. package/lib/typescript/utils/CoreHelperUtil.d.ts.map +1 -1
  141. package/lib/typescript/utils/NetworkUtil.d.ts +8 -0
  142. package/lib/typescript/utils/NetworkUtil.d.ts.map +1 -0
  143. package/lib/typescript/utils/RouterUtil.d.ts.map +1 -1
  144. package/lib/typescript/utils/SwapApiUtil.d.ts +8 -0
  145. package/lib/typescript/utils/SwapApiUtil.d.ts.map +1 -1
  146. package/lib/typescript/utils/SwapCalculationUtil.d.ts +19 -0
  147. package/lib/typescript/utils/SwapCalculationUtil.d.ts.map +1 -1
  148. package/lib/typescript/utils/TypeUtil.d.ts +146 -6
  149. package/lib/typescript/utils/TypeUtil.d.ts.map +1 -1
  150. package/package.json +3 -17
  151. package/src/controllers/ApiController.ts +1 -1
  152. package/src/controllers/BlockchainApiController.ts +114 -17
  153. package/src/controllers/ConnectionController.ts +6 -2
  154. package/src/controllers/NetworkController.ts +8 -0
  155. package/src/controllers/RouterController.ts +6 -1
  156. package/src/controllers/SnackController.ts +7 -1
  157. package/src/controllers/SwapController.ts +759 -6
  158. package/src/controllers/ThemeController.ts +3 -3
  159. package/src/index.ts +2 -0
  160. package/src/utils/ConnectionUtil.ts +27 -0
  161. package/src/utils/ConstantsUtil.ts +120 -0
  162. package/src/utils/CoreHelperUtil.ts +20 -15
  163. package/src/utils/NetworkUtil.ts +33 -0
  164. package/src/utils/RouterUtil.ts +4 -1
  165. package/src/utils/SwapApiUtil.ts +89 -0
  166. package/src/utils/SwapCalculationUtil.ts +125 -0
  167. package/src/utils/TypeUtil.ts +169 -10
@@ -1,11 +1,22 @@
1
+ "use strict";
2
+
1
3
  import { subscribeKey as subKey } from 'valtio/utils';
2
4
  import { proxy, subscribe as sub } from 'valtio';
5
+ import { NumberUtil } from '@reown/appkit-common-react-native';
3
6
  import { ConstantsUtil } from '../utils/ConstantsUtil';
4
7
  import { SwapApiUtil } from '../utils/SwapApiUtil';
5
8
  import { NetworkController } from './NetworkController';
6
9
  import { BlockchainApiController } from './BlockchainApiController';
7
10
  import { OptionsController } from './OptionsController';
8
11
  import { SwapCalculationUtil } from '../utils/SwapCalculationUtil';
12
+ import { SnackController } from './SnackController';
13
+ import { RouterController } from './RouterController';
14
+ import { ConnectorController } from './ConnectorController';
15
+ import { AccountController } from './AccountController';
16
+ import { CoreHelperUtil } from '../utils/CoreHelperUtil';
17
+ import { ConnectionController } from './ConnectionController';
18
+ import { TransactionsController } from './TransactionsController';
19
+ import { EventsController } from './EventsController';
9
20
 
10
21
  // -- Constants ---------------------------------------- //
11
22
  export const INITIAL_GAS_LIMIT = 150000;
@@ -13,16 +24,55 @@ export const TO_AMOUNT_DECIMALS = 6;
13
24
 
14
25
  // -- Types --------------------------------------------- //
15
26
 
27
+ class TransactionError extends Error {
28
+ constructor(message, shortMessage) {
29
+ super(message);
30
+ this.name = 'TransactionError';
31
+ this.shortMessage = shortMessage;
32
+ }
33
+ }
16
34
  // -- State --------------------------------------------- //
17
35
  const initialState = {
36
+ // Loading states
37
+ initializing: false,
38
+ initialized: false,
39
+ loadingPrices: false,
40
+ loadingQuote: false,
41
+ loadingApprovalTransaction: false,
42
+ loadingBuildTransaction: false,
43
+ loadingTransaction: false,
44
+ // Error states
45
+ fetchError: false,
46
+ // Approval & Swap transaction states
47
+ approvalTransaction: undefined,
48
+ swapTransaction: undefined,
49
+ transactionError: undefined,
18
50
  // Input values
51
+ sourceToken: undefined,
52
+ sourceTokenAmount: '',
53
+ sourceTokenPriceInUSD: 0,
54
+ toToken: undefined,
55
+ toTokenAmount: '',
56
+ toTokenPriceInUSD: 0,
19
57
  networkPrice: '0',
58
+ networkBalanceInUSD: '0',
20
59
  networkTokenSymbol: '',
60
+ inputError: undefined,
61
+ // Request values
62
+ slippage: ConstantsUtil.CONVERT_SLIPPAGE_TOLERANCE,
21
63
  // Tokens
64
+ tokens: undefined,
65
+ popularTokens: undefined,
66
+ suggestedTokens: undefined,
67
+ foundTokens: undefined,
68
+ myTokensWithBalance: undefined,
22
69
  tokensPriceMap: {},
23
70
  // Calculations
24
71
  gasFee: '0',
25
- gasPriceInUSD: 0
72
+ gasPriceInUSD: 0,
73
+ priceImpact: undefined,
74
+ maxSlippage: undefined,
75
+ providerFee: undefined
26
76
  };
27
77
  const state = proxy(initialState);
28
78
 
@@ -36,18 +86,164 @@ export const SwapController = {
36
86
  return subKey(state, key, callback);
37
87
  },
38
88
  getParams() {
39
- const caipNetwork = NetworkController.state.caipNetwork;
40
- const networkAddress = `${caipNetwork?.id}:${ConstantsUtil.NATIVE_TOKEN_ADDRESS}`;
89
+ const caipAddress = AccountController.state.caipAddress;
90
+ const address = CoreHelperUtil.getPlainAddress(caipAddress);
91
+ const networkAddress = NetworkController.getActiveNetworkTokenAddress();
92
+ const type = ConnectorController.state.connectedConnector;
93
+ if (!address) {
94
+ throw new Error('No address found to swap the tokens from.');
95
+ }
96
+ const invalidToToken = !state.toToken?.address || !state.toToken?.decimals;
97
+ const invalidSourceToken = !state.sourceToken?.address || !state.sourceToken?.decimals || state.sourceToken.address === state.toToken?.address || !NumberUtil.bigNumber(state.sourceTokenAmount).isGreaterThan(0);
98
+ const invalidSourceTokenAmount = !state.sourceTokenAmount;
41
99
  return {
42
- networkAddress
100
+ networkAddress,
101
+ fromAddress: address,
102
+ fromCaipAddress: caipAddress,
103
+ sourceTokenAddress: state.sourceToken?.address,
104
+ toTokenAddress: state.toToken?.address,
105
+ toTokenAmount: state.toTokenAmount,
106
+ toTokenDecimals: state.toToken?.decimals,
107
+ sourceTokenAmount: state.sourceTokenAmount,
108
+ sourceTokenDecimals: state.sourceToken?.decimals,
109
+ invalidToToken,
110
+ invalidSourceToken,
111
+ invalidSourceTokenAmount,
112
+ availableToSwap: caipAddress && !invalidToToken && !invalidSourceToken && !invalidSourceTokenAmount,
113
+ isAuthConnector: type === 'AUTH'
43
114
  };
44
115
  },
116
+ switchTokens() {
117
+ if (state.initializing || !state.initialized) {
118
+ return;
119
+ }
120
+ let newSourceToken = state.toToken ? {
121
+ ...state.toToken
122
+ } : undefined;
123
+ const sourceTokenWithBalance = state.myTokensWithBalance?.find(token => token.address === newSourceToken?.address);
124
+ if (sourceTokenWithBalance) {
125
+ newSourceToken = sourceTokenWithBalance;
126
+ }
127
+ const newToToken = state.sourceToken ? {
128
+ ...state.sourceToken
129
+ } : undefined;
130
+ const newSourceTokenAmount = newSourceToken && state.toTokenAmount === '' ? '1' : state.toTokenAmount;
131
+ this.setSourceToken(newSourceToken);
132
+ this.setToToken(newToToken);
133
+ this.setSourceTokenAmount(newSourceTokenAmount);
134
+ this.setToTokenAmount('');
135
+ this.swapTokens();
136
+ },
45
137
  resetState() {
138
+ state.myTokensWithBalance = initialState.myTokensWithBalance;
46
139
  state.tokensPriceMap = initialState.tokensPriceMap;
140
+ state.initialized = initialState.initialized;
141
+ state.sourceToken = initialState.sourceToken;
142
+ state.sourceTokenAmount = initialState.sourceTokenAmount;
143
+ state.sourceTokenPriceInUSD = initialState.sourceTokenPriceInUSD;
144
+ state.toToken = initialState.toToken;
145
+ state.toTokenAmount = initialState.toTokenAmount;
146
+ state.toTokenPriceInUSD = initialState.toTokenPriceInUSD;
47
147
  state.networkPrice = initialState.networkPrice;
48
148
  state.networkTokenSymbol = initialState.networkTokenSymbol;
149
+ state.networkBalanceInUSD = initialState.networkBalanceInUSD;
150
+ state.inputError = initialState.inputError;
151
+ },
152
+ async fetchTokens() {
153
+ const {
154
+ networkAddress
155
+ } = this.getParams();
156
+ await this.getTokenList();
157
+ await this.getNetworkTokenPrice();
158
+ await this.getMyTokensWithBalance();
159
+ const networkToken = state.tokens?.find(token => token.address === networkAddress);
160
+ if (networkToken) {
161
+ state.networkTokenSymbol = networkToken.symbol;
162
+ }
163
+ const sourceToken = state.myTokensWithBalance?.find(token => token.address.startsWith(networkAddress)) || state.myTokensWithBalance?.[0];
164
+ this.setSourceToken(sourceToken);
165
+ this.setSourceTokenAmount('1');
166
+ },
167
+ async getTokenList() {
168
+ const tokens = await SwapApiUtil.getTokenList();
169
+ state.tokens = tokens;
170
+ state.popularTokens = tokens.sort((aTokenInfo, bTokenInfo) => {
171
+ if (aTokenInfo.symbol < bTokenInfo.symbol) {
172
+ return -1;
173
+ }
174
+ if (aTokenInfo.symbol > bTokenInfo.symbol) {
175
+ return 1;
176
+ }
177
+ return 0;
178
+ });
179
+ state.suggestedTokens = tokens.filter(token => {
180
+ if (ConstantsUtil.SWAP_SUGGESTED_TOKENS.includes(token.symbol)) {
181
+ return true;
182
+ }
183
+ return false;
184
+ }, {});
185
+ },
186
+ async getMyTokensWithBalance(forceUpdate) {
187
+ const balances = await SwapApiUtil.getMyTokensWithBalance(forceUpdate);
188
+ if (!balances) {
189
+ return;
190
+ }
191
+ await this.getInitialGasPrice();
192
+ this.setBalances(balances);
193
+ },
194
+ getFilteredPopularTokens() {
195
+ return state.popularTokens?.filter(token => !state.myTokensWithBalance?.some(t => t.address === token.address));
196
+ },
197
+ setSourceToken(sourceToken) {
198
+ if (!sourceToken) {
199
+ state.sourceToken = sourceToken;
200
+ state.sourceTokenAmount = '';
201
+ state.sourceTokenPriceInUSD = 0;
202
+ return;
203
+ }
204
+ state.sourceToken = sourceToken;
205
+ this.setTokenPrice(sourceToken.address, 'sourceToken');
206
+ },
207
+ setSourceTokenAmount(amount) {
208
+ state.sourceTokenAmount = amount;
209
+ if (amount === '') {
210
+ state.toTokenAmount = '';
211
+ }
212
+ },
213
+ async initializeState() {
214
+ if (state.initializing) {
215
+ return;
216
+ }
217
+ state.initializing = true;
218
+ if (!state.initialized) {
219
+ try {
220
+ await this.fetchTokens();
221
+ state.initialized = true;
222
+ } catch (error) {
223
+ state.initialized = false;
224
+ SnackController.showError('Failed to initialize swap');
225
+ RouterController.goBack();
226
+ }
227
+ }
228
+ state.initializing = false;
229
+ },
230
+ async getAddressPrice(address) {
231
+ const existPrice = state.tokensPriceMap[address];
232
+ if (existPrice) {
233
+ return existPrice;
234
+ }
235
+ const response = await BlockchainApiController.fetchTokenPrice({
236
+ projectId: OptionsController.state.projectId,
237
+ addresses: [address]
238
+ });
239
+ const fungibles = response?.fungibles || [];
240
+ const allTokens = [...(state.tokens || []), ...(state.myTokensWithBalance || [])];
241
+ const symbol = allTokens?.find(token => token.address === address)?.symbol;
242
+ const price = fungibles.find(p => p.symbol.toLowerCase() === symbol?.toLowerCase())?.price || 0;
243
+ const priceAsFloat = parseFloat(price.toString());
244
+ state.tokensPriceMap[address] = priceAsFloat;
245
+ return priceAsFloat;
49
246
  },
50
- //this
51
247
  async getNetworkTokenPrice() {
52
248
  const {
53
249
  networkAddress
@@ -62,7 +258,6 @@ export const SwapController = {
62
258
  state.networkTokenSymbol = token?.symbol || '';
63
259
  state.networkPrice = price;
64
260
  },
65
- //this
66
261
  async getInitialGasPrice() {
67
262
  const res = await SwapApiUtil.fetchGasPrice();
68
263
  if (!res) {
@@ -81,6 +276,385 @@ export const SwapController = {
81
276
  gasPrice: gasFee,
82
277
  gasPriceInUSD: state.gasPriceInUSD
83
278
  };
279
+ },
280
+ getProviderFeePrice() {
281
+ return SwapCalculationUtil.getProviderFeePrice(state.sourceTokenAmount, state.sourceTokenPriceInUSD);
282
+ },
283
+ setBalances(balances) {
284
+ const {
285
+ networkAddress
286
+ } = this.getParams();
287
+ const caipNetwork = NetworkController.state.caipNetwork;
288
+ if (!caipNetwork) {
289
+ return;
290
+ }
291
+ const networkToken = balances.find(token => token.address === networkAddress);
292
+ balances.forEach(token => {
293
+ state.tokensPriceMap[token.address] = token.price || 0;
294
+ });
295
+ state.myTokensWithBalance = balances.filter(token => token.address?.startsWith(caipNetwork.id));
296
+ state.networkBalanceInUSD = networkToken ? NumberUtil.multiply(networkToken.quantity.numeric, networkToken.price).toString() : '0';
297
+ },
298
+ setToToken(toToken) {
299
+ if (!toToken) {
300
+ state.toToken = toToken;
301
+ state.toTokenAmount = '';
302
+ state.toTokenPriceInUSD = 0;
303
+ return;
304
+ }
305
+ state.toToken = toToken;
306
+ this.setTokenPrice(toToken.address, 'toToken');
307
+ },
308
+ setToTokenAmount(amount) {
309
+ state.toTokenAmount = amount ? NumberUtil.formatNumberToLocalString(amount, TO_AMOUNT_DECIMALS) : '';
310
+ },
311
+ async setTokenPrice(address, target) {
312
+ let price = state.tokensPriceMap[address] || 0;
313
+ if (!price) {
314
+ state.loadingPrices = true;
315
+ price = await this.getAddressPrice(address);
316
+ }
317
+ if (target === 'sourceToken') {
318
+ state.sourceTokenPriceInUSD = price;
319
+ } else if (target === 'toToken') {
320
+ state.toTokenPriceInUSD = price;
321
+ }
322
+ if (state.loadingPrices) {
323
+ state.loadingPrices = false;
324
+ }
325
+ if (this.getParams().availableToSwap) {
326
+ this.swapTokens();
327
+ }
328
+ },
329
+ // -- Swap ---------------------------------------------- //
330
+ async swapTokens() {
331
+ const address = AccountController.state.address;
332
+ const sourceToken = state.sourceToken;
333
+ const toToken = state.toToken;
334
+ const haveSourceTokenAmount = NumberUtil.bigNumber(state.sourceTokenAmount).isGreaterThan(0);
335
+ if (!toToken || !sourceToken || state.loadingPrices || !haveSourceTokenAmount) {
336
+ return;
337
+ }
338
+ state.loadingQuote = true;
339
+ const amountDecimal = NumberUtil.bigNumber(state.sourceTokenAmount).multipliedBy(10 ** sourceToken.decimals).integerValue();
340
+ const quoteResponse = await BlockchainApiController.fetchSwapQuote({
341
+ userAddress: address,
342
+ projectId: OptionsController.state.projectId,
343
+ from: sourceToken.address,
344
+ to: toToken.address,
345
+ gasPrice: state.gasFee,
346
+ amount: amountDecimal.toString()
347
+ });
348
+ state.loadingQuote = false;
349
+ const quoteToAmount = quoteResponse?.quotes?.[0]?.toAmount;
350
+ if (!quoteToAmount) {
351
+ return;
352
+ }
353
+ const toTokenAmount = NumberUtil.bigNumber(quoteToAmount).dividedBy(10 ** toToken.decimals).toString();
354
+ this.setToTokenAmount(toTokenAmount);
355
+ const isInsufficientToken = this.hasInsufficientToken(state.sourceTokenAmount, sourceToken.address);
356
+ if (isInsufficientToken) {
357
+ state.inputError = 'Insufficient balance';
358
+ } else {
359
+ state.inputError = undefined;
360
+ this.setTransactionDetails();
361
+ }
362
+ },
363
+ // -- Create Transactions -------------------------------------- //
364
+ async getTransaction() {
365
+ const {
366
+ fromCaipAddress,
367
+ availableToSwap
368
+ } = this.getParams();
369
+ const sourceToken = state.sourceToken;
370
+ const toToken = state.toToken;
371
+ if (!fromCaipAddress || !availableToSwap || !sourceToken || !toToken || state.loadingQuote) {
372
+ return undefined;
373
+ }
374
+ try {
375
+ state.loadingBuildTransaction = true;
376
+ const hasAllowance = await SwapApiUtil.fetchSwapAllowance({
377
+ userAddress: fromCaipAddress,
378
+ tokenAddress: sourceToken.address,
379
+ sourceTokenAmount: state.sourceTokenAmount,
380
+ sourceTokenDecimals: sourceToken.decimals
381
+ });
382
+ let transaction;
383
+ if (hasAllowance) {
384
+ transaction = await this.createSwapTransaction();
385
+ } else {
386
+ transaction = await this.createAllowanceTransaction();
387
+ }
388
+ state.loadingBuildTransaction = false;
389
+ state.fetchError = false;
390
+ return transaction;
391
+ } catch (error) {
392
+ RouterController.goBack();
393
+ SnackController.showError('Failed to check allowance');
394
+ state.loadingBuildTransaction = false;
395
+ state.approvalTransaction = undefined;
396
+ state.swapTransaction = undefined;
397
+ state.fetchError = true;
398
+ return undefined;
399
+ }
400
+ },
401
+ async createAllowanceTransaction() {
402
+ const {
403
+ fromCaipAddress,
404
+ fromAddress,
405
+ sourceTokenAddress,
406
+ toTokenAddress
407
+ } = this.getParams();
408
+ if (!fromCaipAddress || !toTokenAddress) {
409
+ return undefined;
410
+ }
411
+ if (!sourceTokenAddress) {
412
+ throw new Error('createAllowanceTransaction - No source token address found.');
413
+ }
414
+ try {
415
+ const response = await BlockchainApiController.generateApproveCalldata({
416
+ projectId: OptionsController.state.projectId,
417
+ from: sourceTokenAddress,
418
+ to: toTokenAddress,
419
+ userAddress: fromCaipAddress
420
+ });
421
+ if (!response) {
422
+ throw new Error('createAllowanceTransaction - No response from generateApproveCalldata');
423
+ }
424
+ const gasLimit = await ConnectionController.estimateGas({
425
+ address: fromAddress,
426
+ to: CoreHelperUtil.getPlainAddress(response.tx.to),
427
+ data: response.tx.data
428
+ });
429
+ const transaction = {
430
+ data: response.tx.data,
431
+ to: CoreHelperUtil.getPlainAddress(response.tx.from),
432
+ gas: gasLimit,
433
+ gasPrice: BigInt(response.tx.eip155.gasPrice),
434
+ value: BigInt(response.tx.value),
435
+ toAmount: state.toTokenAmount
436
+ };
437
+ state.swapTransaction = undefined;
438
+ state.approvalTransaction = {
439
+ data: transaction.data,
440
+ to: transaction.to,
441
+ gas: transaction.gas ?? BigInt(0),
442
+ gasPrice: transaction.gasPrice,
443
+ value: transaction.value,
444
+ toAmount: transaction.toAmount
445
+ };
446
+ return {
447
+ data: transaction.data,
448
+ to: transaction.to,
449
+ gas: transaction.gas ?? BigInt(0),
450
+ gasPrice: transaction.gasPrice,
451
+ value: transaction.value,
452
+ toAmount: transaction.toAmount
453
+ };
454
+ } catch (error) {
455
+ RouterController.goBack();
456
+ SnackController.showError('Failed to create approval transaction');
457
+ state.approvalTransaction = undefined;
458
+ state.swapTransaction = undefined;
459
+ state.fetchError = true;
460
+ return undefined;
461
+ }
462
+ },
463
+ async createSwapTransaction() {
464
+ const {
465
+ networkAddress,
466
+ fromCaipAddress,
467
+ sourceTokenAmount
468
+ } = this.getParams();
469
+ const sourceToken = state.sourceToken;
470
+ const toToken = state.toToken;
471
+ if (!fromCaipAddress || !sourceTokenAmount || !sourceToken || !toToken) {
472
+ return undefined;
473
+ }
474
+ const amount = ConnectionController.parseUnits(sourceTokenAmount, sourceToken.decimals)?.toString();
475
+ try {
476
+ const response = await BlockchainApiController.generateSwapCalldata({
477
+ projectId: OptionsController.state.projectId,
478
+ userAddress: fromCaipAddress,
479
+ from: sourceToken.address,
480
+ to: toToken.address,
481
+ amount: amount
482
+ });
483
+ if (!response) {
484
+ throw new Error('createSwapTransaction - No response from generateSwapCalldata');
485
+ }
486
+ const isSourceNetworkToken = sourceToken.address === networkAddress;
487
+ const gas = BigInt(response.tx.eip155.gas);
488
+ const gasPrice = BigInt(response.tx.eip155.gasPrice);
489
+ const transaction = {
490
+ data: response.tx.data,
491
+ to: CoreHelperUtil.getPlainAddress(response.tx.to),
492
+ gas,
493
+ gasPrice,
494
+ value: isSourceNetworkToken ? BigInt(amount ?? '0') : BigInt('0'),
495
+ toAmount: state.toTokenAmount
496
+ };
497
+ state.gasPriceInUSD = SwapCalculationUtil.getGasPriceInUSD(state.networkPrice, gas, gasPrice);
498
+ state.approvalTransaction = undefined;
499
+ state.swapTransaction = transaction;
500
+ return transaction;
501
+ } catch (error) {
502
+ RouterController.goBack();
503
+ SnackController.showError('Failed to create transaction');
504
+ state.approvalTransaction = undefined;
505
+ state.swapTransaction = undefined;
506
+ state.fetchError = true;
507
+ return undefined;
508
+ }
509
+ },
510
+ async sendTransactionForApproval(data) {
511
+ const {
512
+ fromAddress,
513
+ isAuthConnector
514
+ } = this.getParams();
515
+ state.loadingApprovalTransaction = true;
516
+ const approveLimitMessage = `Approve limit increase in your wallet`;
517
+ if (isAuthConnector) {
518
+ RouterController.pushTransactionStack({
519
+ view: null,
520
+ goBack: true,
521
+ onSuccess() {
522
+ SnackController.showLoading(approveLimitMessage);
523
+ }
524
+ });
525
+ } else {
526
+ SnackController.showLoading(approveLimitMessage);
527
+ }
528
+ try {
529
+ await ConnectionController.sendTransaction({
530
+ address: fromAddress,
531
+ to: data.to,
532
+ data: data.data,
533
+ value: BigInt(data.value),
534
+ gasPrice: BigInt(data.gasPrice),
535
+ chainNamespace: 'eip155'
536
+ });
537
+ await this.swapTokens();
538
+ await this.getTransaction();
539
+ state.approvalTransaction = undefined;
540
+ state.loadingApprovalTransaction = false;
541
+ } catch (err) {
542
+ const error = err;
543
+ state.transactionError = error?.shortMessage;
544
+ state.loadingApprovalTransaction = false;
545
+ SnackController.showError(error?.shortMessage ?? 'Transaction error');
546
+ }
547
+ },
548
+ async sendTransactionForSwap(data) {
549
+ if (!data) {
550
+ return undefined;
551
+ }
552
+ const {
553
+ fromAddress,
554
+ toTokenAmount,
555
+ isAuthConnector
556
+ } = this.getParams();
557
+ state.loadingTransaction = true;
558
+ const snackbarPendingMessage = `Swapping ${state.sourceToken?.symbol} to ${NumberUtil.formatNumberToLocalString(toTokenAmount, 3)} ${state.toToken?.symbol}`;
559
+ const snackbarSuccessMessage = `Swapped ${state.sourceToken?.symbol} to ${NumberUtil.formatNumberToLocalString(toTokenAmount, 3)} ${state.toToken?.symbol}`;
560
+ if (isAuthConnector) {
561
+ RouterController.pushTransactionStack({
562
+ view: 'Account',
563
+ goBack: false,
564
+ onSuccess() {
565
+ SnackController.showLoading(snackbarPendingMessage);
566
+ SwapController.resetState();
567
+ }
568
+ });
569
+ } else {
570
+ SnackController.showLoading('Confirm transaction in your wallet');
571
+ }
572
+ try {
573
+ const forceUpdateAddresses = [state.sourceToken?.address, state.toToken?.address].join(',');
574
+ const transactionHash = await ConnectionController.sendTransaction({
575
+ address: fromAddress,
576
+ to: data.to,
577
+ data: data.data,
578
+ gas: data.gas,
579
+ gasPrice: BigInt(data.gasPrice),
580
+ value: data.value,
581
+ chainNamespace: 'eip155'
582
+ });
583
+ state.loadingTransaction = false;
584
+ SnackController.showSuccess(snackbarSuccessMessage);
585
+ EventsController.sendEvent({
586
+ type: 'track',
587
+ event: 'SWAP_SUCCESS',
588
+ properties: {
589
+ network: NetworkController.state.caipNetwork?.id || '',
590
+ swapFromToken: this.state.sourceToken?.symbol || '',
591
+ swapToToken: this.state.toToken?.symbol || '',
592
+ swapFromAmount: this.state.sourceTokenAmount || '',
593
+ swapToAmount: this.state.toTokenAmount || '',
594
+ isSmartAccount: AccountController.state.preferredAccountType === 'smartAccount'
595
+ }
596
+ });
597
+ SwapController.resetState();
598
+ if (!isAuthConnector) {
599
+ RouterController.replace('AccountDefault');
600
+ }
601
+ SwapController.getMyTokensWithBalance(forceUpdateAddresses);
602
+ AccountController.fetchTokenBalance();
603
+ setTimeout(() => {
604
+ TransactionsController.fetchTransactions(AccountController.state.address, true);
605
+ }, 5000);
606
+ return transactionHash;
607
+ } catch (err) {
608
+ const error = err;
609
+ state.transactionError = error?.shortMessage;
610
+ state.loadingTransaction = false;
611
+ SnackController.showError(error?.shortMessage ?? 'Transaction error');
612
+ EventsController.sendEvent({
613
+ type: 'track',
614
+ event: 'SWAP_ERROR',
615
+ properties: {
616
+ message: error?.shortMessage ?? error?.message ?? 'Unknown',
617
+ network: NetworkController.state.caipNetwork?.id || '',
618
+ swapFromToken: this.state.sourceToken?.symbol || '',
619
+ swapToToken: this.state.toToken?.symbol || '',
620
+ swapFromAmount: this.state.sourceTokenAmount || '',
621
+ swapToAmount: this.state.toTokenAmount || '',
622
+ isSmartAccount: AccountController.state.preferredAccountType === 'smartAccount'
623
+ }
624
+ });
625
+ return undefined;
626
+ }
627
+ },
628
+ // -- Checks -------------------------------------------- //
629
+ hasInsufficientToken(sourceTokenAmount, sourceTokenAddress) {
630
+ const isInsufficientSourceTokenForSwap = SwapCalculationUtil.isInsufficientSourceTokenForSwap(sourceTokenAmount, sourceTokenAddress, state.myTokensWithBalance);
631
+ let insufficientNetworkTokenForGas = true;
632
+ if (AccountController.state.preferredAccountType === 'smartAccount') {
633
+ // Smart Accounts may pay gas in any ERC20 token
634
+ insufficientNetworkTokenForGas = false;
635
+ } else {
636
+ insufficientNetworkTokenForGas = SwapCalculationUtil.isInsufficientNetworkTokenForGas(state.networkBalanceInUSD, state.gasPriceInUSD);
637
+ }
638
+ return insufficientNetworkTokenForGas || isInsufficientSourceTokenForSwap;
639
+ },
640
+ // -- Calculations -------------------------------------- //
641
+ setTransactionDetails() {
642
+ const {
643
+ toTokenAddress,
644
+ toTokenDecimals
645
+ } = this.getParams();
646
+ if (!toTokenAddress || !toTokenDecimals) {
647
+ return;
648
+ }
649
+ state.gasPriceInUSD = SwapCalculationUtil.getGasPriceInUSD(state.networkPrice, BigInt(state.gasFee), BigInt(INITIAL_GAS_LIMIT));
650
+ state.priceImpact = SwapCalculationUtil.getPriceImpact({
651
+ sourceTokenAmount: state.sourceTokenAmount,
652
+ sourceTokenPriceInUSD: state.sourceTokenPriceInUSD,
653
+ toTokenPriceInUSD: state.toTokenPriceInUSD,
654
+ toTokenAmount: state.toTokenAmount
655
+ });
656
+ state.maxSlippage = SwapCalculationUtil.getMaxSlippage(state.slippage, state.toTokenAmount);
657
+ state.providerFee = SwapCalculationUtil.getProviderFee(state.sourceTokenAmount);
84
658
  }
85
659
  };
86
660
  //# sourceMappingURL=SwapController.js.map