@subwallet/extension-base 1.0.7-2 → 1.0.9-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 (57) hide show
  1. package/background/KoniTypes.d.ts +3 -1
  2. package/background/KoniTypes.js +1 -0
  3. package/background/errors/TransactionError.js +5 -1
  4. package/cjs/background/KoniTypes.js +1 -0
  5. package/cjs/background/errors/TransactionError.js +4 -0
  6. package/cjs/constants/index.js +6 -3
  7. package/cjs/koni/api/dotsama/balance.js +5 -2
  8. package/cjs/koni/api/dotsama/crowdloan.js +1 -1
  9. package/cjs/koni/api/dotsama/transfer.js +19 -5
  10. package/cjs/koni/api/tokens/wasm/index.js +7 -0
  11. package/cjs/koni/api/xcm/polkadotXcm.js +18 -37
  12. package/cjs/koni/api/xcm/utils.js +78 -11
  13. package/cjs/koni/api/xcm/xTokens.js +4 -33
  14. package/cjs/koni/api/xcm/xcmPallet.js +4 -36
  15. package/cjs/koni/background/handlers/Extension.js +83 -25
  16. package/cjs/koni/background/handlers/State.js +1 -1
  17. package/cjs/packageInfo.js +1 -1
  18. package/cjs/services/chain-service/constants.js +9 -7
  19. package/cjs/services/chain-service/index.js +19 -15
  20. package/cjs/services/chain-service/utils.js +1 -5
  21. package/cjs/services/history-service/constants/index.js +13 -0
  22. package/cjs/services/history-service/subsquid-multi-chain-history.js +38 -3
  23. package/cjs/services/transaction-service/helpers/index.js +45 -2
  24. package/cjs/services/transaction-service/index.js +58 -24
  25. package/cjs/utils/eth/parseTransaction/index.js +69 -59
  26. package/cjs/utils/number.js +112 -0
  27. package/constants/index.d.ts +1 -0
  28. package/constants/index.js +1 -0
  29. package/koni/api/dotsama/balance.js +4 -2
  30. package/koni/api/dotsama/crowdloan.js +2 -2
  31. package/koni/api/dotsama/transfer.js +19 -5
  32. package/koni/api/tokens/wasm/index.js +7 -0
  33. package/koni/api/xcm/polkadotXcm.js +20 -39
  34. package/koni/api/xcm/utils.d.ts +36 -3
  35. package/koni/api/xcm/utils.js +72 -11
  36. package/koni/api/xcm/xTokens.js +6 -35
  37. package/koni/api/xcm/xcmPallet.js +5 -35
  38. package/koni/background/handlers/Extension.js +82 -24
  39. package/koni/background/handlers/State.js +2 -2
  40. package/package.json +18 -8
  41. package/packageInfo.js +1 -1
  42. package/services/chain-service/constants.d.ts +2 -0
  43. package/services/chain-service/constants.js +9 -7
  44. package/services/chain-service/index.js +13 -8
  45. package/services/chain-service/utils.d.ts +0 -1
  46. package/services/chain-service/utils.js +1 -4
  47. package/services/history-service/constants/index.d.ts +2 -0
  48. package/services/history-service/constants/index.js +5 -0
  49. package/services/history-service/subsquid-multi-chain-history.d.ts +1 -1
  50. package/services/history-service/subsquid-multi-chain-history.js +36 -3
  51. package/services/transaction-service/helpers/index.d.ts +2 -0
  52. package/services/transaction-service/helpers/index.js +42 -0
  53. package/services/transaction-service/index.js +54 -20
  54. package/services/transaction-service/types.d.ts +2 -2
  55. package/utils/eth/parseTransaction/index.js +69 -59
  56. package/utils/number.d.ts +9 -0
  57. package/utils/number.js +100 -0
@@ -22,11 +22,11 @@ export const _PURE_EVM_CHAINS = ['binance', 'binance_test', 'ethereum', 'ethereu
22
22
  // Get balance----------------------------------------------------------------------------------------------------------
23
23
 
24
24
  export const _BALANCE_CHAIN_GROUP = {
25
- kintsugi: ['kintsugi', 'interlay', 'kintsugi_test'],
25
+ kintsugi: ['kintsugi', 'interlay', 'kintsugi_test', 'mangatax_para'],
26
26
  genshiro: ['genshiro_testnet', 'genshiro'],
27
27
  equilibrium_parachain: ['equilibrium_parachain'],
28
- bifrost: ['bifrost', 'acala', 'karura', 'acala_testnet', 'pioneer', 'bitcountry'],
29
- statemine: ['statemine', 'astar', 'shiden', 'statemint', 'moonbeam', 'moonbase', 'moonriver', 'crabParachain', 'darwinia2'],
28
+ bifrost: ['bifrost', 'acala', 'karura', 'acala_testnet', 'pioneer', 'bitcountry', 'bifrost_dot', 'hydradx_main'],
29
+ statemine: ['statemine', 'astar', 'shiden', 'statemint', 'moonbeam', 'moonbase', 'moonriver', 'crabParachain', 'darwinia2', 'parallel'],
30
30
  kusama: ['kusama', 'kintsugi', 'kintsugi_test', 'interlay', 'acala', 'statemint', 'karura', 'bifrost'] // perhaps there are some runtime updates
31
31
  };
32
32
 
@@ -176,11 +176,13 @@ export const _KNOWN_CHAIN_INFLATION_PARAMS = {
176
176
  export const _TRANSFER_NOT_SUPPORTED_CHAINS = ['subspace_gemini_3a', 'kulupu', 'joystream', 'equilibrium_parachain', 'genshiro_testnet', 'genshiro'];
177
177
  export const _TRANSFER_CHAIN_GROUP = {
178
178
  acala: ['karura', 'acala', 'acala_testnet'],
179
- kintsugi: ['kintsugi', 'kintsugi_test', 'interlay'],
179
+ kintsugi: ['kintsugi', 'kintsugi_test', 'interlay', 'bifrost_dot', 'hydradx_main', 'mangatax_para'],
180
180
  genshiro: ['genshiro_testnet', 'genshiro', 'equilibrium_parachain'],
181
181
  crab: ['crab', 'pangolin'],
182
- bitcountry: ['pioneer', 'bitcountry'],
183
- statemine: ['statemint', 'statemine', 'darwinia2']
182
+ bitcountry: ['pioneer', 'bitcountry', 'bifrost'],
183
+ statemine: ['statemint', 'statemine', 'darwinia2', 'astar', 'shiden', 'shibuya', 'parallel'],
184
+ riochain: ['riochain'],
185
+ sora_substrate: ['sora_substrate']
184
186
  };
185
187
  export const _BALANCE_PARSING_CHAIN_GROUP = {
186
188
  bobabeam: ['bobabeam', 'bobabase']
@@ -189,7 +191,7 @@ export const _BALANCE_PARSING_CHAIN_GROUP = {
189
191
  // XCM------------------------------------------------------------------------------------------------------------------
190
192
 
191
193
  export const _XCM_CHAIN_GROUP = {
192
- polkadotXcm: ['astar', 'shiden', 'statemine', 'statemint'],
194
+ polkadotXcm: ['astar', 'shiden', 'statemine', 'statemint', 'equilibrium_parachain'],
193
195
  xcmPallet: ['polkadot', 'kusama']
194
196
  // default is xTokens pallet
195
197
  };
@@ -40,21 +40,25 @@ export class ChainService {
40
40
  this.chainInfoMapSubject.next(this.dataMap.chainInfoMap);
41
41
  this.chainStateMapSubject.next(this.dataMap.chainStateMap);
42
42
  this.assetRegistrySubject.next(this.dataMap.assetRegistry);
43
- this.xcmRefMapSubject.next(this.getXcmRefMap());
43
+ this.xcmRefMapSubject.next(this.dataMap.assetRefMap);
44
44
  this.logger = createLogger('chain-service');
45
45
  this.refreshChainStateInterval(3000, 6);
46
46
  }
47
47
 
48
48
  // Getter
49
49
  getXcmRefMap() {
50
- const result = {};
51
- Object.entries(AssetRefMap).forEach(([key, assetRef]) => {
52
- if (assetRef.path === _AssetRefPath.XCM) {
53
- result[key] = assetRef;
54
- }
55
- });
56
- return result;
50
+ return this.dataMap.assetRefMap;
51
+ // const result: Record<string, _AssetRef> = {};
52
+ //
53
+ // Object.entries(AssetRefMap).forEach(([key, assetRef]) => {
54
+ // if (assetRef.path === _AssetRefPath.XCM) {
55
+ // result[key] = assetRef;
56
+ // }
57
+ // });
58
+ //
59
+ // return result;
57
60
  }
61
+
58
62
  getEvmApi(slug) {
59
63
  return this.evmChainHandler.getEvmApiByChain(slug);
60
64
  }
@@ -356,6 +360,7 @@ export class ChainService {
356
360
  this.chainInfoMapSubject.next(this.getChainInfoMap());
357
361
  this.chainStateMapSubject.next(this.getChainStateMap());
358
362
  this.assetRegistrySubject.next(this.getAssetRegistry());
363
+ this.xcmRefMapSubject.next(this.dataMap.assetRefMap);
359
364
  this.initApis();
360
365
  await this.initAssetSettings();
361
366
  }
@@ -26,7 +26,6 @@ export declare function _getSubstrateRelayParent(chainInfo: _ChainInfo): string;
26
26
  export declare function _getSubstrateGenesisHash(chainInfo: _ChainInfo): string;
27
27
  export declare function _isChainSupportSubstrateStaking(chainInfo: _ChainInfo): boolean;
28
28
  export declare function _isChainEnabled(chainState: _ChainState): boolean;
29
- export declare function _isSubstrateParachain(chainInfo: _ChainInfo): boolean;
30
29
  export declare function _getChainSubstrateAddressPrefix(chainInfo: _ChainInfo): number;
31
30
  export declare function _isChainSupportNativeNft(chainInfo: _ChainInfo): boolean;
32
31
  export declare function _isChainSupportEvmNft(chainInfo: _ChainInfo): boolean;
@@ -130,9 +130,6 @@ export function _isChainSupportSubstrateStaking(chainInfo) {
130
130
  export function _isChainEnabled(chainState) {
131
131
  return chainState.active;
132
132
  }
133
- export function _isSubstrateParachain(chainInfo) {
134
- return chainInfo.substrateInfo !== null && chainInfo.substrateInfo.paraId !== null;
135
- }
136
133
  export function _getChainSubstrateAddressPrefix(chainInfo) {
137
134
  var _chainInfo$substrateI5, _chainInfo$substrateI6;
138
135
  return (_chainInfo$substrateI5 = chainInfo === null || chainInfo === void 0 ? void 0 : (_chainInfo$substrateI6 = chainInfo.substrateInfo) === null || _chainInfo$substrateI6 === void 0 ? void 0 : _chainInfo$substrateI6.addressPrefix) !== null && _chainInfo$substrateI5 !== void 0 ? _chainInfo$substrateI5 : -1;
@@ -259,7 +256,7 @@ export function _isSubstrateRelayChain(chainInfo) {
259
256
  }
260
257
  export function _isSubstrateParaChain(chainInfo) {
261
258
  var _chainInfo$substrateI11;
262
- return ((_chainInfo$substrateI11 = chainInfo.substrateInfo) === null || _chainInfo$substrateI11 === void 0 ? void 0 : _chainInfo$substrateI11.chainType) === _SubstrateChainType.PARACHAIN;
259
+ return chainInfo.substrateInfo !== null && chainInfo.substrateInfo.paraId !== null && ((_chainInfo$substrateI11 = chainInfo.substrateInfo) === null || _chainInfo$substrateI11 === void 0 ? void 0 : _chainInfo$substrateI11.chainType) === _SubstrateChainType.PARACHAIN;
263
260
  }
264
261
  export function _getEvmAbiExplorer(chainInfo) {
265
262
  var _chainInfo$evmInfo3;
@@ -0,0 +1,2 @@
1
+ export declare const MAX_FETCH_PAGE_PER_SESSION = 25;
2
+ export declare const MIN__NUM_HISTORY_PER_ACCOUNT = 50;
@@ -0,0 +1,5 @@
1
+ // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export const MAX_FETCH_PAGE_PER_SESSION = 25;
5
+ export const MIN__NUM_HISTORY_PER_ACCOUNT = 50;
@@ -27,4 +27,4 @@ export interface ParseInputType {
27
27
  export declare type TransactionBasicData = Pick<TransactionHistoryItem, 'address' | 'origin' | 'time' | 'chainType' | 'from' | 'direction' | 'blockNumber' | 'blockHash' | 'chain' | 'data'>;
28
28
  export declare type TransactionSpecifyType = Pick<TransactionHistoryItem, 'to' | 'type' | 'status' | 'fee' | 'amount' | 'tip' | 'signature' | 'extrinsicHash'>;
29
29
  export declare function parseSubsquidTransactionData(address: string, type: SubsquidTransactionType, historyItem: MultiHistoryData, chainInfo: _ChainInfo, args: any, data: any): TransactionHistoryItem;
30
- export declare function fetchMultiChainHistories(addresses: string[], chainMap: Record<string, _ChainInfo>, maxPage?: number): Promise<TransactionHistoryItem<ExtrinsicType.TRANSFER_BALANCE>[]>;
30
+ export declare function fetchMultiChainHistories(addresses: string[], chainMap: Record<string, _ChainInfo>, maxPage?: number, countMap?: Record<string, number>, _lastId?: string): Promise<TransactionHistoryItem<ExtrinsicType.TRANSFER_BALANCE>[]>;
@@ -3,7 +3,9 @@
3
3
 
4
4
  import { ApolloClient, createHttpLink, gql, InMemoryCache } from '@apollo/client';
5
5
  import { ChainType, ExtrinsicStatus, ExtrinsicType, TransactionDirection } from '@subwallet/extension-base/background/KoniTypes';
6
+ import { MAX_FETCH_PAGE_PER_SESSION, MIN__NUM_HISTORY_PER_ACCOUNT } from '@subwallet/extension-base/services/history-service/constants';
6
7
  import fetch from 'cross-fetch';
8
+ import { isArray } from '@polkadot/util';
7
9
  import { decodeAddress, encodeAddress, isEthereumAddress } from '@polkadot/util-crypto';
8
10
  const MULTI_CHAIN_URL = 'https://squid.subsquid.io/multi-chain-tx/v/v1/graphql';
9
11
  const MultiChainTxClient = new ApolloClient({
@@ -71,6 +73,17 @@ function generateSignature(input) {
71
73
  const vHex = parseInt(v).toString(16);
72
74
  return `0x${rHex}${sHex}${vHex}`;
73
75
  }
76
+ const parseArgs = args => {
77
+ if (isArray(args)) {
78
+ return {
79
+ from: args[0],
80
+ to: args[1],
81
+ amount: args[2]
82
+ };
83
+ } else {
84
+ return args;
85
+ }
86
+ };
74
87
  export function parseSubsquidTransactionData(address, type, historyItem, chainInfo, args, data) {
75
88
  var _chainInfo$substrateI, _chainInfo$evmInfo, _chainInfo$substrateI2, _chainInfo$evmInfo2;
76
89
  const chainType = chainInfo.substrateInfo ? ChainType.SUBSTRATE : ChainType.EVM;
@@ -91,7 +104,7 @@ export function parseSubsquidTransactionData(address, type, historyItem, chainIn
91
104
  {
92
105
  transactionType = ExtrinsicType.TRANSFER_BALANCE;
93
106
  const extrinsic = data.extrinsic;
94
- const parsedArgs = args;
107
+ const parsedArgs = parseArgs(args);
95
108
  to = autoFormatAddress(parsedArgs.to);
96
109
  from = autoFormatAddress(parsedArgs.from);
97
110
  amount = parsedArgs.amount;
@@ -196,10 +209,10 @@ export function parseSubsquidTransactionData(address, type, historyItem, chainIn
196
209
  status: success ? ExtrinsicStatus.SUCCESS : ExtrinsicStatus.FAIL
197
210
  };
198
211
  }
199
- export async function fetchMultiChainHistories(addresses, chainMap, maxPage = 25) {
212
+ export async function fetchMultiChainHistories(addresses, chainMap, maxPage = MAX_FETCH_PAGE_PER_SESSION, countMap = {}, _lastId) {
200
213
  const responseData = [];
201
214
  let currentPage = 0;
202
- let lastId;
215
+ let lastId = _lastId;
203
216
  while (true) {
204
217
  try {
205
218
  if (maxPage) {
@@ -228,6 +241,9 @@ export async function fetchMultiChainHistories(addresses, chainMap, maxPage = 25
228
241
  }
229
242
  const histories = [];
230
243
  const lowerAddresses = addresses.map(a => a.toLowerCase());
244
+ for (const lowerAddress of lowerAddresses) {
245
+ countMap[lowerAddress] = countMap[lowerAddress] || 0;
246
+ }
231
247
  responseData.forEach(historyItem => {
232
248
  const {
233
249
  _data,
@@ -248,6 +264,10 @@ export async function fetchMultiChainHistories(addresses, chainMap, maxPage = 25
248
264
 
249
265
  return;
250
266
  }
267
+ usedAddresses.forEach(address => {
268
+ const adr = address.toLowerCase();
269
+ countMap[adr] = (countMap[adr] || 0) + 1;
270
+ });
251
271
  usedAddresses.forEach(address => {
252
272
  try {
253
273
  const transactionData = parseSubsquidTransactionData(address, name, historyItem, chainInfo, parseData(args), parseData(_data));
@@ -257,5 +277,18 @@ export async function fetchMultiChainHistories(addresses, chainMap, maxPage = 25
257
277
  }
258
278
  });
259
279
  });
280
+ if (currentPage > 1) {
281
+ const retryAddresses = [];
282
+ for (const [address, number] of Object.entries(countMap)) {
283
+ if (number < MIN__NUM_HISTORY_PER_ACCOUNT) {
284
+ retryAddresses.push(address);
285
+ }
286
+ }
287
+ const _addresses = addresses.filter(add => retryAddresses.includes(add.toLowerCase()));
288
+ if (_addresses.length > 0) {
289
+ const retryHistories = await fetchMultiChainHistories(_addresses, chainMap, maxPage, countMap, lastId);
290
+ histories.push(...retryHistories);
291
+ }
292
+ }
260
293
  return histories;
261
294
  }
@@ -1,5 +1,7 @@
1
+ import { _ChainInfo } from '@subwallet/chain-list/types';
1
2
  import { SWTransaction } from '@subwallet/extension-base/services/transaction-service/types';
2
3
  import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
3
4
  export declare const getTransactionId: (chainType: string, chain: string, isInternal: boolean) => string;
4
5
  export declare const getValidationId: (chainType: string, chain: string) => string;
5
6
  export declare const isSubstrateTransaction: (tx: SWTransaction['transaction']) => tx is SubmittableExtrinsic;
7
+ export declare const getBaseTransactionInfo: (transaction: SWTransaction, chainInfoMap: Record<string, _ChainInfo>) => string;
@@ -1,6 +1,7 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
4
5
  let transactionCount = 0;
5
6
  let validationCount = 0;
6
7
  export const getTransactionId = (chainType, chain, isInternal) => {
@@ -11,4 +12,45 @@ export const getValidationId = (chainType, chain) => {
11
12
  };
12
13
  export const isSubstrateTransaction = tx => {
13
14
  return !!tx.send;
15
+ };
16
+ const typeName = type => {
17
+ switch (type) {
18
+ case ExtrinsicType.TRANSFER_BALANCE:
19
+ case ExtrinsicType.TRANSFER_TOKEN:
20
+ case ExtrinsicType.TRANSFER_XCM:
21
+ return 'Transfer';
22
+ case ExtrinsicType.SEND_NFT:
23
+ return 'Send NFT';
24
+ case ExtrinsicType.CROWDLOAN:
25
+ return 'Crowdloan contribution';
26
+ case ExtrinsicType.STAKING_JOIN_POOL:
27
+ return 'Join pool';
28
+ case ExtrinsicType.STAKING_LEAVE_POOL:
29
+ return 'Leave pool';
30
+ case ExtrinsicType.STAKING_BOND:
31
+ return 'Bond';
32
+ case ExtrinsicType.STAKING_UNBOND:
33
+ return 'Unbond';
34
+ case ExtrinsicType.STAKING_CLAIM_REWARD:
35
+ return 'Claim reward';
36
+ case ExtrinsicType.STAKING_WITHDRAW:
37
+ return 'Withdraw';
38
+ case ExtrinsicType.STAKING_CANCEL_UNSTAKE:
39
+ return 'Cancel unstake';
40
+ case ExtrinsicType.STAKING_COMPOUNDING:
41
+ return 'Stake compound';
42
+ case ExtrinsicType.EVM_EXECUTE:
43
+ return 'EVM execute';
44
+ case ExtrinsicType.STAKING_CANCEL_COMPOUNDING:
45
+ return 'Cancel compounding';
46
+ case ExtrinsicType.STAKING_POOL_WITHDRAW:
47
+ return 'Withdraw pool';
48
+ case ExtrinsicType.UNKNOWN:
49
+ default:
50
+ return 'unknown';
51
+ }
52
+ };
53
+ export const getBaseTransactionInfo = (transaction, chainInfoMap) => {
54
+ var _chainInfoMap$transac;
55
+ return `${typeName(transaction.extrinsicType)} on ${((_chainInfoMap$transac = chainInfoMap[transaction.chain]) === null || _chainInfoMap$transac === void 0 ? void 0 : _chainInfoMap$transac.name) || 'unknown network'}`;
14
56
  };
@@ -6,11 +6,12 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
6
6
  import { BasicTxErrorType, BasicTxWarningCode, ChainType, EvmProviderErrorType, ExtrinsicStatus, ExtrinsicType, NotificationType, TransactionDirection } from '@subwallet/extension-base/background/KoniTypes';
7
7
  import { TransactionWarning } from '@subwallet/extension-base/background/warnings/TransactionWarning';
8
8
  import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants';
9
+ import { _TRANSFER_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
9
10
  import { _getChainNativeTokenBasicInfo, _getEvmChainId } from '@subwallet/extension-base/services/chain-service/utils';
10
11
  import { EXTENSION_REQUEST_URL } from '@subwallet/extension-base/services/request-service/constants';
11
12
  import { TRANSACTION_TIMEOUT } from '@subwallet/extension-base/services/transaction-service/constants';
12
13
  import { parseTransferEventLogs, parseXcmEventLogs } from '@subwallet/extension-base/services/transaction-service/event-parser';
13
- import { getTransactionId, isSubstrateTransaction } from '@subwallet/extension-base/services/transaction-service/helpers';
14
+ import { getBaseTransactionInfo, getTransactionId, isSubstrateTransaction } from '@subwallet/extension-base/services/transaction-service/helpers';
14
15
  import { getExplorerLink, parseTransactionData } from '@subwallet/extension-base/services/transaction-service/utils';
15
16
  import { anyNumberToBN } from '@subwallet/extension-base/utils/eth';
16
17
  import { parseTxAndSignature } from '@subwallet/extension-base/utils/eth/mergeTransactionAndSignature';
@@ -19,7 +20,7 @@ import keyring from '@subwallet/ui-keyring';
19
20
  import EventEmitter from 'eventemitter3';
20
21
  import RLP from 'rlp';
21
22
  import { BehaviorSubject } from 'rxjs';
22
- import { u8aToHex } from '@polkadot/util';
23
+ import { isHex, u8aToHex } from '@polkadot/util';
23
24
  export default class TransactionService {
24
25
  transactionSubject = new BehaviorSubject({});
25
26
  get transactions() {
@@ -109,6 +110,10 @@ export default class TransactionService {
109
110
  }
110
111
  }
111
112
  } catch (e) {
113
+ const error = e;
114
+ if (error.message.includes('gas required exceeds allowance')) {
115
+ validationResponse.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE));
116
+ }
112
117
  estimateFee.value = '0';
113
118
  }
114
119
  }
@@ -135,16 +140,22 @@ export default class TransactionService {
135
140
  const balanceNum = parseInt(balance.value);
136
141
  const edNum = parseInt(existentialDeposit);
137
142
  const transferNativeNum = parseInt(transferNative);
138
- if (!isTransferAll) {
139
- if (transferNativeNum + feeNum > balanceNum) {
143
+ if (transferNativeNum + feeNum > balanceNum) {
144
+ if (!isTransferAll) {
140
145
  validationResponse.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE));
141
146
  } else {
142
- if (balanceNum - (transferNativeNum + feeNum) <= edNum) {
143
- if (edAsWarning) {
144
- validationResponse.warnings.push(new TransactionWarning(BasicTxWarningCode.NOT_ENOUGH_EXISTENTIAL_DEPOSIT, ''));
145
- } else {
146
- validationResponse.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_EXISTENTIAL_DEPOSIT, ''));
147
- }
147
+ if ([..._TRANSFER_CHAIN_GROUP.acala, ..._TRANSFER_CHAIN_GROUP.genshiro, ..._TRANSFER_CHAIN_GROUP.bitcountry, ..._TRANSFER_CHAIN_GROUP.statemine].includes(chain)) {
148
+ // Chain not have transfer all function
149
+ validationResponse.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE));
150
+ }
151
+ }
152
+ }
153
+ if (!isTransferAll) {
154
+ if (balanceNum - (transferNativeNum + feeNum) < edNum) {
155
+ if (edAsWarning) {
156
+ validationResponse.warnings.push(new TransactionWarning(BasicTxWarningCode.NOT_ENOUGH_EXISTENTIAL_DEPOSIT, ''));
157
+ } else {
158
+ validationResponse.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_EXISTENTIAL_DEPOSIT, ''));
148
159
  }
149
160
  }
150
161
  }
@@ -206,6 +217,7 @@ export default class TransactionService {
206
217
  // @ts-ignore
207
218
  'transaction' in validatedTransaction && delete validatedTransaction.transaction;
208
219
  'additionalValidator' in validatedTransaction && delete validatedTransaction.additionalValidator;
220
+ 'eventsHandler' in validatedTransaction && delete validatedTransaction.eventsHandler;
209
221
  return validatedTransaction;
210
222
  }
211
223
  validatedTransaction.warnings = [];
@@ -227,11 +239,15 @@ export default class TransactionService {
227
239
  // @ts-ignore
228
240
  'transaction' in validatedTransaction && delete validatedTransaction.transaction;
229
241
  'additionalValidator' in validatedTransaction && delete validatedTransaction.additionalValidator;
242
+ 'eventsHandler' in validatedTransaction && delete validatedTransaction.eventsHandler;
230
243
  return validatedTransaction;
231
244
  }
232
245
  async sendTransaction(transaction) {
233
246
  // Send Transaction
234
247
  const emitter = transaction.chainType === 'substrate' ? this.signAndSendSubstrateTransaction(transaction) : await this.signAndSendEvmTransaction(transaction);
248
+ const {
249
+ eventsHandler
250
+ } = transaction;
235
251
  emitter.on('signed', data => {
236
252
  this.onSigned(data);
237
253
  });
@@ -255,6 +271,7 @@ export default class TransactionService {
255
271
 
256
272
  // Todo: handle any event with transaction.eventsHandler
257
273
 
274
+ eventsHandler === null || eventsHandler === void 0 ? void 0 : eventsHandler(emitter);
258
275
  return emitter;
259
276
  }
260
277
  removeTransaction(id) {
@@ -281,6 +298,7 @@ export default class TransactionService {
281
298
  }
282
299
  transactionToHistories(id, startBlock, nonce, eventLogs) {
283
300
  const transaction = this.getTransaction(id);
301
+ const extrinsicType = transaction.extrinsicType;
284
302
  const historyItem = {
285
303
  origin: 'app',
286
304
  chain: transaction.chain,
@@ -311,7 +329,7 @@ export default class TransactionService {
311
329
  };
312
330
 
313
331
  // Fill data by extrinsicType
314
- switch (transaction.extrinsicType) {
332
+ switch (extrinsicType) {
315
333
  case ExtrinsicType.TRANSFER_BALANCE:
316
334
  {
317
335
  const inputData = parseTransactionData(transaction.data);
@@ -350,9 +368,10 @@ export default class TransactionService {
350
368
  };
351
369
 
352
370
  // @ts-ignore
353
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
354
371
  historyItem.additionalInfo = {
355
- destinationChain: (inputData === null || inputData === void 0 ? void 0 : inputData.destinationNetworkKey) || ''
372
+ destinationChain: (inputData === null || inputData === void 0 ? void 0 : inputData.destinationNetworkKey) || '',
373
+ originalChain: inputData.originNetworkKey || '',
374
+ fee: transaction.estimateFee
356
375
  };
357
376
  eventLogs && parseXcmEventLogs(historyItem, eventLogs, transaction.chain, sendingTokenInfo, chainInfo);
358
377
  }
@@ -451,11 +470,22 @@ export default class TransactionService {
451
470
  // Return one more history record if transaction send to account in the wallets
452
471
  const toAccount = (historyItem === null || historyItem === void 0 ? void 0 : historyItem.to) && keyring.getPair(historyItem.to);
453
472
  if (toAccount) {
454
- return [historyItem, {
473
+ const receiverHistory = {
455
474
  ...historyItem,
456
475
  address: toAccount.address,
457
476
  direction: TransactionDirection.RECEIVED
458
- }];
477
+ };
478
+ switch (extrinsicType) {
479
+ case ExtrinsicType.TRANSFER_XCM:
480
+ {
481
+ const inputData = parseTransactionData(transaction.data);
482
+ receiverHistory.chain = inputData.destinationNetworkKey;
483
+ break;
484
+ }
485
+ default:
486
+ break;
487
+ }
488
+ return [historyItem, receiverHistory];
459
489
  }
460
490
  } catch (e) {
461
491
  console.warn(e);
@@ -543,10 +573,11 @@ export default class TransactionService {
543
573
  blockNumber: blockNumber || 0,
544
574
  blockHash: blockHash || ''
545
575
  }).catch(console.error);
576
+ const info = isHex(extrinsicHash) ? extrinsicHash : getBaseTransactionInfo(transaction, this.chainService.getChainInfoMap());
546
577
  this.notificationService.notify({
547
578
  type: NotificationType.SUCCESS,
548
579
  title: 'Transaction completed',
549
- message: `Transaction ${transaction === null || transaction === void 0 ? void 0 : transaction.extrinsicHash} completed`,
580
+ message: `Transaction ${info} completed`,
550
581
  action: {
551
582
  url: this.getTransactionLink(id)
552
583
  },
@@ -577,10 +608,11 @@ export default class TransactionService {
577
608
  blockNumber: blockNumber || 0,
578
609
  blockHash: blockHash || ''
579
610
  }).catch(console.error);
611
+ const info = isHex(transaction === null || transaction === void 0 ? void 0 : transaction.extrinsicHash) ? transaction === null || transaction === void 0 ? void 0 : transaction.extrinsicHash : getBaseTransactionInfo(transaction, this.chainService.getChainInfoMap());
580
612
  this.notificationService.notify({
581
613
  type: NotificationType.ERROR,
582
614
  title: 'Transaction failed',
583
- message: `Transaction ${transaction === null || transaction === void 0 ? void 0 : transaction.extrinsicHash} failed`,
615
+ message: `Transaction ${info} failed`,
584
616
  action: {
585
617
  url: this.getTransactionLink(id)
586
618
  },
@@ -674,7 +706,8 @@ export default class TransactionService {
674
706
  const eventData = {
675
707
  id,
676
708
  errors: [],
677
- warnings: []
709
+ warnings: [],
710
+ extrinsicHash: id
678
711
  };
679
712
  this.requestService.addConfirmation(id, url || EXTENSION_REQUEST_URL, 'evmSendTransactionRequest', payload, {}).then(async ({
680
713
  isApproved,
@@ -745,7 +778,8 @@ export default class TransactionService {
745
778
  const eventData = {
746
779
  id,
747
780
  errors: [],
748
- warnings: []
781
+ warnings: [],
782
+ extrinsicHash: id
749
783
  };
750
784
  transaction.signAsync(address, {
751
785
  signer: {
@@ -775,7 +809,7 @@ export default class TransactionService {
775
809
  }
776
810
  if (txState.status.isInBlock) {
777
811
  eventData.eventLogs = txState.events;
778
- if (!eventData.extrinsicHash || eventData.extrinsicHash === '') {
812
+ if (!eventData.extrinsicHash || eventData.extrinsicHash === '' || !isHex(eventData.extrinsicHash)) {
779
813
  eventData.extrinsicHash = txState.txHash.toHex();
780
814
  eventData.blockHash = txState.status.asInBlock.toHex();
781
815
  emitter.emit('extrinsicHash', eventData);
@@ -21,8 +21,8 @@ export interface SWTransaction extends ValidateTransactionResponse, Partial<Pick
21
21
  additionalValidator?: (inputTransaction: SWTransactionResponse) => Promise<void>;
22
22
  eventsHandler?: (eventEmitter: TransactionEmitter) => void;
23
23
  }
24
- export declare type SWTransactionResult = Omit<SWTransaction, 'transaction' | 'additionalValidator'>;
25
- declare type SwInputBase = Pick<SWTransaction, 'address' | 'url' | 'data' | 'extrinsicType' | 'chain' | 'chainType' | 'ignoreWarnings' | 'transferNativeAmount'> & Partial<Pick<SWTransaction, 'additionalValidator'>>;
24
+ export declare type SWTransactionResult = Omit<SWTransaction, 'transaction' | 'additionalValidator' | 'eventsHandler'>;
25
+ declare type SwInputBase = Pick<SWTransaction, 'address' | 'url' | 'data' | 'extrinsicType' | 'chain' | 'chainType' | 'ignoreWarnings' | 'transferNativeAmount'> & Partial<Pick<SWTransaction, 'additionalValidator' | 'eventsHandler'>>;
26
26
  export interface SWTransactionInput extends SwInputBase {
27
27
  transaction?: SWTransaction['transaction'] | null;
28
28
  warnings?: SWTransaction['warnings'];
@@ -100,44 +100,59 @@ export const isContractAddress = async (address, evmApi) => {
100
100
  return code !== '0x';
101
101
  }
102
102
  };
103
+ const parseInputWithAbi = (input, abi) => {
104
+ const decoder = new InputDataDecoder(abi);
105
+ const raw = decoder.decodeData(input);
106
+ if (raw.method && raw.methodName) {
107
+ const temp = {
108
+ method: raw.method,
109
+ methodName: raw.methodName,
110
+ args: []
111
+ };
112
+ raw.types.forEach((type, index) => {
113
+ temp.args.push(parseResult(type, raw.inputs[index], raw.names[index]));
114
+ });
115
+ return temp;
116
+ } else {
117
+ return null;
118
+ }
119
+ };
103
120
  export const parseContractInput = async (input, contractAddress, network) => {
104
- let result = input;
105
-
106
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
107
- const _ABIs = [...ABIs];
121
+ for (const abi of ABIs) {
122
+ const temp = parseInputWithAbi(input, abi);
123
+ if (temp) {
124
+ return {
125
+ result: temp
126
+ };
127
+ }
128
+ }
108
129
  if (contractAddress && network) {
130
+ console.log('parseOnline');
109
131
  if (_getEvmAbiExplorer(network)) {
110
- const res = await axios.get(_getEvmAbiExplorer(network), {
111
- params: {
112
- address: contractAddress
113
- }
114
- });
132
+ try {
133
+ const res = await axios.get(_getEvmAbiExplorer(network), {
134
+ params: {
135
+ address: contractAddress
136
+ },
137
+ timeout: 3000
138
+ });
115
139
 
116
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
117
- if (res.status === 200 && res.data.status === '1') {
118
140
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
119
- _ABIs.unshift(res.data.result);
120
- }
121
- }
122
- }
123
- for (const abi of _ABIs) {
124
- const decoder = new InputDataDecoder(abi);
125
- const raw = decoder.decodeData(input);
126
- if (raw.method && raw.methodName) {
127
- const temp = {
128
- method: raw.method,
129
- methodName: raw.methodName,
130
- args: []
131
- };
132
- raw.types.forEach((type, index) => {
133
- temp.args.push(parseResult(type, raw.inputs[index], raw.names[index]));
134
- });
135
- result = temp;
136
- break;
141
+ if (res.status === 200 && res.data.status === '1') {
142
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
143
+ const abi = res.data.result;
144
+ const temp = parseInputWithAbi(input, abi);
145
+ if (temp) {
146
+ return {
147
+ result: temp
148
+ };
149
+ }
150
+ }
151
+ } catch (e) {}
137
152
  }
138
153
  }
139
154
  return {
140
- result
155
+ result: input
141
156
  };
142
157
  };
143
158
  const getChainInfoByChainId = (networkMap, chainId) => {
@@ -179,42 +194,37 @@ export const parseEvmRlp = async (data, networkMap, evmApiMap) => {
179
194
  nonce: new BigN(tx.nonce).toNumber()
180
195
  };
181
196
  const network = getChainInfoByChainId(networkMap, parseInt(tx.ethereumChainId));
182
-
183
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
184
- const _ABIs = [...ABIs];
197
+ for (const abi of ABIs) {
198
+ const temp = parseInputWithAbi(tx.data, abi);
199
+ if (temp) {
200
+ result.data = temp;
201
+ return result;
202
+ }
203
+ }
185
204
  if (tx.action && network) {
186
205
  if (await isContractAddress(tx.action, evmApiMap[network.slug])) {
187
206
  if (_getEvmAbiExplorer(network) !== '') {
188
- const res = await axios.get(_getEvmAbiExplorer(network), {
189
- params: {
190
- address: tx.action
191
- }
192
- });
207
+ try {
208
+ const res = await axios.get(_getEvmAbiExplorer(network), {
209
+ params: {
210
+ address: tx.action
211
+ },
212
+ timeout: 2000
213
+ });
193
214
 
194
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
195
- if (res.status === 200 && res.data.status === '1') {
196
215
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
197
- _ABIs.unshift(res.data.result);
198
- }
216
+ if (res.status === 200 && res.data.status === '1') {
217
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
218
+ const abi = res.data.result;
219
+ const temp = parseInputWithAbi(tx.data, abi);
220
+ if (temp) {
221
+ result.data = temp;
222
+ return result;
223
+ }
224
+ }
225
+ } catch (e) {}
199
226
  }
200
227
  }
201
228
  }
202
- for (const abi of _ABIs) {
203
- const decoder = new InputDataDecoder(abi);
204
- const raw = decoder.decodeData(tx.data);
205
- if (raw.method && raw.methodName) {
206
- const temp = {
207
- method: raw.method,
208
- methodName: raw.methodName,
209
- args: []
210
- };
211
- raw.types.forEach((type, index) => {
212
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
213
- temp.args.push(parseResult(type, raw.inputs[index], raw.names[index]));
214
- });
215
- result.data = temp;
216
- break;
217
- }
218
- }
219
229
  return result;
220
230
  };