@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
@@ -1,49 +1,30 @@
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, _getXcmAssetMultilocation, _isSubstrateParaChain, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
6
- function getDestinationChainLocation(destinationChainInfo) {
7
- if (_isSubstrateParaChain(destinationChainInfo)) {
8
- return {
9
- V1: {
10
- parents: 1,
11
- interior: {
12
- X1: {
13
- Parachain: _getSubstrateParaId(destinationChainInfo)
14
- }
15
- }
16
- }
17
- };
18
- }
19
- return {
20
- // to relaychain by default
21
- V1: {
22
- parents: 1,
23
- interior: 'Here'
24
- }
25
- };
26
- }
27
- function getAssetLocation(tokenInfo, sendingValue) {
28
- const multilocation = _getXcmAssetMultilocation(tokenInfo);
29
- return {
30
- V1: [{
31
- id: multilocation,
32
- fun: {
33
- Fungible: sendingValue
34
- }
35
- }]
36
- };
37
- }
4
+ import { getBeneficiary, getDestinationChainLocation, getDestWeight, getTokenLocation } from '@subwallet/extension-base/koni/api/xcm/utils';
5
+ import { _isNativeToken, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
38
6
  export function getExtrinsicByPolkadotXcmPallet(tokenInfo, originChainInfo, destinationChainInfo, recipientAddress, value, api) {
39
7
  const weightParam = getDestWeight();
40
- const beneficiary = getBeneficiary(originChainInfo, destinationChainInfo, recipientAddress);
41
- const destination = getDestinationChainLocation(destinationChainInfo);
42
- const assetLocation = getAssetLocation(tokenInfo, value);
8
+ const beneficiary = getBeneficiary(destinationChainInfo, recipientAddress);
9
+ const destination = getDestinationChainLocation(originChainInfo, destinationChainInfo);
10
+ let assetLocation = getTokenLocation(tokenInfo, value);
43
11
  let method = 'limitedReserveTransferAssets';
44
- if (['astar', 'shiden'].includes(originChainInfo.slug)) {
12
+ if (['astar', 'shiden'].includes(originChainInfo.slug) && !_isNativeToken(tokenInfo)) {
45
13
  method = 'limitedReserveWithdrawAssets';
46
- } else if (_isSubstrateRelayChain(destinationChainInfo)) {
14
+ } else if (['statemint', 'statemine'].includes(originChainInfo.slug) && _isSubstrateRelayChain(destinationChainInfo)) {
15
+ assetLocation = {
16
+ V1: [{
17
+ id: {
18
+ Concrete: {
19
+ parents: 1,
20
+ interior: 'Here'
21
+ }
22
+ },
23
+ fun: {
24
+ Fungible: value
25
+ }
26
+ }]
27
+ };
47
28
  method = 'limitedTeleportAssets';
48
29
  }
49
30
  return api.tx.polkadotXcm[method](destination, beneficiary, assetLocation, 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.9-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -1190,6 +1190,11 @@
1190
1190
  "require": "./cjs/services/history-service/index.js",
1191
1191
  "default": "./services/history-service/index.js"
1192
1192
  },
1193
+ "./services/history-service/constants": {
1194
+ "types": "./services/history-service/constants/index.d.ts",
1195
+ "require": "./cjs/services/history-service/constants/index.js",
1196
+ "default": "./services/history-service/constants/index.js"
1197
+ },
1193
1198
  "./services/history-service/helpers/recoverHistoryStatus": {
1194
1199
  "types": "./services/history-service/helpers/recoverHistoryStatus.d.ts",
1195
1200
  "require": "./cjs/services/history-service/helpers/recoverHistoryStatus.js",
@@ -1635,6 +1640,11 @@
1635
1640
  "require": "./cjs/utils/keyring.js",
1636
1641
  "default": "./utils/keyring.js"
1637
1642
  },
1643
+ "./utils/number": {
1644
+ "types": "./utils/number.d.ts",
1645
+ "require": "./cjs/utils/number.js",
1646
+ "default": "./utils/number.js"
1647
+ },
1638
1648
  "./utils/promise": {
1639
1649
  "types": "./utils/promise.d.ts",
1640
1650
  "require": "./cjs/utils/promise.js",
@@ -1697,13 +1707,13 @@
1697
1707
  "@sora-substrate/type-definitions": "^1.17.7",
1698
1708
  "@subsocial/types": "^0.6.8",
1699
1709
  "@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",
1710
+ "@subwallet/chain-list": "0.1.11-beta.1",
1711
+ "@subwallet/extension-base": "^1.0.9-0",
1712
+ "@subwallet/extension-chains": "^1.0.9-0",
1713
+ "@subwallet/extension-dapp": "^1.0.9-0",
1714
+ "@subwallet/extension-inject": "^1.0.9-0",
1715
+ "@subwallet/keyring": "^0.0.10",
1716
+ "@subwallet/ui-keyring": "^0.0.10",
1707
1717
  "@unique-nft/types": "^0.6.0-4",
1708
1718
  "@zeitgeistpm/type-defs": "^1.0.0",
1709
1719
  "@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.9-0'
11
11
  };
@@ -62,6 +62,8 @@ export declare const _TRANSFER_CHAIN_GROUP: {
62
62
  crab: string[];
63
63
  bitcountry: string[];
64
64
  statemine: string[];
65
+ riochain: string[];
66
+ sora_substrate: string[];
65
67
  };
66
68
  export declare const _BALANCE_PARSING_CHAIN_GROUP: {
67
69
  bobabeam: string[];