@subwallet/extension-base 1.3.34-0 → 1.3.35-0

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 (34) hide show
  1. package/background/KoniTypes.d.ts +2 -0
  2. package/cjs/core/logic-validation/request.js +1 -1
  3. package/cjs/koni/background/handlers/Extension.js +11 -4
  4. package/cjs/koni/background/utils.js +64 -29
  5. package/cjs/packageInfo.js +1 -1
  6. package/cjs/services/balance-service/helpers/process.js +1 -5
  7. package/cjs/services/balance-service/index.js +20 -1
  8. package/cjs/services/balance-service/transfer/xcm/acrossBridge/index.js +91 -175
  9. package/cjs/services/balance-service/transfer/xcm/index.js +7 -6
  10. package/cjs/services/price-service/coingecko.js +22 -15
  11. package/cjs/services/price-service/index.js +12 -0
  12. package/cjs/services/swap-service/handler/uniswap-handler.js +14 -1
  13. package/cjs/services/swap-service/index.js +6 -0
  14. package/cjs/services/transaction-service/index.js +49 -28
  15. package/core/logic-validation/request.js +1 -1
  16. package/koni/background/handlers/Extension.d.ts +1 -0
  17. package/koni/background/handlers/Extension.js +11 -4
  18. package/koni/background/utils.d.ts +3 -5
  19. package/koni/background/utils.js +64 -29
  20. package/package.json +6 -6
  21. package/packageInfo.js +1 -1
  22. package/services/balance-service/helpers/process.d.ts +2 -2
  23. package/services/balance-service/helpers/process.js +1 -5
  24. package/services/balance-service/index.js +21 -2
  25. package/services/balance-service/transfer/xcm/acrossBridge/index.d.ts +9 -8
  26. package/services/balance-service/transfer/xcm/acrossBridge/index.js +91 -174
  27. package/services/balance-service/transfer/xcm/index.js +7 -6
  28. package/services/price-service/coingecko.d.ts +1 -1
  29. package/services/price-service/coingecko.js +22 -16
  30. package/services/price-service/index.d.ts +1 -0
  31. package/services/price-service/index.js +12 -0
  32. package/services/swap-service/handler/uniswap-handler.js +15 -2
  33. package/services/swap-service/index.js +6 -0
  34. package/services/transaction-service/index.js +45 -24
@@ -15,176 +15,6 @@ export function _isAcrossChainBridge(srcChain, destChain) {
15
15
  export function _isAcrossTestnetBridge(srcChain) {
16
16
  return srcChain === 'base_sepolia' || srcChain === 'arbitrum_sepolia' || srcChain === COMMON_CHAIN_SLUGS.ETHEREUM_SEPOLIA;
17
17
  }
18
- export const SpokePoolMapping = {
19
- 1: {
20
- SpokePool: {
21
- address: '0x5c7BCd6E7De5423a257D81B442095A1a6ced35C5',
22
- blockNumber: 17117454
23
- }
24
- },
25
- 10: {
26
- SpokePool: {
27
- address: '0x6f26Bf09B1C792e3228e5467807a900A503c0281',
28
- blockNumber: 93903076
29
- }
30
- },
31
- 11155111: {
32
- SpokePool: {
33
- address: '0x5ef6C01E11889d86803e0B23e3cB3F9E9d97B662',
34
- blockNumber: 5288470
35
- }
36
- },
37
- 11155420: {
38
- SpokePool: {
39
- address: '0x4e8E101924eDE233C13e2D8622DC8aED2872d505',
40
- blockNumber: 7762656
41
- }
42
- },
43
- 1135: {
44
- SpokePool: {
45
- address: '0x9552a0a6624A23B848060AE5901659CDDa1f83f8',
46
- blockNumber: 2602337
47
- }
48
- },
49
- 130: {
50
- SpokePool: {
51
- address: '0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64',
52
- blockNumber: 7915488
53
- }
54
- },
55
- 137: {
56
- SpokePool: {
57
- address: '0x9295ee1d8C5b022Be115A2AD3c30C72E34e7F096',
58
- blockNumber: 41908657
59
- }
60
- },
61
- 168587773: {
62
- SpokePool: {
63
- address: '0x5545092553Cf5Bf786e87a87192E902D50D8f022',
64
- blockNumber: 7634204
65
- }
66
- },
67
- 1868: {
68
- SpokePool: {
69
- address: '0x3baD7AD0728f9917d1Bf08af5782dCbD516cDd96',
70
- blockNumber: 1709997
71
- }
72
- },
73
- 288: {
74
- SpokePool: {
75
- address: '0xBbc6009fEfFc27ce705322832Cb2068F8C1e0A58',
76
- blockNumber: 619993
77
- }
78
- },
79
- 324: {
80
- SpokePool: {
81
- address: '0xE0B015E54d54fc84a6cB9B666099c46adE9335FF',
82
- blockNumber: 10352565
83
- }
84
- },
85
- 34443: {
86
- SpokePool: {
87
- address: '0x3baD7AD0728f9917d1Bf08af5782dCbD516cDd96',
88
- blockNumber: 8043187
89
- }
90
- },
91
- 37111: {
92
- SpokePool: {
93
- address: '0x6A0a7f39530923911832Dd60667CE5da5449967B',
94
- blockNumber: 156275
95
- }
96
- },
97
- 41455: {
98
- SpokePool: {
99
- address: '0x13fDac9F9b4777705db45291bbFF3c972c6d1d97',
100
- blockNumber: 4240318
101
- }
102
- },
103
- 4202: {
104
- SpokePool: {
105
- address: '0xeF684C38F94F48775959ECf2012D7E864ffb9dd4',
106
- blockNumber: 7267988
107
- }
108
- },
109
- 42161: {
110
- SpokePool: {
111
- address: '0xe35e9842fceaCA96570B734083f4a58e8F7C5f2A',
112
- blockNumber: 83868041
113
- }
114
- },
115
- 421614: {
116
- SpokePool: {
117
- address: '0x7E63A5f1a8F0B4d0934B2f2327DAED3F6bb2ee75',
118
- blockNumber: 12411026
119
- }
120
- },
121
- 480: {
122
- SpokePool: {
123
- address: '0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64',
124
- blockNumber: 4524742
125
- }
126
- },
127
- 534352: {
128
- SpokePool: {
129
- address: '0x3baD7AD0728f9917d1Bf08af5782dCbD516cDd96',
130
- blockNumber: 7489705
131
- }
132
- },
133
- 57073: {
134
- SpokePool: {
135
- address: '0xeF684C38F94F48775959ECf2012D7E864ffb9dd4',
136
- blockNumber: 1139240
137
- }
138
- },
139
- 59144: {
140
- SpokePool: {
141
- address: '0x7E63A5f1a8F0B4d0934B2f2327DAED3F6bb2ee75',
142
- blockNumber: 2721169
143
- }
144
- },
145
- 690: {
146
- SpokePool: {
147
- address: '0x13fDac9F9b4777705db45291bbFF3c972c6d1d97',
148
- blockNumber: 5512122
149
- }
150
- },
151
- 7777777: {
152
- SpokePool: {
153
- address: '0x13fDac9F9b4777705db45291bbFF3c972c6d1d97',
154
- blockNumber: 18382867
155
- }
156
- },
157
- 80002: {
158
- SpokePool: {
159
- address: '0xd08baaE74D6d2eAb1F3320B2E1a53eeb391ce8e5',
160
- blockNumber: 7529960
161
- }
162
- },
163
- 81457: {
164
- SpokePool: {
165
- address: '0x2D509190Ed0172ba588407D4c2df918F955Cc6E1',
166
- blockNumber: 5574280
167
- }
168
- },
169
- 8453: {
170
- SpokePool: {
171
- address: '0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64',
172
- blockNumber: 2164878
173
- }
174
- },
175
- 84532: {
176
- SpokePool: {
177
- address: '0x82B564983aE7274c86695917BBf8C99ECb6F0F8F',
178
- blockNumber: 6082004
179
- }
180
- },
181
- 919: {
182
- SpokePool: {
183
- address: '0xbd886FC0725Cc459b55BbFEb3E4278610331f83b',
184
- blockNumber: 13999465
185
- }
186
- }
187
- };
188
18
  export const AcrossErrorMsg = {
189
19
  AMOUNT_TOO_LOW: 'amount too low',
190
20
  AMOUNT_TOO_HIGH: 'amount too high'
@@ -209,11 +39,98 @@ export const getAcrossQuote = async ({
209
39
  try {
210
40
  var _subwalletApiSdk$xcmA;
211
41
  const data = await ((_subwalletApiSdk$xcmA = subwalletApiSdk.xcmApi) === null || _subwalletApiSdk$xcmA === void 0 ? void 0 : _subwalletApiSdk$xcmA.fetchXcmData(sender, originTokenInfo.slug, destinationTokenInfo.slug, recipient, sendingValue));
212
- if (!data || !data.metadata) {
213
- throw new Error('Failed to get AcrossBridge quote');
42
+ if (!data) {
43
+ throw new Error('Failed to fetch Across Bridge Data. Please try again later');
214
44
  }
215
- return data.metadata;
45
+ return data;
216
46
  } catch (error) {
217
47
  return Promise.reject(error);
218
48
  }
219
- };
49
+ };
50
+
51
+ // export const SpokePoolMapping: Record<number, { SpokePool: { address: string; blockNumber: number } }> = {
52
+ // 1: {
53
+ // SpokePool: { address: '0x5c7BCd6E7De5423a257D81B442095A1a6ced35C5', blockNumber: 17117454 }
54
+ // },
55
+ // 10: {
56
+ // SpokePool: { address: '0x6f26Bf09B1C792e3228e5467807a900A503c0281', blockNumber: 93903076 }
57
+ // },
58
+ // 11155111: {
59
+ // SpokePool: { address: '0x5ef6C01E11889d86803e0B23e3cB3F9E9d97B662', blockNumber: 5288470 }
60
+ // },
61
+ // 11155420: {
62
+ // SpokePool: { address: '0x4e8E101924eDE233C13e2D8622DC8aED2872d505', blockNumber: 7762656 }
63
+ // },
64
+ // 1135: {
65
+ // SpokePool: { address: '0x9552a0a6624A23B848060AE5901659CDDa1f83f8', blockNumber: 2602337 }
66
+ // },
67
+ // 130: {
68
+ // SpokePool: { address: '0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64', blockNumber: 7915488 }
69
+ // },
70
+ // 137: {
71
+ // SpokePool: { address: '0x9295ee1d8C5b022Be115A2AD3c30C72E34e7F096', blockNumber: 41908657 }
72
+ // },
73
+ // 168587773: {
74
+ // SpokePool: { address: '0x5545092553Cf5Bf786e87a87192E902D50D8f022', blockNumber: 7634204 }
75
+ // },
76
+ // 1868: {
77
+ // SpokePool: { address: '0x3baD7AD0728f9917d1Bf08af5782dCbD516cDd96', blockNumber: 1709997 }
78
+ // },
79
+ // 288: {
80
+ // SpokePool: { address: '0xBbc6009fEfFc27ce705322832Cb2068F8C1e0A58', blockNumber: 619993 }
81
+ // },
82
+ // 324: {
83
+ // SpokePool: { address: '0xE0B015E54d54fc84a6cB9B666099c46adE9335FF', blockNumber: 10352565 }
84
+ // },
85
+ // 34443: {
86
+ // SpokePool: { address: '0x3baD7AD0728f9917d1Bf08af5782dCbD516cDd96', blockNumber: 8043187 }
87
+ // },
88
+ // 37111: {
89
+ // SpokePool: { address: '0x6A0a7f39530923911832Dd60667CE5da5449967B', blockNumber: 156275 }
90
+ // },
91
+ // 41455: {
92
+ // SpokePool: { address: '0x13fDac9F9b4777705db45291bbFF3c972c6d1d97', blockNumber: 4240318 }
93
+ // },
94
+ // 4202: {
95
+ // SpokePool: { address: '0xeF684C38F94F48775959ECf2012D7E864ffb9dd4', blockNumber: 7267988 }
96
+ // },
97
+ // 42161: {
98
+ // SpokePool: { address: '0xe35e9842fceaCA96570B734083f4a58e8F7C5f2A', blockNumber: 83868041 }
99
+ // },
100
+ // 421614: {
101
+ // SpokePool: { address: '0x7E63A5f1a8F0B4d0934B2f2327DAED3F6bb2ee75', blockNumber: 12411026 }
102
+ // },
103
+ // 480: {
104
+ // SpokePool: { address: '0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64', blockNumber: 4524742 }
105
+ // },
106
+ // 534352: {
107
+ // SpokePool: { address: '0x3baD7AD0728f9917d1Bf08af5782dCbD516cDd96', blockNumber: 7489705 }
108
+ // },
109
+ // 57073: {
110
+ // SpokePool: { address: '0xeF684C38F94F48775959ECf2012D7E864ffb9dd4', blockNumber: 1139240 }
111
+ // },
112
+ // 59144: {
113
+ // SpokePool: { address: '0x7E63A5f1a8F0B4d0934B2f2327DAED3F6bb2ee75', blockNumber: 2721169 }
114
+ // },
115
+ // 690: {
116
+ // SpokePool: { address: '0x13fDac9F9b4777705db45291bbFF3c972c6d1d97', blockNumber: 5512122 }
117
+ // },
118
+ // 7777777: {
119
+ // SpokePool: { address: '0x13fDac9F9b4777705db45291bbFF3c972c6d1d97', blockNumber: 18382867 }
120
+ // },
121
+ // 80002: {
122
+ // SpokePool: { address: '0xd08baaE74D6d2eAb1F3320B2E1a53eeb391ce8e5', blockNumber: 7529960 }
123
+ // },
124
+ // 81457: {
125
+ // SpokePool: { address: '0x2D509190Ed0172ba588407D4c2df918F955Cc6E1', blockNumber: 5574280 }
126
+ // },
127
+ // 8453: {
128
+ // SpokePool: { address: '0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64', blockNumber: 2164878 }
129
+ // },
130
+ // 84532: {
131
+ // SpokePool: { address: '0x82B564983aE7274c86695917BBf8C99ECb6F0F8F', blockNumber: 6082004 }
132
+ // },
133
+ // 919: {
134
+ // SpokePool: { address: '0xbd886FC0725Cc459b55BbFEb3E4278610331f83b', blockNumber: 13999465 }
135
+ // }
136
+ // };
@@ -182,13 +182,14 @@ export const createAcrossBridgeExtrinsic = async ({
182
182
  const data = await ((_subwalletApiSdk$xcmA = subwalletApiSdk.xcmApi) === null || _subwalletApiSdk$xcmA === void 0 ? void 0 : _subwalletApiSdk$xcmA.fetchXcmData(sender, originTokenInfo.slug, destinationTokenInfo.slug, recipient, sendingValue));
183
183
  const _feeCustom = feeCustom;
184
184
  const feeCombine = combineEthFee(feeInfo, feeOption, _feeCustom);
185
-
186
- // todo: validate data before sending
185
+ if (!data) {
186
+ throw new Error('Failed to fetch Across Bridge Data. Please try again later');
187
+ }
187
188
  const transactionConfig = {
188
- from: data === null || data === void 0 ? void 0 : data.sender,
189
- to: data === null || data === void 0 ? void 0 : data.to,
190
- value: data === null || data === void 0 ? void 0 : data.value,
191
- data: data === null || data === void 0 ? void 0 : data.transferEncodedCall,
189
+ from: data.sender,
190
+ to: data.to,
191
+ value: data.value,
192
+ data: data.transferEncodedCall,
192
193
  ...feeCombine
193
194
  };
194
195
  const gasLimit = await evmApi.api.eth.estimateGas(transactionConfig).catch(() => 200000);
@@ -1,4 +1,4 @@
1
1
  import { CurrencyType, ExchangeRateJSON, HistoryTokenPriceJSON, PriceChartTimeframe, PriceJson } from '@subwallet/extension-base/background/KoniTypes';
2
2
  export declare const getExchangeRateMap: () => Promise<Record<CurrencyType, ExchangeRateJSON>>;
3
- export declare const getPriceMap: (priceIds: Set<string>, currency?: CurrencyType) => Promise<Omit<PriceJson, 'exchangeRateMap'>>;
3
+ export declare const getPriceMap: (priceIds: Set<string>, currency?: CurrencyType, skipDerivativePrice?: boolean) => Promise<Omit<PriceJson, 'exchangeRateMap'>>;
4
4
  export declare const getHistoryPrice: (priceId: string, type: PriceChartTimeframe) => Promise<HistoryTokenPriceJSON>;
@@ -51,29 +51,33 @@ const fetchDerivativeTokenSlugs = async () => {
51
51
  return new Set(DERIVATIVE_TOKEN_SLUG_LIST);
52
52
  }
53
53
  };
54
- export const getPriceMap = async (priceIds, currency = 'USD') => {
54
+ export const getPriceMap = async (priceIds, currency = 'USD', skipDerivativePrice) => {
55
55
  const idStr = Array.from(priceIds).join(',');
56
56
  let response;
57
57
  try {
58
58
  var _response3, _response5;
59
59
  const derivativePriceMap = {};
60
+ const lastUpdatedMap = {};
60
61
  let derivativeApiError = false;
61
- try {
62
- const responseDerivativeTokens = await fetch(`${apiCacheDomain}/api/price/derivative-get`);
63
- const generateDerivativePriceRaw = (await (responseDerivativeTokens === null || responseDerivativeTokens === void 0 ? void 0 : responseDerivativeTokens.json())) || [];
64
- if (Array.isArray(generateDerivativePriceRaw)) {
65
- generateDerivativePriceRaw.forEach(token => {
66
- if (token.id) {
67
- derivativePriceMap[token.id] = token.derived_price;
68
- }
69
- });
70
- } else {
71
- console.warn('Invalid data from derivative API:', generateDerivativePriceRaw);
62
+ if (!skipDerivativePrice) {
63
+ try {
64
+ const responseDerivativeTokens = await fetch(`${apiCacheDomain}/api/price/derivative-get`);
65
+ const generateDerivativePriceRaw = (await (responseDerivativeTokens === null || responseDerivativeTokens === void 0 ? void 0 : responseDerivativeTokens.json())) || [];
66
+ if (Array.isArray(generateDerivativePriceRaw)) {
67
+ generateDerivativePriceRaw.forEach(token => {
68
+ if (token.id) {
69
+ derivativePriceMap[token.id] = token.derived_price;
70
+ lastUpdatedMap[token.id] = new Date(token.cached_at || Date.now());
71
+ }
72
+ });
73
+ } else {
74
+ console.warn('Invalid data from derivative API:', generateDerivativePriceRaw);
75
+ derivativeApiError = true;
76
+ }
77
+ } catch (error) {
78
+ console.error('Error fetching derivative API:', error);
72
79
  derivativeApiError = true;
73
80
  }
74
- } catch (error) {
75
- console.error('Error fetching derivative API:', error);
76
- derivativeApiError = true;
77
81
  }
78
82
  if (!useBackupApi) {
79
83
  try {
@@ -102,10 +106,11 @@ export const getPriceMap = async (priceIds, currency = 'USD') => {
102
106
  const currencyData = staticData[StaticKey.CURRENCY_SYMBOL][currency || DEFAULT_CURRENCY];
103
107
  const priceMap = {};
104
108
  const price24hMap = {};
105
- const lastUpdatedMap = {};
109
+ const priceCoinGeckoSupported = [];
106
110
  responseDataPrice.forEach(val => {
107
111
  const currentPrice = val.current_price || 0;
108
112
  const price24h = currentPrice - (val.price_change_24h || 0);
113
+ priceCoinGeckoSupported.push(val.id);
109
114
  priceMap[val.id] = currentPrice;
110
115
  price24hMap[val.id] = price24h;
111
116
  lastUpdatedMap[val.id] = new Date(val.last_updated || val.last_updated_at || Date.now());
@@ -127,6 +132,7 @@ export const getPriceMap = async (priceIds, currency = 'USD') => {
127
132
  currencyData,
128
133
  priceMap,
129
134
  price24hMap,
135
+ priceCoinGeckoSupported,
130
136
  lastUpdatedMap
131
137
  };
132
138
  } catch (e) {
@@ -39,6 +39,7 @@ export declare class PriceService implements StoppableServiceInterface, PersistD
39
39
  };
40
40
  };
41
41
  init(): Promise<void>;
42
+ checkCoinGeckoPriceSupport(priceId: string): boolean;
42
43
  loadData(): Promise<void>;
43
44
  persistData(): Promise<void>;
44
45
  startPromiseHandler: {
@@ -20,6 +20,7 @@ const DEFAULT_PRICE_SUBJECT = {
20
20
  isPrefix: true
21
21
  },
22
22
  priceMap: {},
23
+ priceCoinGeckoSupported: [],
23
24
  price24hMap: {},
24
25
  exchangeRateMap: {},
25
26
  lastUpdatedMap: {}
@@ -96,6 +97,7 @@ export class PriceService {
96
97
  let {
97
98
  lastUpdatedMap,
98
99
  price24hMap,
100
+ priceCoinGeckoSupported,
99
101
  priceMap
100
102
  } = this.rawPriceSubject.value;
101
103
  let exchangeRateData = this.rawExchangeRateMap.value;
@@ -125,6 +127,7 @@ export class PriceService {
125
127
  },
126
128
  currency: currencyKey,
127
129
  exchangeRateMap: exchangeRateData,
130
+ priceCoinGeckoSupported,
128
131
  currencyData: staticData[StaticKey.CURRENCY_SYMBOL][currencyKey || DEFAULT_CURRENCY],
129
132
  lastUpdatedMap: {
130
133
  ...lastUpdatedMap
@@ -260,6 +263,15 @@ export class PriceService {
260
263
  this.status = ServiceStatus.INITIALIZED;
261
264
  this.eventService.on('asset.updateState', eventHandler);
262
265
  }
266
+ checkCoinGeckoPriceSupport(priceId) {
267
+ const {
268
+ priceCoinGeckoSupported
269
+ } = this.priceSubject.value;
270
+ if (!priceCoinGeckoSupported) {
271
+ return false;
272
+ }
273
+ return priceCoinGeckoSupported.includes(priceId);
274
+ }
263
275
  async loadData() {
264
276
  const data = await this.dbService.getPriceStore(this.priceSubject.value.currency);
265
277
  this.priceSubject.next(data || DEFAULT_PRICE_SUBJECT);
@@ -6,7 +6,7 @@ import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/K
6
6
  import { validateTypedSignMessageDataV3V4 } from '@subwallet/extension-base/core/logic-validation';
7
7
  import { estimateTxFee, getERC20Allowance, getERC20SpendingApprovalTx } from '@subwallet/extension-base/koni/api/contract-handler/evm/web3';
8
8
  import { createAcrossBridgeExtrinsic } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
9
- import { SpokePoolMapping } from '@subwallet/extension-base/services/balance-service/transfer/xcm/acrossBridge';
9
+ import { getAcrossQuote } from '@subwallet/extension-base/services/balance-service/transfer/xcm/acrossBridge';
10
10
  import { BasicTxErrorType, CommonStepType, DynamicSwapType, FeeOptionKey, SwapFeeType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
11
11
  import { _reformatAddressWithChain } from '@subwallet/extension-base/utils';
12
12
  import { getId } from '@subwallet/extension-base/utils/getId';
@@ -133,6 +133,7 @@ export class UniswapHandler {
133
133
  if (!quote) {
134
134
  return Promise.resolve(undefined);
135
135
  }
136
+ console.log('params', params);
136
137
  const sendingAmount = quote.toAmount;
137
138
  const senderAddress = params.request.address;
138
139
  const fromTokenInfo = this.chainService.getAssetBySlug(quote.pair.to);
@@ -140,13 +141,25 @@ export class UniswapHandler {
140
141
  const fromChainId = _getEvmChainId(fromChainInfo);
141
142
  const evmApi = this.chainService.getEvmApi(fromChainInfo.slug);
142
143
  const tokenContract = _getContractAddressOfToken(fromTokenInfo);
144
+ const toTokenInfo = this.chainService.getAssetBySlug(params.request.pair.to);
145
+ const toChainInfo = this.chainService.getChainInfoByKey(_getAssetOriginChain(toTokenInfo));
143
146
  if (_isNativeToken(fromTokenInfo)) {
144
147
  return Promise.resolve(undefined);
145
148
  }
146
149
  if (!fromChainId) {
147
150
  throw Error('Error getting Evm chain Id');
148
151
  }
149
- const spokePoolAddress = SpokePoolMapping[fromChainId].SpokePool.address;
152
+ const inputData = {
153
+ destinationTokenInfo: toTokenInfo,
154
+ originTokenInfo: fromTokenInfo,
155
+ sendingValue: sendingAmount,
156
+ sender: senderAddress,
157
+ recipient: senderAddress,
158
+ destinationChain: toChainInfo,
159
+ originChain: fromChainInfo
160
+ };
161
+ const acrossQuote = await getAcrossQuote(inputData);
162
+ const spokePoolAddress = acrossQuote.to;
150
163
  const allowance = await getERC20Allowance(spokePoolAddress, senderAddress, tokenContract, evmApi);
151
164
  if (allowance && BigNumber(allowance).gt(sendingAmount)) {
152
165
  return Promise.resolve(undefined);
@@ -123,6 +123,12 @@ export class SwapService {
123
123
  } catch (e) {
124
124
  throw new Error(e.message);
125
125
  }
126
+ if (swapQuoteResponse.error) {
127
+ return {
128
+ process: optimalProcess,
129
+ quote: swapQuoteResponse
130
+ };
131
+ }
126
132
  console.log('optimalProcess', optimalProcess);
127
133
  console.groupEnd();
128
134
  if (JSON.stringify(processStepsToPathActions(optimalProcess.steps)) !== JSON.stringify(optimalProcess.path.map(e => e.action))) {
@@ -1416,40 +1416,61 @@ export default class TransactionService {
1416
1416
  this.handleTransactionTimeout(emitter, eventData);
1417
1417
  emitter.emit('send', eventData); // This event is needed after sending transaction with queue
1418
1418
 
1419
+ let isBroadcast = false;
1420
+ let isInBlock = false;
1421
+ let isFinish = false;
1419
1422
  rs.send(txState => {
1420
1423
  // handle events, logs, history
1421
1424
  if (!txState || !txState.status) {
1422
1425
  return;
1423
1426
  }
1424
- if (txState.status.isInBlock) {
1425
- eventData.eventLogs = txState.events;
1426
- if (!eventData.extrinsicHash || eventData.extrinsicHash === '' || !isHex(eventData.extrinsicHash)) {
1427
+
1428
+ // Broadcast transaction
1429
+ if (!isBroadcast) {
1430
+ if (txState.status.isBroadcast || txState.status.isInBlock || txState.status.isFinalized) {
1427
1431
  eventData.extrinsicHash = txState.txHash.toHex();
1432
+ isBroadcast = true;
1433
+ if (!isFinish) {
1434
+ emitter.emit('extrinsicHash', eventData);
1435
+ }
1436
+ }
1437
+ }
1438
+
1439
+ // Transaction in block
1440
+ if (!isInBlock) {
1441
+ if (txState.status.isInBlock || txState.status.isFinalized) {
1428
1442
  eventData.blockHash = txState.status.asInBlock.toHex();
1429
- emitter.emit('extrinsicHash', eventData);
1443
+ eventData.eventLogs = txState.events;
1444
+ isInBlock = true;
1430
1445
  }
1431
1446
  }
1432
- if (txState.status.isFinalized) {
1433
- eventData.extrinsicHash = txState.txHash.toHex();
1434
- eventData.eventLogs = txState.events;
1435
- // TODO: push block hash and block number into eventData
1436
- txState.events.filter(({
1437
- event: {
1438
- section
1439
- }
1440
- }) => section === 'system').forEach(({
1441
- event: {
1442
- data: [error],
1443
- method
1444
- }
1445
- }) => {
1446
- if (method === 'ExtrinsicFailed') {
1447
- eventData.errors.push(new TransactionError(BasicTxErrorType.SEND_TRANSACTION_FAILED, error.toString()));
1448
- emitter.emit('error', eventData);
1449
- } else if (method === 'ExtrinsicSuccess') {
1450
- emitter.emit('success', eventData);
1447
+
1448
+ // Transaction finished
1449
+ if (!isFinish) {
1450
+ if (txState.status.isInBlock || txState.status.isFinalized) {
1451
+ if (!eventData.extrinsicHash) {
1452
+ eventData.extrinsicHash = txState.txHash.toHex();
1451
1453
  }
1452
- });
1454
+ txState.events.filter(({
1455
+ event: {
1456
+ section
1457
+ }
1458
+ }) => section === 'system').forEach(({
1459
+ event: {
1460
+ data: [error],
1461
+ method
1462
+ }
1463
+ }) => {
1464
+ if (method === 'ExtrinsicFailed') {
1465
+ eventData.errors.push(new TransactionError(BasicTxErrorType.SEND_TRANSACTION_FAILED, error.toString()));
1466
+ emitter.emit('error', eventData);
1467
+ isFinish = true;
1468
+ } else if (method === 'ExtrinsicSuccess') {
1469
+ emitter.emit('success', eventData);
1470
+ isFinish = true;
1471
+ }
1472
+ });
1473
+ }
1453
1474
  }
1454
1475
  }).catch(e => {
1455
1476
  eventData.errors.push(new TransactionError(BasicTxErrorType.SEND_TRANSACTION_FAILED, e.message));