@subwallet/extension-base 1.0.7-2 → 1.0.8-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 (46) 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 +2 -1
  8. package/cjs/koni/api/dotsama/crowdloan.js +1 -1
  9. package/cjs/koni/api/dotsama/transfer.js +2 -2
  10. package/cjs/koni/api/xcm/polkadotXcm.js +18 -37
  11. package/cjs/koni/api/xcm/utils.js +78 -11
  12. package/cjs/koni/api/xcm/xTokens.js +4 -33
  13. package/cjs/koni/api/xcm/xcmPallet.js +4 -36
  14. package/cjs/koni/background/handlers/Extension.js +83 -25
  15. package/cjs/koni/background/handlers/State.js +1 -1
  16. package/cjs/packageInfo.js +1 -1
  17. package/cjs/services/chain-service/constants.js +5 -5
  18. package/cjs/services/chain-service/index.js +19 -15
  19. package/cjs/services/chain-service/utils.js +1 -5
  20. package/cjs/services/transaction-service/helpers/index.js +45 -2
  21. package/cjs/services/transaction-service/index.js +58 -24
  22. package/cjs/utils/number.js +112 -0
  23. package/constants/index.d.ts +1 -0
  24. package/constants/index.js +1 -0
  25. package/koni/api/dotsama/balance.js +2 -1
  26. package/koni/api/dotsama/crowdloan.js +2 -2
  27. package/koni/api/dotsama/transfer.js +2 -2
  28. package/koni/api/xcm/polkadotXcm.js +20 -39
  29. package/koni/api/xcm/utils.d.ts +36 -3
  30. package/koni/api/xcm/utils.js +72 -11
  31. package/koni/api/xcm/xTokens.js +6 -35
  32. package/koni/api/xcm/xcmPallet.js +5 -35
  33. package/koni/background/handlers/Extension.js +82 -24
  34. package/koni/background/handlers/State.js +2 -2
  35. package/package.json +13 -8
  36. package/packageInfo.js +1 -1
  37. package/services/chain-service/constants.js +5 -5
  38. package/services/chain-service/index.js +13 -8
  39. package/services/chain-service/utils.d.ts +0 -1
  40. package/services/chain-service/utils.js +1 -4
  41. package/services/transaction-service/helpers/index.d.ts +2 -0
  42. package/services/transaction-service/helpers/index.js +42 -0
  43. package/services/transaction-service/index.js +54 -20
  44. package/services/transaction-service/types.d.ts +2 -2
  45. package/utils/number.d.ts +9 -0
  46. package/utils/number.js +100 -0
@@ -1,10 +1,10 @@
1
- import { _ChainInfo } from '@subwallet/chain-list/types';
1
+ import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
2
  export declare const FOUR_INSTRUCTIONS_WEIGHT = 5000000000;
3
3
  export declare const FOUR_INSTRUCTIONS_LIMITED_WEIGHT: {
4
4
  Limited: number;
5
5
  };
6
- export declare function getReceiverLocation(originChainInfo: _ChainInfo, destinationChainInfo: _ChainInfo, toAddress: string): Record<string, any>;
7
- export declare function getBeneficiary(originChainInfo: _ChainInfo, destinationChainInfo: _ChainInfo, recipientAddress: string, version?: string): {
6
+ export declare function getReceiverLocation(destinationChainInfo: _ChainInfo, toAddress: string, version?: string): Record<string, any>;
7
+ export declare function getBeneficiary(destinationChainInfo: _ChainInfo, recipientAddress: string, version?: string): {
8
8
  [x: string]: {
9
9
  parents: number;
10
10
  interior: {
@@ -13,3 +13,36 @@ export declare function getBeneficiary(originChainInfo: _ChainInfo, destinationC
13
13
  };
14
14
  };
15
15
  export declare function getDestWeight(): string;
16
+ export declare function getTokenLocation(tokenInfo: _ChainAsset, sendingValue: string, version?: string): {
17
+ [x: string]: {
18
+ id: Record<string, any>;
19
+ fun: {
20
+ Fungible: string;
21
+ };
22
+ }[];
23
+ };
24
+ export declare function getDestMultilocation(destinationChainInfo: _ChainInfo, recipient: string, version?: string): {
25
+ [x: string]: {
26
+ parents: number;
27
+ interior: {
28
+ X2: Record<string, any>[];
29
+ };
30
+ };
31
+ } | {
32
+ [x: string]: {
33
+ parents: number;
34
+ interior: {
35
+ X1: Record<string, any>;
36
+ };
37
+ };
38
+ };
39
+ export declare function getDestinationChainLocation(originChainInfo: _ChainInfo, destinationChainInfo: _ChainInfo, version?: string): {
40
+ [x: string]: {
41
+ parents: number;
42
+ interior: string | {
43
+ X1: {
44
+ Parachain: number;
45
+ };
46
+ };
47
+ };
48
+ };
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { COMMON_CHAIN_SLUGS } from '@subwallet/chain-list';
5
- import { _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
5
+ import { _getSubstrateParaId, _getXcmAssetMultilocation, _isChainEvmCompatible, _isNativeToken, _isSubstrateParaChain, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
6
6
  import { decodeAddress, evmToAddress } from '@polkadot/util-crypto';
7
7
  export const FOUR_INSTRUCTIONS_WEIGHT = 5000000000;
8
8
  export const FOUR_INSTRUCTIONS_LIMITED_WEIGHT = {
@@ -11,13 +11,14 @@ export const FOUR_INSTRUCTIONS_LIMITED_WEIGHT = {
11
11
 
12
12
  // get multilocation for destination chain from a parachain
13
13
 
14
- export function getReceiverLocation(originChainInfo, destinationChainInfo, toAddress) {
14
+ export function getReceiverLocation(destinationChainInfo, toAddress, version) {
15
+ const network = version && version === 'V3' ? undefined : 'Any';
15
16
  if (destinationChainInfo.slug === COMMON_CHAIN_SLUGS.ASTAR_EVM) {
16
17
  const ss58Address = evmToAddress(toAddress, 2006); // TODO: shouldn't pass addressPrefix directly
17
18
 
18
19
  return {
19
20
  AccountId32: {
20
- network: 'Any',
21
+ network,
21
22
  id: decodeAddress(ss58Address)
22
23
  }
23
24
  };
@@ -25,20 +26,20 @@ export function getReceiverLocation(originChainInfo, destinationChainInfo, toAdd
25
26
  if (_isChainEvmCompatible(destinationChainInfo)) {
26
27
  return {
27
28
  AccountKey20: {
28
- network: 'Any',
29
+ network,
29
30
  key: toAddress
30
31
  }
31
32
  };
32
33
  }
33
34
  return {
34
35
  AccountId32: {
35
- network: 'Any',
36
+ network,
36
37
  id: decodeAddress(toAddress)
37
38
  }
38
39
  };
39
40
  }
40
- export function getBeneficiary(originChainInfo, destinationChainInfo, recipientAddress, version = 'V1') {
41
- const receiverLocation = getReceiverLocation(originChainInfo, destinationChainInfo, recipientAddress);
41
+ export function getBeneficiary(destinationChainInfo, recipientAddress, version = 'V1') {
42
+ const receiverLocation = getReceiverLocation(destinationChainInfo, recipientAddress, version);
42
43
  return {
43
44
  [version]: {
44
45
  parents: 0,
@@ -50,8 +51,68 @@ export function getBeneficiary(originChainInfo, destinationChainInfo, recipientA
50
51
  }
51
52
  export function getDestWeight() {
52
53
  return 'Unlimited';
53
- // return api.tx.xTokens.transfer.meta.args[3].type.toString() ===
54
- // 'XcmV2WeightLimit'
55
- // ? 'Unlimited'
56
- // : FOUR_INSTRUCTIONS_WEIGHT;
54
+ }
55
+ export function getTokenLocation(tokenInfo, sendingValue, version = 'V1') {
56
+ if (!_isNativeToken(tokenInfo)) {
57
+ const multilocation = _getXcmAssetMultilocation(tokenInfo);
58
+ return {
59
+ [version]: [{
60
+ id: multilocation,
61
+ fun: {
62
+ Fungible: sendingValue
63
+ }
64
+ }]
65
+ };
66
+ }
67
+ return {
68
+ [version]: [{
69
+ id: {
70
+ Concrete: {
71
+ parents: 0,
72
+ interior: 'Here'
73
+ }
74
+ },
75
+ fun: {
76
+ Fungible: sendingValue
77
+ }
78
+ }]
79
+ };
80
+ }
81
+ export function getDestMultilocation(destinationChainInfo, recipient, version = 'V1') {
82
+ const receiverLocation = getReceiverLocation(destinationChainInfo, recipient, version);
83
+ if (_isSubstrateParaChain(destinationChainInfo)) {
84
+ const interior = {
85
+ X2: [{
86
+ Parachain: _getSubstrateParaId(destinationChainInfo)
87
+ }, receiverLocation]
88
+ };
89
+ return {
90
+ [version]: {
91
+ parents: 1,
92
+ interior
93
+ }
94
+ };
95
+ }
96
+ return {
97
+ [version]: {
98
+ parents: 1,
99
+ interior: {
100
+ X1: receiverLocation
101
+ }
102
+ }
103
+ };
104
+ }
105
+ export function getDestinationChainLocation(originChainInfo, destinationChainInfo, version = 'V1') {
106
+ const parents = _isSubstrateRelayChain(originChainInfo) ? 0 : 1;
107
+ const interior = _isSubstrateParaChain(destinationChainInfo) ? {
108
+ X1: {
109
+ Parachain: _getSubstrateParaId(destinationChainInfo)
110
+ }
111
+ } : 'Here';
112
+ return {
113
+ [version]: {
114
+ parents,
115
+ interior
116
+ }
117
+ };
57
118
  }
@@ -1,9 +1,8 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { FOUR_INSTRUCTIONS_WEIGHT, getDestWeight, getReceiverLocation } from '@subwallet/extension-base/koni/api/xcm/utils';
5
- import { _XCM_TYPE } from '@subwallet/extension-base/services/chain-service/constants';
6
- import { _getSubstrateParaId, _getTokenOnChainInfo, _getXcmAssetId, _getXcmAssetMultilocation, _getXcmAssetType, _getXcmTransferType, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
4
+ import { FOUR_INSTRUCTIONS_WEIGHT, getDestMultilocation, getDestWeight } from '@subwallet/extension-base/koni/api/xcm/utils';
5
+ import { _getTokenOnChainAssetId, _getTokenOnChainInfo, _getXcmAssetId, _getXcmAssetMultilocation, _getXcmAssetType, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
7
6
  function getCurrencyId(tokenInfo) {
8
7
  if (['acala', 'karura'].includes(tokenInfo.originChain) && _isNativeToken(tokenInfo)) {
9
8
  return _getXcmAssetMultilocation(tokenInfo);
@@ -16,38 +15,10 @@ function getCurrencyId(tokenInfo) {
16
15
  } else if (['pioneer'].includes(tokenInfo.originChain)) {
17
16
  return _getXcmAssetMultilocation(tokenInfo);
18
17
  }
19
- return _getTokenOnChainInfo(tokenInfo);
20
- }
21
- function getMultiLocationForXtokensPallet(originChainInfo, destinationChainInfo, toAddress) {
22
- const xcmType = _getXcmTransferType(originChainInfo, destinationChainInfo);
23
- const paraId = _getSubstrateParaId(destinationChainInfo);
24
- const receiverLocation = getReceiverLocation(originChainInfo, destinationChainInfo, toAddress);
25
- if (xcmType === _XCM_TYPE.PP) {
26
- // parachain -> parachain
27
- const interior = {
28
- X2: [{
29
- Parachain: paraId
30
- }, receiverLocation]
31
- };
32
- return {
33
- V1: {
34
- parents: 1,
35
- interior
36
- }
37
- };
38
- }
39
-
40
- // parachain -> relaychain by default
41
- return {
42
- V1: {
43
- parents: 1,
44
- interior: {
45
- X1: receiverLocation
46
- }
47
- }
48
- };
18
+ return _getTokenOnChainInfo(tokenInfo) || _getTokenOnChainAssetId(tokenInfo);
49
19
  }
50
20
  export function getExtrinsicByXtokensPallet(tokenInfo, originChainInfo, destinationChainInfo, recipientAddress, value, api) {
51
- const weightParam = ['pioneer'].includes(originChainInfo.slug) ? FOUR_INSTRUCTIONS_WEIGHT : getDestWeight();
52
- return api.tx.xTokens.transfer(getCurrencyId(tokenInfo), value, getMultiLocationForXtokensPallet(originChainInfo, destinationChainInfo, recipientAddress), weightParam);
21
+ const weightParam = ['pioneer', 'hydradx_main'].includes(originChainInfo.slug) ? FOUR_INSTRUCTIONS_WEIGHT : getDestWeight();
22
+ const destVersion = ['moonbeam', 'moonriver'].includes(originChainInfo.slug) ? 'V3' : undefined;
23
+ return api.tx.xTokens.transfer(getCurrencyId(tokenInfo), value, getDestMultilocation(destinationChainInfo, recipientAddress, destVersion), weightParam);
53
24
  }
@@ -1,44 +1,14 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { getBeneficiary, getDestWeight } from '@subwallet/extension-base/koni/api/xcm/utils';
5
- import { _getSubstrateParaId } from '@subwallet/extension-base/services/chain-service/utils';
6
- function getDestinationChainLocation(destinationChainInfo, version = 'V1') {
7
- return {
8
- [version]: {
9
- parents: 0,
10
- interior: {
11
- X1: {
12
- Parachain: _getSubstrateParaId(destinationChainInfo)
13
- }
14
- }
15
- }
16
- };
17
- }
18
- function getTokenLocation(sendingValue, version = 'V2') {
19
- return {
20
- // always native token of relaychain
21
- [version]: [{
22
- id: {
23
- Concrete: {
24
- parents: 0,
25
- interior: 'Here'
26
- }
27
- },
28
- fun: {
29
- Fungible: sendingValue
30
- }
31
- }]
32
- };
33
- }
34
-
4
+ import { getBeneficiary, getDestinationChainLocation, getDestWeight, getTokenLocation } from '@subwallet/extension-base/koni/api/xcm/utils';
35
5
  // this pallet is only used by Relaychains
36
6
  export function getExtrinsicByXcmPalletPallet(tokenInfo, originChainInfo, destinationChainInfo, recipientAddress, value, api) {
37
7
  const weightParam = getDestWeight();
38
- const xcmVer = ['kusama'].includes(originChainInfo.slug) ? 'V2' : 'V1';
39
- const destination = getDestinationChainLocation(destinationChainInfo, xcmVer);
40
- const beneficiary = getBeneficiary(originChainInfo, destinationChainInfo, recipientAddress, xcmVer);
41
- const tokenLocation = getTokenLocation(value, xcmVer);
8
+ const xcmVer = ['kusama'].includes(originChainInfo.slug) ? 'V3' : 'V1';
9
+ const destination = getDestinationChainLocation(originChainInfo, destinationChainInfo, xcmVer);
10
+ const beneficiary = getBeneficiary(destinationChainInfo, recipientAddress, xcmVer);
11
+ const tokenLocation = getTokenLocation(tokenInfo, value, xcmVer);
42
12
  let method = 'limitedReserveTransferAssets';
43
13
  if (['statemint', 'statemine'].includes(destinationChainInfo.slug)) {
44
14
  method = 'limitedTeleportAssets';
@@ -2,13 +2,14 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import Common from '@ethereumjs/common';
5
+ import { _AssetType } from '@subwallet/chain-list/types';
5
6
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
6
7
  import { isJsonPayload, SEED_DEFAULT_LENGTH, SEED_LENGTHS } from '@subwallet/extension-base/background/handlers/Extension';
7
8
  import { withErrorLog } from '@subwallet/extension-base/background/handlers/helpers';
8
9
  import { createSubscription } from '@subwallet/extension-base/background/handlers/subscriptions';
9
10
  import { AccountExternalErrorCode, BasicTxErrorType, BasicTxWarningCode, ChainType, ExternalRequestPromiseStatus, ExtrinsicType, StakingType, TransferTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
10
11
  import { TransactionWarning } from '@subwallet/extension-base/background/warnings/TransactionWarning';
11
- import { ALL_ACCOUNT_KEY, ALL_GENESIS_HASH } from '@subwallet/extension-base/constants';
12
+ import { ALL_ACCOUNT_KEY, ALL_GENESIS_HASH, XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
12
13
  import { ALLOWED_PATH } from '@subwallet/extension-base/defaults';
13
14
  import { parseSubstrateTransaction } from '@subwallet/extension-base/koni/api/dotsama/parseTransaction';
14
15
  import { checkReferenceCount, checkSupportTransfer, createTransferExtrinsic } from '@subwallet/extension-base/koni/api/dotsama/transfer';
@@ -26,6 +27,7 @@ import { reformatAddress } from '@subwallet/extension-base/utils';
26
27
  import { convertSubjectInfoToAddresses } from '@subwallet/extension-base/utils/address';
27
28
  import { createTransactionFromRLP, signatureToHex } from '@subwallet/extension-base/utils/eth';
28
29
  import { parseContractInput, parseEvmRlp } from '@subwallet/extension-base/utils/eth/parseTransaction';
30
+ import { balanceFormatter, formatNumber } from '@subwallet/extension-base/utils/number';
29
31
  import { createPair } from '@subwallet/keyring';
30
32
  import { keyring } from '@subwallet/ui-keyring';
31
33
  import BigN from 'bignumber.js';
@@ -1399,41 +1401,57 @@ export default class KoniExtension {
1399
1401
 
1400
1402
  // Get native token amount
1401
1403
  const freeBalance = await this.#koniState.balanceService.getTokenFreeBalance(from, networkKey, tokenSlug);
1402
- if (isEthereumAddress(from) && isEthereumAddress(to) && _isTokenTransferredByEvm(tokenInfo)) {
1403
- // TODO: review this
1404
- chainType = ChainType.EVM;
1405
- const txVal = transferAll ? freeBalance.value : value || '0';
1406
-
1407
- // Estimate with EVM API
1408
- if (_isTokenEvmSmartContract(tokenInfo) || _isLocalToken(tokenInfo)) {
1409
- [transaction, transferAmount.value] = await getERC20TransactionObject(_getContractAddressOfToken(tokenInfo), chainInfo, from, to, txVal, !!transferAll, evmApiMap);
1404
+ try {
1405
+ if (isEthereumAddress(from) && isEthereumAddress(to) && _isTokenTransferredByEvm(tokenInfo)) {
1406
+ // TODO: review this
1407
+ chainType = ChainType.EVM;
1408
+ const txVal = transferAll ? freeBalance.value : value || '0';
1409
+
1410
+ // Estimate with EVM API
1411
+ if (_isTokenEvmSmartContract(tokenInfo) || _isLocalToken(tokenInfo)) {
1412
+ [transaction, transferAmount.value] = await getERC20TransactionObject(_getContractAddressOfToken(tokenInfo), chainInfo, from, to, txVal, !!transferAll, evmApiMap);
1413
+ } else {
1414
+ [transaction, transferAmount.value] = await getEVMTransactionObject(chainInfo, to, txVal, !!transferAll, evmApiMap);
1415
+ }
1410
1416
  } else {
1411
- [transaction, transferAmount.value] = await getEVMTransactionObject(chainInfo, to, txVal, !!transferAll, evmApiMap);
1417
+ const substrateApi = this.#koniState.getSubstrateApi(networkKey);
1418
+ [transaction, transferAmount.value] = await createTransferExtrinsic({
1419
+ transferAll: !!transferAll,
1420
+ value: value || '0',
1421
+ from: from,
1422
+ networkKey,
1423
+ tokenInfo,
1424
+ to: to,
1425
+ substrateApi
1426
+ });
1412
1427
  }
1413
- } else {
1414
- const substrateApi = this.#koniState.getSubstrateApi(networkKey);
1415
- [transaction, transferAmount.value] = await createTransferExtrinsic({
1416
- transferAll: !!transferAll,
1417
- value: value || '0',
1418
- from: from,
1419
- networkKey,
1420
- tokenInfo,
1421
- to: to,
1422
- substrateApi
1423
- });
1428
+ } catch (e) {
1429
+ const error = e;
1430
+ if (error.message.includes('transfer amount exceeds balance')) {
1431
+ error.message = 'Not enough balance';
1432
+ }
1433
+ throw error;
1424
1434
  }
1425
1435
  const transferNativeAmount = isTransferNativeToken ? transferAmount.value : '0';
1426
1436
  this.addContact(to);
1427
1437
  const additionalValidator = async inputTransaction => {
1438
+ const minAmount = tokenInfo.minAmount || '0';
1428
1439
  if (!isTransferNativeToken) {
1429
1440
  const {
1430
1441
  value: balance
1431
1442
  } = await this.#koniState.balanceService.getTokenFreeBalance(from, networkKey, tokenSlug);
1432
- const minAmount = tokenInfo.minAmount || '0';
1433
1443
  if (new BigN(balance).minus(transferAmount.value).lt(minAmount)) {
1434
1444
  inputTransaction.warnings.push(new TransactionWarning(BasicTxWarningCode.NOT_ENOUGH_EXISTENTIAL_DEPOSIT, ''));
1435
1445
  }
1436
1446
  }
1447
+ const {
1448
+ value: receiverBalance
1449
+ } = await this.#koniState.balanceService.getTokenFreeBalance(to, networkKey, tokenSlug);
1450
+ if (new BigN(receiverBalance).plus(transferAmount.value).lt(minAmount)) {
1451
+ const atLeast = new BigN(minAmount).minus(receiverBalance).plus((tokenInfo.decimals || 0) === 0 ? 0 : 1);
1452
+ const atLeastStr = formatNumber(atLeast, tokenInfo.decimals || 0, balanceFormatter);
1453
+ inputTransaction.errors.push(new TransactionError(TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, `You must transfer at least ${atLeastStr} ${tokenInfo.symbol} to keep the destination account alive`));
1454
+ }
1437
1455
  };
1438
1456
  return this.#koniState.transactionService.handleTransaction({
1439
1457
  errors,
@@ -1447,7 +1465,7 @@ export default class KoniExtension {
1447
1465
  extrinsicType: isTransferNativeToken ? ExtrinsicType.TRANSFER_BALANCE : ExtrinsicType.TRANSFER_TOKEN,
1448
1466
  ignoreWarnings: transferAll,
1449
1467
  isTransferAll: isTransferNativeToken ? transferAll : false,
1450
- edAsWarning: true,
1468
+ edAsWarning: isTransferNativeToken,
1451
1469
  additionalValidator: additionalValidator
1452
1470
  });
1453
1471
  }
@@ -1476,6 +1494,8 @@ export default class KoniExtension {
1476
1494
  if (errors.length > 0) {
1477
1495
  return this.#koniState.transactionService.generateBeforeHandleResponseErrors(errors);
1478
1496
  }
1497
+ let additionalValidator;
1498
+ let eventsHandler;
1479
1499
  if (fromKeyPair && destinationTokenInfo) {
1480
1500
  const substrateApi = this.#koniState.getSubstrateApi(originNetworkKey);
1481
1501
  const chainInfoMap = this.#koniState.getChainInfoMap();
@@ -1487,6 +1507,40 @@ export default class KoniExtension {
1487
1507
  chainInfoMap,
1488
1508
  substrateApi
1489
1509
  });
1510
+ additionalValidator = async inputTransaction => {
1511
+ const destMinAmount = destinationTokenInfo.minAmount || '0';
1512
+ const atLeast = new BigN(destMinAmount).multipliedBy(XCM_MIN_AMOUNT_RATIO);
1513
+ if (new BigN(value).lt(atLeast)) {
1514
+ const atLeastStr = formatNumber(atLeast, destinationTokenInfo.decimals || 0, balanceFormatter);
1515
+ inputTransaction.errors.push(new TransactionError(TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, `You must transfer at least ${atLeastStr} ${originTokenInfo.symbol} to keep the destination account alive`));
1516
+ }
1517
+ const srcMinAmount = originTokenInfo.minAmount || '0';
1518
+ const isTransferNativeToken = originTokenInfo.assetType === _AssetType.NATIVE;
1519
+ if (!isTransferNativeToken) {
1520
+ const {
1521
+ value: balance
1522
+ } = await this.#koniState.balanceService.getTokenFreeBalance(from, originNetworkKey, originTokenInfo.slug);
1523
+ if (new BigN(balance).minus(value).lt(srcMinAmount)) {
1524
+ inputTransaction.warnings.push(new TransactionWarning(BasicTxWarningCode.NOT_ENOUGH_EXISTENTIAL_DEPOSIT, ''));
1525
+ }
1526
+ }
1527
+ };
1528
+ eventsHandler = eventEmitter => {
1529
+ eventEmitter.on('send', () => {
1530
+ try {
1531
+ const dest = keyring.getPair(to);
1532
+ if (dest) {
1533
+ this.updateAssetSetting({
1534
+ autoEnableNativeToken: false,
1535
+ tokenSlug: destinationTokenInfo.slug,
1536
+ assetSetting: {
1537
+ visible: true
1538
+ }
1539
+ }).catch(console.error);
1540
+ }
1541
+ } catch (e) {}
1542
+ });
1543
+ };
1490
1544
  }
1491
1545
  this.addContact(to);
1492
1546
  return await this.#koniState.transactionService.handleTransaction({
@@ -1498,8 +1552,11 @@ export default class KoniExtension {
1498
1552
  extrinsicType: ExtrinsicType.TRANSFER_XCM,
1499
1553
  chainType: ChainType.SUBSTRATE,
1500
1554
  transferNativeAmount: _isNativeToken(originTokenInfo) ? value : '0',
1555
+ ignoreWarnings: inputData.transferAll,
1501
1556
  isTransferAll: inputData.transferAll,
1502
- errors
1557
+ errors,
1558
+ additionalValidator: additionalValidator,
1559
+ eventsHandler: eventsHandler
1503
1560
  });
1504
1561
  }
1505
1562
  async evmNftSubmitTransaction(inputData) {
@@ -2861,6 +2918,7 @@ export default class KoniExtension {
2861
2918
  return Object.fromEntries(Object.entries(rs).map(([key, value]) => {
2862
2919
  const {
2863
2920
  additionalValidator,
2921
+ eventsHandler,
2864
2922
  transaction,
2865
2923
  ...transactionResult
2866
2924
  } = value;
@@ -10,7 +10,7 @@ import { ALL_ACCOUNT_KEY, ALL_GENESIS_HASH } from '@subwallet/extension-base/con
10
10
  import { BalanceService } from '@subwallet/extension-base/services/balance-service';
11
11
  import { ChainService } from '@subwallet/extension-base/services/chain-service';
12
12
  import { _PREDEFINED_SINGLE_MODES } from '@subwallet/extension-base/services/chain-service/constants';
13
- import { _getEvmChainId, _getSubstrateGenesisHash, _isAssetFungibleToken, _isChainEnabled, _isChainTestNet, _isSubstrateParachain, _parseMetadataForSmartContractAsset } from '@subwallet/extension-base/services/chain-service/utils';
13
+ import { _getEvmChainId, _getSubstrateGenesisHash, _isAssetFungibleToken, _isChainEnabled, _isChainTestNet, _isSubstrateParaChain, _parseMetadataForSmartContractAsset } from '@subwallet/extension-base/services/chain-service/utils';
14
14
  import { EventService } from '@subwallet/extension-base/services/event-service';
15
15
  import { HistoryService } from '@subwallet/extension-base/services/history-service';
16
16
  import { KeyringService } from '@subwallet/extension-base/services/keyring-service';
@@ -44,7 +44,7 @@ const getSuri = (seed, type) => {
44
44
  const generateDefaultCrowdloanMap = () => {
45
45
  const crowdloanMap = {};
46
46
  Object.entries(ChainInfoMap).forEach(([networkKey, chainInfo]) => {
47
- if (_isSubstrateParachain(chainInfo)) {
47
+ if (_isSubstrateParaChain(chainInfo)) {
48
48
  crowdloanMap[networkKey] = {
49
49
  state: APIItemState.PENDING,
50
50
  contribute: '0'
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.0.7-2",
20
+ "version": "1.0.8-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -1635,6 +1635,11 @@
1635
1635
  "require": "./cjs/utils/keyring.js",
1636
1636
  "default": "./utils/keyring.js"
1637
1637
  },
1638
+ "./utils/number": {
1639
+ "types": "./utils/number.d.ts",
1640
+ "require": "./cjs/utils/number.js",
1641
+ "default": "./utils/number.js"
1642
+ },
1638
1643
  "./utils/promise": {
1639
1644
  "types": "./utils/promise.d.ts",
1640
1645
  "require": "./cjs/utils/promise.js",
@@ -1697,13 +1702,13 @@
1697
1702
  "@sora-substrate/type-definitions": "^1.17.7",
1698
1703
  "@subsocial/types": "^0.6.8",
1699
1704
  "@substrate/connect": "^0.7.26",
1700
- "@subwallet/chain-list": "^0.1.9",
1701
- "@subwallet/extension-base": "^1.0.7-2",
1702
- "@subwallet/extension-chains": "^1.0.7-2",
1703
- "@subwallet/extension-dapp": "^1.0.7-2",
1704
- "@subwallet/extension-inject": "^1.0.7-2",
1705
- "@subwallet/keyring": "^0.0.9",
1706
- "@subwallet/ui-keyring": "^0.0.9",
1705
+ "@subwallet/chain-list": "0.1.10",
1706
+ "@subwallet/extension-base": "^1.0.8-0",
1707
+ "@subwallet/extension-chains": "^1.0.8-0",
1708
+ "@subwallet/extension-dapp": "^1.0.8-0",
1709
+ "@subwallet/extension-inject": "^1.0.8-0",
1710
+ "@subwallet/keyring": "^0.0.10",
1711
+ "@subwallet/ui-keyring": "^0.0.10",
1707
1712
  "@unique-nft/types": "^0.6.0-4",
1708
1713
  "@zeitgeistpm/type-defs": "^1.0.0",
1709
1714
  "@zeroio/type-definitions": "^0.0.14",
package/packageInfo.js CHANGED
@@ -7,5 +7,5 @@ export const packageInfo = {
7
7
  name: '@subwallet/extension-base',
8
8
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
9
9
  type: 'esm',
10
- version: '1.0.7-2'
10
+ version: '1.0.8-0'
11
11
  };
@@ -25,8 +25,8 @@ export const _BALANCE_CHAIN_GROUP = {
25
25
  kintsugi: ['kintsugi', 'interlay', 'kintsugi_test'],
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,11 @@ 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'],
180
180
  genshiro: ['genshiro_testnet', 'genshiro', 'equilibrium_parachain'],
181
181
  crab: ['crab', 'pangolin'],
182
182
  bitcountry: ['pioneer', 'bitcountry'],
183
- statemine: ['statemint', 'statemine', 'darwinia2']
183
+ statemine: ['statemint', 'statemine', 'darwinia2', 'astar', 'parallel']
184
184
  };
185
185
  export const _BALANCE_PARSING_CHAIN_GROUP = {
186
186
  bobabeam: ['bobabeam', 'bobabase']
@@ -189,7 +189,7 @@ export const _BALANCE_PARSING_CHAIN_GROUP = {
189
189
  // XCM------------------------------------------------------------------------------------------------------------------
190
190
 
191
191
  export const _XCM_CHAIN_GROUP = {
192
- polkadotXcm: ['astar', 'shiden', 'statemine', 'statemint'],
192
+ polkadotXcm: ['astar', 'shiden', 'statemine', 'statemint', 'equilibrium_parachain'],
193
193
  xcmPallet: ['polkadot', 'kusama']
194
194
  // default is xTokens pallet
195
195
  };
@@ -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;
@@ -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;