@subwallet/extension-base 1.2.13-0 → 1.2.15-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 (86) hide show
  1. package/background/errors/SwapError.js +5 -1
  2. package/cjs/background/errors/SwapError.js +5 -1
  3. package/cjs/core/logic-validation/swap.js +56 -3
  4. package/cjs/core/substrate/nominationpools-pallet.js +2 -1
  5. package/cjs/koni/api/nft/config.js +37 -23
  6. package/cjs/koni/api/nft/index.js +9 -1
  7. package/cjs/koni/api/nft/unique_network_nft/index.js +12 -20
  8. package/cjs/koni/background/handlers/Extension.js +12 -0
  9. package/cjs/packageInfo.js +1 -1
  10. package/cjs/services/balance-service/transfer/xcm/utils.js +2 -2
  11. package/cjs/services/chain-service/constants.js +2 -1
  12. package/cjs/services/chain-service/handler/SubstrateApi.js +6 -0
  13. package/cjs/services/chain-service/health-check/constants/index.js +4 -4
  14. package/cjs/services/chain-service/health-check/utils/asset-info.js +23 -6
  15. package/cjs/services/chain-service/health-check/utils/chain-info.js +25 -2
  16. package/cjs/services/chain-service/health-check/utils/new-utils/asset-asset-validate.js +160 -0
  17. package/cjs/services/chain-service/health-check/utils/new-utils/asset-validate.js +45 -0
  18. package/cjs/services/chain-service/health-check/utils/new-utils/chain-asset-validate.js +73 -0
  19. package/cjs/services/chain-service/health-check/utils/new-utils/chain-validate.js +34 -0
  20. package/cjs/services/chain-service/index.js +47 -5
  21. package/cjs/services/earning-service/handlers/liquid-staking/acala.js +49 -19
  22. package/cjs/services/migration-service/scripts/databases/ReloadMetadata.js +35 -0
  23. package/cjs/services/migration-service/scripts/index.js +4 -2
  24. package/cjs/services/price-service/coingecko.js +57 -32
  25. package/cjs/services/price-service/index.js +30 -11
  26. package/cjs/services/storage-service/db-stores/BaseStore.js +4 -0
  27. package/cjs/services/swap-service/handler/asset-hub/handler.js +343 -0
  28. package/cjs/services/swap-service/handler/asset-hub/index.js +12 -0
  29. package/cjs/services/swap-service/handler/asset-hub/router.js +93 -0
  30. package/cjs/services/swap-service/handler/asset-hub/utils.js +158 -0
  31. package/cjs/services/swap-service/index.js +10 -1
  32. package/cjs/services/swap-service/utils.js +10 -1
  33. package/cjs/types/swap/index.js +5 -1
  34. package/core/logic-validation/swap.d.ts +3 -1
  35. package/core/logic-validation/swap.js +55 -4
  36. package/core/substrate/nominationpools-pallet.js +2 -1
  37. package/koni/api/nft/config.d.ts +1 -0
  38. package/koni/api/nft/config.js +31 -19
  39. package/koni/api/nft/index.js +9 -1
  40. package/koni/api/nft/unique_network_nft/index.js +12 -20
  41. package/koni/background/handlers/Extension.js +12 -0
  42. package/package.json +56 -11
  43. package/packageInfo.js +1 -1
  44. package/services/balance-service/transfer/xcm/utils.js +2 -2
  45. package/services/chain-service/constants.d.ts +1 -0
  46. package/services/chain-service/constants.js +2 -1
  47. package/services/chain-service/handler/SubstrateApi.js +6 -0
  48. package/services/chain-service/health-check/constants/index.js +4 -4
  49. package/services/chain-service/health-check/utils/asset-info.d.ts +1 -0
  50. package/services/chain-service/health-check/utils/asset-info.js +20 -4
  51. package/services/chain-service/health-check/utils/chain-info.d.ts +4 -2
  52. package/services/chain-service/health-check/utils/chain-info.js +20 -0
  53. package/services/chain-service/health-check/utils/new-utils/asset-asset-validate.d.ts +10 -0
  54. package/services/chain-service/health-check/utils/new-utils/asset-asset-validate.js +146 -0
  55. package/services/chain-service/health-check/utils/new-utils/asset-validate.d.ts +3 -0
  56. package/services/chain-service/health-check/utils/new-utils/asset-validate.js +38 -0
  57. package/services/chain-service/health-check/utils/new-utils/chain-asset-validate.d.ts +5 -0
  58. package/services/chain-service/health-check/utils/new-utils/chain-asset-validate.js +64 -0
  59. package/services/chain-service/health-check/utils/new-utils/chain-validate.d.ts +4 -0
  60. package/services/chain-service/health-check/utils/new-utils/chain-validate.js +26 -0
  61. package/services/chain-service/index.js +47 -5
  62. package/services/chain-service/types.d.ts +5 -0
  63. package/services/earning-service/handlers/liquid-staking/acala.js +46 -17
  64. package/services/migration-service/scripts/databases/ReloadMetadata.d.ts +5 -0
  65. package/services/migration-service/scripts/databases/ReloadMetadata.js +27 -0
  66. package/services/migration-service/scripts/index.js +4 -2
  67. package/services/price-service/coingecko.js +54 -32
  68. package/services/price-service/index.js +29 -11
  69. package/services/storage-service/db-stores/BaseStore.d.ts +3 -0
  70. package/services/storage-service/db-stores/BaseStore.js +4 -0
  71. package/services/swap-service/handler/asset-hub/handler.d.ts +31 -0
  72. package/services/swap-service/handler/asset-hub/handler.js +335 -0
  73. package/services/swap-service/handler/asset-hub/index.d.ts +1 -0
  74. package/services/swap-service/handler/asset-hub/index.js +4 -0
  75. package/services/swap-service/handler/asset-hub/router.d.ts +16 -0
  76. package/services/swap-service/handler/asset-hub/router.js +85 -0
  77. package/services/swap-service/handler/asset-hub/utils.d.ts +18 -0
  78. package/services/swap-service/handler/asset-hub/utils.js +133 -0
  79. package/services/swap-service/index.js +10 -1
  80. package/services/swap-service/utils.d.ts +1 -0
  81. package/services/swap-service/utils.js +9 -1
  82. package/types/swap/index.d.ts +15 -2
  83. package/types/swap/index.js +5 -1
  84. /package/cjs/services/migration-service/scripts/{ClearMetadataDatabase.js → databases/ClearMetadataDatabase.js} +0 -0
  85. /package/services/migration-service/scripts/{ClearMetadataDatabase.d.ts → databases/ClearMetadataDatabase.d.ts} +0 -0
  86. /package/services/migration-service/scripts/{ClearMetadataDatabase.js → databases/ClearMetadataDatabase.js} +0 -0
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getReserveForPool = exports.getReserveForPath = exports.estimateTokensForPool = exports.estimateTokensForPath = exports.estimateRateForPath = exports.estimateRateAfter = exports.estimatePriceImpactPct = exports.estimateActualRate = exports.checkMinAmountForPool = exports.checkMinAmountForPath = exports.checkLiquidityForPool = exports.checkLiquidityForPath = exports.buildSwapExtrinsic = exports._getPoolInfo = void 0;
8
+ var _utils = require("@subwallet/extension-base/services/chain-service/utils");
9
+ var _swap = require("@subwallet/extension-base/types/swap");
10
+ var _bignumber = _interopRequireDefault(require("bignumber.js"));
11
+ // Copyright 2019-2022 @subwallet/extension-base
12
+ // SPDX-License-Identifier: Apache-2.0
13
+
14
+ const _getPoolInfo = async (api, asset1, asset2) => {
15
+ const assetLocation1 = (0, _utils._getXcmAssetMultilocation)(asset1);
16
+ const assetLocation2 = (0, _utils._getXcmAssetMultilocation)(asset2);
17
+ const rs = await api.call.assetConversionApi.getReserves(assetLocation1, assetLocation2);
18
+ if (!rs) {
19
+ return ['0', '0'];
20
+ }
21
+ const [balanceAsset1, balanceAsset2] = rs.unwrapOrDefault();
22
+ return [balanceAsset1.toString(), balanceAsset2.toString()];
23
+ };
24
+ exports._getPoolInfo = _getPoolInfo;
25
+ const getReserveForPool = async (api, asset1, asset2) => {
26
+ let [balanceAsset1, balanceAsset2] = await _getPoolInfo(api, asset1, asset2);
27
+ if (balanceAsset1 !== '0' && balanceAsset2 !== '0') {
28
+ return [balanceAsset1, balanceAsset2];
29
+ } else {
30
+ [balanceAsset2, balanceAsset1] = await _getPoolInfo(api, asset2, asset1);
31
+ return [balanceAsset1, balanceAsset2];
32
+ }
33
+ };
34
+ exports.getReserveForPool = getReserveForPool;
35
+ const getReserveForPath = async (api, paths) => {
36
+ const pairs = [];
37
+ for (let i = 0; i < paths.length - 1; i++) {
38
+ const asset1 = paths[i];
39
+ const asset2 = paths[i + 1];
40
+ pairs.push([asset1, asset2]);
41
+ }
42
+ return await Promise.all(pairs.map(async _ref => {
43
+ let [asset1, asset2] = _ref;
44
+ return getReserveForPool(api, asset1, asset2);
45
+ }));
46
+ };
47
+ exports.getReserveForPath = getReserveForPath;
48
+ const estimateTokensForPool = (amount, reserves) => {
49
+ if (amount === '0') {
50
+ return '0';
51
+ }
52
+ return new _bignumber.default(amount).times(reserves[1]).div(reserves[0]).integerValue(_bignumber.default.ROUND_DOWN).toString();
53
+ };
54
+ exports.estimateTokensForPool = estimateTokensForPool;
55
+ const estimateTokensForPath = (amount, reserves) => {
56
+ const result = [amount];
57
+ for (let i = 0; i < reserves.length; i++) {
58
+ const reserve = reserves[i];
59
+ const currentAmount = result[i];
60
+ const nextAmount = estimateTokensForPool(currentAmount, reserve);
61
+ result.push(nextAmount);
62
+ }
63
+ return result;
64
+ };
65
+ exports.estimateTokensForPath = estimateTokensForPath;
66
+ const estimateRateForPath = reserves => {
67
+ let result = new _bignumber.default(1);
68
+ for (const reserve of reserves) {
69
+ result = result.times(reserve[0]).div(reserve[1]);
70
+ }
71
+ return result.toString();
72
+ };
73
+ exports.estimateRateForPath = estimateRateForPath;
74
+ const estimateActualRate = (amount, reserves) => {
75
+ let result = new _bignumber.default(1);
76
+ const m = new _bignumber.default(amount);
77
+
78
+ // Currently support for direct path swap only
79
+ for (const reserve of reserves) {
80
+ const x = new _bignumber.default(reserve[0]);
81
+ const y = new _bignumber.default(reserve[1]);
82
+ result = result.times(x.plus(m)).div(y);
83
+ }
84
+ return result.toString();
85
+ };
86
+ exports.estimateActualRate = estimateActualRate;
87
+ const estimateRateAfter = (amount, reserves) => {
88
+ const m = new _bignumber.default(amount);
89
+ const reserve = reserves[0];
90
+ const x = new _bignumber.default(reserve[0]);
91
+ const y = new _bignumber.default(reserve[1]);
92
+ const n = y.multipliedBy(m).div(x.plus(m));
93
+ const result = x.plus(m).div(y.minus(n));
94
+ return result.toString();
95
+ };
96
+ exports.estimateRateAfter = estimateRateAfter;
97
+ const estimatePriceImpactPct = (marketRate, marketRateAfter) => {
98
+ const bnMarketRate = new _bignumber.default(marketRate);
99
+ const bnActualRate = new _bignumber.default(marketRateAfter);
100
+ return new _bignumber.default(1).minus(bnMarketRate.div(bnActualRate)).multipliedBy(100).toString();
101
+ };
102
+ exports.estimatePriceImpactPct = estimatePriceImpactPct;
103
+ const checkLiquidityForPool = (amount, reserve1, reserve2) => {
104
+ if (new _bignumber.default(reserve1).eq('0') || new _bignumber.default(reserve2).eq('0')) {
105
+ return _swap.SwapErrorType.ASSET_NOT_SUPPORTED;
106
+ } else if (new _bignumber.default(reserve1).lt(amount)) {
107
+ return _swap.SwapErrorType.NOT_ENOUGH_LIQUIDITY;
108
+ }
109
+ return undefined;
110
+ };
111
+ exports.checkLiquidityForPool = checkLiquidityForPool;
112
+ const checkLiquidityForPath = (amounts, reserves) => {
113
+ for (let i = 0; i < reserves.length; i++) {
114
+ const amount = amounts[i];
115
+ const [reserve1, reserve2] = reserves[i];
116
+ const error = checkLiquidityForPool(amount, reserve1, reserve2);
117
+ if (error) {
118
+ return error;
119
+ }
120
+ }
121
+ return undefined;
122
+ };
123
+
124
+ // Swap from asset1 to asset2
125
+ exports.checkLiquidityForPath = checkLiquidityForPath;
126
+ const checkMinAmountForPool = (reserve1, reserve2, amount1, amount2, minAmount1, minAmount2) => {
127
+ const newReserve1 = new _bignumber.default(reserve1).plus(amount1);
128
+ const newReserve2 = new _bignumber.default(reserve2).minus(amount2);
129
+ if (newReserve1.lt(minAmount1) || newReserve2.lt(minAmount2)) {
130
+ return _swap.SwapErrorType.MAKE_POOL_NOT_ENOUGH_EXISTENTIAL_DEPOSIT;
131
+ }
132
+ return undefined;
133
+ };
134
+ exports.checkMinAmountForPool = checkMinAmountForPool;
135
+ const checkMinAmountForPath = (reserves, amounts, minAmounts) => {
136
+ for (let i = 0; i < reserves.length; i++) {
137
+ const [amount1, amount2] = amounts.slice(i, 2);
138
+ const [minAmount1, minAmount2] = minAmounts.slice(i, 2);
139
+ const [reserve1, reserve2] = reserves[i];
140
+ const error = checkMinAmountForPool(reserve1, reserve2, amount1, amount2, minAmount1, minAmount2);
141
+ if (error) {
142
+ return error;
143
+ }
144
+ }
145
+ return undefined;
146
+ };
147
+
148
+ // Build extrinsic for swap
149
+ exports.checkMinAmountForPath = checkMinAmountForPath;
150
+ const buildSwapExtrinsic = function (api, paths, recipient, amountIn, amountOutMin) {
151
+ let keepAlive = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
152
+ const pathsInfo = paths.map(asset => {
153
+ const multilocation = (0, _utils._getXcmAssetMultilocation)(asset);
154
+ return api.createType('MultiLocation', multilocation).toU8a();
155
+ });
156
+ return api.tx.assetConversion.swapExactTokensForTokens(pathsInfo, amountIn, amountOutMin, recipient, keepAlive);
157
+ };
158
+ exports.buildSwapExtrinsic = buildSwapExtrinsic;
@@ -8,6 +8,7 @@ var _SwapError = require("@subwallet/extension-base/background/errors/SwapError"
8
8
  var _TransactionError = require("@subwallet/extension-base/background/errors/TransactionError");
9
9
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
10
10
  var _types = require("@subwallet/extension-base/services/base/types");
11
+ var _assetHub = require("@subwallet/extension-base/services/swap-service/handler/asset-hub");
11
12
  var _chainflipHandler = require("@subwallet/extension-base/services/swap-service/handler/chainflip-handler");
12
13
  var _hydradxHandler = require("@subwallet/extension-base/services/swap-service/handler/hydradx-handler");
13
14
  var _utils = require("@subwallet/extension-base/services/swap-service/utils");
@@ -97,7 +98,6 @@ class SwapService {
97
98
  request,
98
99
  selectedQuote: swapQuoteResponse.optimalQuote
99
100
  });
100
- console.log('optimalProcess', optimalProcess);
101
101
  return {
102
102
  process: optimalProcess,
103
103
  quote: swapQuoteResponse
@@ -147,6 +147,15 @@ class SwapService {
147
147
  case _swap.SwapProviderId.HYDRADX_MAINNET:
148
148
  this.handlers[providerId] = new _hydradxHandler.HydradxHandler(this.chainService, this.state.balanceService, false);
149
149
  break;
150
+ case _swap.SwapProviderId.POLKADOT_ASSET_HUB:
151
+ this.handlers[providerId] = new _assetHub.AssetHubSwapHandler(this.chainService, this.state.balanceService, 'statemint');
152
+ break;
153
+ case _swap.SwapProviderId.KUSAMA_ASSET_HUB:
154
+ this.handlers[providerId] = new _assetHub.AssetHubSwapHandler(this.chainService, this.state.balanceService, 'statemine');
155
+ break;
156
+ case _swap.SwapProviderId.ROCOCO_ASSET_HUB:
157
+ this.handlers[providerId] = new _assetHub.AssetHubSwapHandler(this.chainService, this.state.balanceService, 'rococo_assethub');
158
+ break;
150
159
  default:
151
160
  throw new Error('Unsupported provider');
152
161
  }
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports._PROVIDER_TO_SUPPORTED_PAIR_MAP = exports.SWAP_QUOTE_TIMEOUT_MAP = exports.CHAIN_FLIP_TESTNET_EXPLORER = exports.CHAIN_FLIP_SUPPORTED_TESTNET_MAPPING = exports.CHAIN_FLIP_SUPPORTED_TESTNET_ASSET_MAPPING = exports.CHAIN_FLIP_SUPPORTED_MAINNET_MAPPING = exports.CHAIN_FLIP_SUPPORTED_MAINNET_ASSET_MAPPING = exports.CHAIN_FLIP_MAINNET_EXPLORER = void 0;
8
8
  exports.calculateSwapRate = calculateSwapRate;
9
+ exports.convertSwapRate = convertSwapRate;
9
10
  exports.getSwapAltToken = getSwapAltToken;
10
11
  exports.getSwapAlternativeAsset = getSwapAlternativeAsset;
11
12
  var _swap = require("@chainflip/sdk/swap");
@@ -53,7 +54,10 @@ const _PROVIDER_TO_SUPPORTED_PAIR_MAP = {
53
54
  [_swap2.SwapProviderId.HYDRADX_MAINNET]: [_chainList.COMMON_CHAIN_SLUGS.HYDRADX],
54
55
  [_swap2.SwapProviderId.HYDRADX_TESTNET]: [_chainList.COMMON_CHAIN_SLUGS.HYDRADX_TESTNET],
55
56
  [_swap2.SwapProviderId.CHAIN_FLIP_MAINNET]: [_chainList.COMMON_CHAIN_SLUGS.POLKADOT, _chainList.COMMON_CHAIN_SLUGS.ETHEREUM],
56
- [_swap2.SwapProviderId.CHAIN_FLIP_TESTNET]: [_chainList.COMMON_CHAIN_SLUGS.CHAINFLIP_POLKADOT, _chainList.COMMON_CHAIN_SLUGS.ETHEREUM_SEPOLIA]
57
+ [_swap2.SwapProviderId.CHAIN_FLIP_TESTNET]: [_chainList.COMMON_CHAIN_SLUGS.CHAINFLIP_POLKADOT, _chainList.COMMON_CHAIN_SLUGS.ETHEREUM_SEPOLIA],
58
+ [_swap2.SwapProviderId.POLKADOT_ASSET_HUB]: [_chainList.COMMON_CHAIN_SLUGS.POLKADOT_ASSET_HUB],
59
+ [_swap2.SwapProviderId.KUSAMA_ASSET_HUB]: [_chainList.COMMON_CHAIN_SLUGS.KUSAMA_ASSET_HUB],
60
+ [_swap2.SwapProviderId.ROCOCO_ASSET_HUB]: [_chainList.COMMON_CHAIN_SLUGS.ROCOCO_ASSET_HUB]
57
61
  };
58
62
  exports._PROVIDER_TO_SUPPORTED_PAIR_MAP = _PROVIDER_TO_SUPPORTED_PAIR_MAP;
59
63
  function getSwapAlternativeAsset(swapPair) {
@@ -70,4 +74,9 @@ function calculateSwapRate(fromAmount, toAmount, fromAsset, toAsset) {
70
74
  const decimalDiff = (0, _utils._getAssetDecimals)(toAsset) - (0, _utils._getAssetDecimals)(fromAsset);
71
75
  const bnRate = bnFromAmount.div(bnToAmount);
72
76
  return 1 / bnRate.times(10 ** decimalDiff).toNumber();
77
+ }
78
+ function convertSwapRate(rate, fromAsset, toAsset) {
79
+ const decimalDiff = (0, _utils._getAssetDecimals)(toAsset) - (0, _utils._getAssetDecimals)(fromAsset);
80
+ const bnRate = new _bignumber.default(rate);
81
+ return bnRate.times(10 ** decimalDiff).pow(-1).toNumber();
73
82
  }
@@ -19,6 +19,7 @@ exports.SwapErrorType = SwapErrorType;
19
19
  SwapErrorType["SWAP_EXCEED_ALLOWANCE"] = "SWAP_EXCEED_ALLOWANCE";
20
20
  SwapErrorType["SWAP_NOT_ENOUGH_BALANCE"] = "SWAP_NOT_ENOUGH_BALANCE";
21
21
  SwapErrorType["NOT_ENOUGH_LIQUIDITY"] = "NOT_ENOUGH_LIQUIDITY";
22
+ SwapErrorType["MAKE_POOL_NOT_ENOUGH_EXISTENTIAL_DEPOSIT"] = "MAKE_POOL_NOT_ENOUGH_EXISTENTIAL_DEPOSIT";
22
23
  SwapErrorType["AMOUNT_CANNOT_BE_ZERO"] = "AMOUNT_CANNOT_BE_ZERO";
23
24
  })(SwapErrorType || (exports.SwapErrorType = SwapErrorType = {}));
24
25
  let SwapStepType;
@@ -33,8 +34,11 @@ exports.SwapProviderId = SwapProviderId;
33
34
  SwapProviderId["CHAIN_FLIP_MAINNET"] = "CHAIN_FLIP_MAINNET";
34
35
  SwapProviderId["HYDRADX_MAINNET"] = "HYDRADX_MAINNET";
35
36
  SwapProviderId["HYDRADX_TESTNET"] = "HYDRADX_TESTNET";
37
+ SwapProviderId["POLKADOT_ASSET_HUB"] = "POLKADOT_ASSET_HUB";
38
+ SwapProviderId["KUSAMA_ASSET_HUB"] = "KUSAMA_ASSET_HUB";
39
+ SwapProviderId["ROCOCO_ASSET_HUB"] = "ROCOCO_ASSET_HUB";
36
40
  })(SwapProviderId || (exports.SwapProviderId = SwapProviderId = {}));
37
- const _SUPPORTED_SWAP_PROVIDERS = [SwapProviderId.CHAIN_FLIP_TESTNET, SwapProviderId.CHAIN_FLIP_MAINNET, SwapProviderId.HYDRADX_MAINNET, SwapProviderId.HYDRADX_TESTNET];
41
+ const _SUPPORTED_SWAP_PROVIDERS = [SwapProviderId.CHAIN_FLIP_TESTNET, SwapProviderId.CHAIN_FLIP_MAINNET, SwapProviderId.HYDRADX_MAINNET, SwapProviderId.HYDRADX_TESTNET, SwapProviderId.POLKADOT_ASSET_HUB, SwapProviderId.KUSAMA_ASSET_HUB, SwapProviderId.ROCOCO_ASSET_HUB];
38
42
  exports._SUPPORTED_SWAP_PROVIDERS = _SUPPORTED_SWAP_PROVIDERS;
39
43
  // process handling
40
44
  let SwapFeeType;
@@ -1,8 +1,10 @@
1
1
  import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
3
3
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
4
- import { ChainflipPreValidationMetadata, HydradxPreValidationMetadata, SwapErrorType } from '@subwallet/extension-base/types/swap';
4
+ import { AssetHubPreValidationMetadata, ChainflipPreValidationMetadata, HydradxPreValidationMetadata, SwapErrorType } from '@subwallet/extension-base/types/swap';
5
+ export declare function _validateBalanceToSwapOnAssetHub(fromToken: _ChainAsset, feeToken: _ChainAsset, feeTokenChainInfo: _ChainInfo, feeAmount: string, fromTokenBalance: string, feeTokenBalance: string, swapAmount: string, isXcmOk: boolean, minSwap?: string): TransactionError | undefined;
5
6
  export declare function _validateBalanceToSwap(fromToken: _ChainAsset, feeToken: _ChainAsset, feeTokenChainInfo: _ChainInfo, feeAmount: string, fromTokenBalance: string, feeTokenBalance: string, swapAmount: string, isXcmOk: boolean, minSwap?: string): TransactionError | undefined;
6
7
  export declare function _validateSwapRecipient(destChainInfo: _ChainInfo, recipient: string): TransactionError | undefined;
7
8
  export declare function _getChainflipEarlyValidationError(error: SwapErrorType, metadata: ChainflipPreValidationMetadata): SwapError;
8
9
  export declare function _getEarlyHydradxValidationError(error: SwapErrorType, metadata: HydradxPreValidationMetadata): SwapError;
10
+ export declare function _getEarlyAssetHubValidationError(error: SwapErrorType, metadata: AssetHubPreValidationMetadata): SwapError;
@@ -4,17 +4,51 @@
4
4
  import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
5
5
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
6
6
  import { BasicTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
7
- import { _getAssetDecimals, _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
7
+ import { _getAssetDecimals, _getTokenMinAmount, _isChainEvmCompatible, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
8
8
  import { SwapErrorType } from '@subwallet/extension-base/types/swap';
9
9
  import { formatNumber } from '@subwallet/extension-base/utils';
10
10
  import BigN from 'bignumber.js';
11
11
  import { isEthereumAddress } from '@polkadot/util-crypto';
12
+ export function _validateBalanceToSwapOnAssetHub(fromToken, feeToken, feeTokenChainInfo, feeAmount, fromTokenBalance, feeTokenBalance, swapAmount, isXcmOk, minSwap) {
13
+ const bnFromTokenBalance = new BigN(fromTokenBalance);
14
+ if (!_isNativeToken(fromToken) && bnFromTokenBalance.minus(swapAmount).lt(_getTokenMinAmount(fromToken))) {
15
+ const parsedMaxBalanceSwap = formatNumber(bnFromTokenBalance.minus(_getTokenMinAmount(fromToken)), _getAssetDecimals(fromToken));
16
+ return new TransactionError(SwapErrorType.SWAP_EXCEED_ALLOWANCE, `Amount too high. Lower your amount ${bnFromTokenBalance.gt(0) ? `below ${parsedMaxBalanceSwap} ${fromToken.symbol}` : ''} and try again`);
17
+ }
18
+ if (new BigN(feeTokenBalance).lte(feeAmount)) {
19
+ return new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, `You don't have enough ${feeToken.symbol} (${feeTokenChainInfo.name}) to pay transaction fee`);
20
+ }
21
+ if (!_isNativeToken(fromToken) && fromToken.slug === feeToken.slug) {
22
+ // todo: need review and refactor
23
+ if (bnFromTokenBalance.lte(new BigN(feeAmount).plus(swapAmount))) {
24
+ return new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, `Insufficient balance. Deposit ${fromToken.symbol} and try again.`);
25
+ }
26
+ }
27
+ if (isXcmOk) {
28
+ // assume that the swap is valid if XCM is in the process and it was successful
29
+ return undefined;
30
+ }
31
+ if (minSwap) {
32
+ if (bnFromTokenBalance.lte(minSwap)) {
33
+ const parsedMinSwapValue = formatNumber(minSwap, _getAssetDecimals(fromToken));
34
+ return new TransactionError(SwapErrorType.SWAP_NOT_ENOUGH_BALANCE, `Insufficient balance. You need more than ${parsedMinSwapValue} ${fromToken.symbol} to start swapping. Deposit ${fromToken.symbol} and try again.`); // todo: min swap or amount?
35
+ }
36
+ }
37
+
38
+ if (new BigN(swapAmount).gte(fromTokenBalance)) {
39
+ const parsedMaxBalanceSwap = formatNumber(fromTokenBalance, _getAssetDecimals(fromToken));
40
+ return new TransactionError(SwapErrorType.SWAP_EXCEED_ALLOWANCE, `Amount too high. Lower your amount ${bnFromTokenBalance.gt(0) ? `below ${parsedMaxBalanceSwap} ${fromToken.symbol}` : ''} and try again`);
41
+ }
42
+ return undefined;
43
+ }
12
44
  export function _validateBalanceToSwap(fromToken, feeToken, feeTokenChainInfo, feeAmount, fromTokenBalance, feeTokenBalance, swapAmount, isXcmOk, minSwap) {
45
+ const bnFromTokenBalance = new BigN(fromTokenBalance);
13
46
  if (new BigN(feeTokenBalance).lte(feeAmount)) {
14
47
  return new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, `You don't have enough ${feeToken.symbol} (${feeTokenChainInfo.name}) to pay transaction fee`);
15
48
  }
16
49
  if (fromToken.slug === feeToken.slug) {
17
- if (new BigN(fromTokenBalance).lte(new BigN(feeAmount).plus(swapAmount))) {
50
+ // todo: need review and refactor
51
+ if (bnFromTokenBalance.lte(new BigN(feeAmount).plus(swapAmount))) {
18
52
  return new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, `Insufficient balance. Deposit ${fromToken.symbol} and try again.`);
19
53
  }
20
54
  }
@@ -23,7 +57,7 @@ export function _validateBalanceToSwap(fromToken, feeToken, feeTokenChainInfo, f
23
57
  return undefined;
24
58
  }
25
59
  if (minSwap) {
26
- if (new BigN(fromTokenBalance).lte(minSwap)) {
60
+ if (bnFromTokenBalance.lte(minSwap)) {
27
61
  const parsedMinSwapValue = formatNumber(minSwap, _getAssetDecimals(fromToken));
28
62
  return new TransactionError(SwapErrorType.SWAP_NOT_ENOUGH_BALANCE, `Insufficient balance. You need more than ${parsedMinSwapValue} ${fromToken.symbol} to start swapping. Deposit ${fromToken.symbol} and try again.`); // todo: min swap or amount?
29
63
  }
@@ -31,7 +65,7 @@ export function _validateBalanceToSwap(fromToken, feeToken, feeTokenChainInfo, f
31
65
 
32
66
  if (new BigN(swapAmount).gte(fromTokenBalance)) {
33
67
  const parsedMaxBalanceSwap = formatNumber(fromTokenBalance, _getAssetDecimals(fromToken));
34
- return new TransactionError(SwapErrorType.SWAP_EXCEED_ALLOWANCE, `Amount too high. Lower your amount ${new BigN(fromTokenBalance).gt(0) ? `below ${parsedMaxBalanceSwap} ${fromToken.symbol}` : ''} and try again`);
68
+ return new TransactionError(SwapErrorType.SWAP_EXCEED_ALLOWANCE, `Amount too high. Lower your amount ${bnFromTokenBalance.gt(0) ? `below ${parsedMaxBalanceSwap} ${fromToken.symbol}` : ''} and try again`);
35
69
  }
36
70
  return undefined;
37
71
  }
@@ -86,4 +120,21 @@ export function _getEarlyHydradxValidationError(error, metadata) {
86
120
  default:
87
121
  return new SwapError(error);
88
122
  }
123
+ }
124
+ export function _getEarlyAssetHubValidationError(error, metadata) {
125
+ switch (error) {
126
+ case SwapErrorType.AMOUNT_CANNOT_BE_ZERO:
127
+ return new SwapError(error, 'Amount too low. Increase your amount above 0 and try again');
128
+ case SwapErrorType.ASSET_NOT_SUPPORTED:
129
+ return new SwapError(error, 'This swap pair is not supported');
130
+ case SwapErrorType.UNKNOWN:
131
+ return new SwapError(error, `Undefined error. Check your Internet and ${metadata.chain.slug} connection or contact support`);
132
+ case SwapErrorType.ERROR_FETCHING_QUOTE:
133
+ return new SwapError(error, 'No swap quote found. Adjust your amount or try again later.');
134
+ case SwapErrorType.MAKE_POOL_NOT_ENOUGH_EXISTENTIAL_DEPOSIT:
135
+ return new SwapError(error, 'You swap too much. It make pool not enough existential deposit');
136
+ // TODO: i18n this
137
+ default:
138
+ return new SwapError(error);
139
+ }
89
140
  }
@@ -6,7 +6,8 @@ export function _getActiveStakeInNominationPool(memberInfo) {
6
6
  return new BigN(memberInfo.points.toString());
7
7
  }
8
8
  export function _getUnbondingStakeInNominationPool(memberInfo) {
9
- return new BigN(Object.values(memberInfo.unbondingEras).reduce((a, b) => a + b, 0));
9
+ const unbondingValues = Object.values(memberInfo.unbondingEras).map(unbonding => new BigN(unbonding));
10
+ return new BigN(Object.values(unbondingValues).reduce((a, b) => a.plus(b), new BigN(0)));
10
11
  }
11
12
  export function _getTotalStakeInNominationPool(memberInfo) {
12
13
  return _getActiveStakeInNominationPool(memberInfo).plus(_getUnbondingStakeInNominationPool(memberInfo));
@@ -47,6 +47,7 @@ export declare enum SUPPORTED_TRANSFER_EVM_CHAIN_NAME {
47
47
  shibuya = "shibuya"
48
48
  }
49
49
  export declare const SUPPORTED_TRANSFER_EVM_CHAIN: string[];
50
+ export declare const UNSUPPORTED_TRANSFER_EVM_CHAIN_NAME: string[];
50
51
  export declare const TRANSFER_CHAIN_ID: {
51
52
  [x: string]: number;
52
53
  };
@@ -1,7 +1,8 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { isFirefox, RuntimeInfo } from '@subwallet/extension-base/utils';
4
+ import { isFirefox, RuntimeInfo } from '@subwallet/extension-base/utils/environment'; // do not change to shorten path, avoid circle import
5
+
5
6
  export const SINGULAR_V1_ENDPOINT = 'https://singular.rmrk-api.xyz/api/account-rmrk1/';
6
7
  export const SINGULAR_V2_ENDPOINT = 'https://singular.rmrk-api.xyz/api/account/';
7
8
  export const KANARIA_ENDPOINT = 'https://kanaria.rmrk.app/api/rmrk2/';
@@ -73,6 +74,7 @@ export let SUPPORTED_TRANSFER_EVM_CHAIN_NAME;
73
74
  SUPPORTED_TRANSFER_EVM_CHAIN_NAME["shibuya"] = "shibuya";
74
75
  })(SUPPORTED_TRANSFER_EVM_CHAIN_NAME || (SUPPORTED_TRANSFER_EVM_CHAIN_NAME = {}));
75
76
  export const SUPPORTED_TRANSFER_EVM_CHAIN = [SUPPORTED_TRANSFER_EVM_CHAIN_NAME.moonbase, SUPPORTED_TRANSFER_EVM_CHAIN_NAME.moonbeam, SUPPORTED_TRANSFER_EVM_CHAIN_NAME.moonriver, SUPPORTED_TRANSFER_EVM_CHAIN_NAME.astarEvm, SUPPORTED_TRANSFER_EVM_CHAIN_NAME.shiden, SUPPORTED_TRANSFER_EVM_CHAIN_NAME.shibuya];
77
+ export const UNSUPPORTED_TRANSFER_EVM_CHAIN_NAME = ['unique_evm'];
76
78
  export const TRANSFER_CHAIN_ID = {
77
79
  [SUPPORTED_TRANSFER_EVM_CHAIN_NAME.moonbase]: 1287,
78
80
  [SUPPORTED_TRANSFER_EVM_CHAIN_NAME.moonbeam]: 1284,
@@ -106,24 +108,34 @@ if (isFirefox) {
106
108
  if (RuntimeInfo.protocol && RuntimeInfo.protocol.startsWith('http')) {
107
109
  // This is for https
108
110
  if (RuntimeInfo.protocol.startsWith('https')) {
109
- RANDOM_IPFS_GATEWAY_SETTING.push({
110
- provider: IPFS_FLEEK,
111
- weight: 4
112
- }, {
113
- provider: IPFS_GATEWAY_4EVERLAND,
114
- weight: 2
115
- }, {
116
- provider: IPFS_W3S_LINK,
117
- weight: 1
118
- }, {
119
- provider: CF_IPFS_GATEWAY,
120
- weight: 4
121
- }, {
122
- provider: PINATA_IPFS_GATEWAY,
123
- weight: 1 // Rate limit too low
124
- }, {
125
- provider: IPFS_IO,
126
- weight: 5
111
+ RANDOM_IPFS_GATEWAY_SETTING.push(
112
+ // {
113
+ // provider: IPFS_FLEEK,
114
+ // weight: 4
115
+ // },
116
+ // {
117
+ // provider: IPFS_GATEWAY_4EVERLAND,
118
+ // weight: 2
119
+ // },
120
+ // {
121
+ // provider: IPFS_W3S_LINK,
122
+ // weight: 1
123
+ // },
124
+ // {
125
+ // provider: CF_IPFS_GATEWAY,
126
+ // weight: 4
127
+ // },
128
+ // {
129
+ // provider: PINATA_IPFS_GATEWAY,
130
+ // weight: 1 // Rate limit too low
131
+ // },
132
+ // {
133
+ // provider: IPFS_IO,
134
+ // weight: 5
135
+ // },
136
+ {
137
+ provider: SUBWALLET_IPFS,
138
+ weight: 10
127
139
  });
128
140
  }
129
141
  } else {
@@ -17,7 +17,7 @@ import { _isChainSupportEvmNft, _isChainSupportNativeNft, _isChainSupportWasmNft
17
17
  import { categoryAddresses, targetIsWeb } from '@subwallet/extension-base/utils';
18
18
  import AssetHubNftsPalletApi from "./assethub_nft/index.js";
19
19
  function createSubstrateNftApi(chain, substrateApi, addresses) {
20
- const [substrateAddresses] = categoryAddresses(addresses);
20
+ const [substrateAddresses, evmAddresses] = categoryAddresses(addresses);
21
21
  if (_NFT_CHAIN_GROUP.acala.includes(chain)) {
22
22
  return [new AcalaNftApi(substrateApi, substrateAddresses, chain)];
23
23
  } else if (_NFT_CHAIN_GROUP.karura.includes(chain)) {
@@ -30,6 +30,8 @@ function createSubstrateNftApi(chain, substrateApi, addresses) {
30
30
  return [new AssetHubUniquesPalletApi(substrateApi, substrateAddresses, chain), new AssetHubNftsPalletApi(substrateApi, substrateAddresses, chain)];
31
31
  } else if (_NFT_CHAIN_GROUP.unique_network.includes(chain)) {
32
32
  return [new UniqueNftApi(chain, substrateAddresses)];
33
+ } else if (_NFT_CHAIN_GROUP.unique_evm.includes(chain)) {
34
+ return [new UniqueNftApi(chain, evmAddresses)];
33
35
  } else if (_NFT_CHAIN_GROUP.bitcountry.includes(chain)) {
34
36
  return [new BitCountryNftApi(substrateApi, substrateAddresses, chain)];
35
37
  } else if (_NFT_CHAIN_GROUP.vara.includes(chain)) {
@@ -119,6 +121,12 @@ export class NftHandler {
119
121
  }
120
122
  }
121
123
  }
124
+ if (chain === 'unique_evm') {
125
+ const handlers = createSubstrateNftApi(chain, null, evmAddresses);
126
+ if (handlers && !!handlers.length) {
127
+ this.handlers.push(...handlers);
128
+ }
129
+ }
122
130
  if (_isChainSupportWasmNft(chainInfo)) {
123
131
  if (this.substrateApiMap[chain]) {
124
132
  const handler = createWasmNftApi(chain, this.substrateApiMap[chain], substrateAddresses);
@@ -3,6 +3,7 @@
3
3
 
4
4
  import { OPAL_SCAN_ENDPOINT, QUARTZ_SCAN_ENDPOINT, UNIQUE_IPFS_GATEWAY, UNIQUE_SCAN_ENDPOINT } from '@subwallet/extension-base/koni/api/nft/config';
5
5
  import { BaseNftApi } from '@subwallet/extension-base/koni/api/nft/nft';
6
+ import { _NFT_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
6
7
  import { baseParseIPFSUrl } from '@subwallet/extension-base/utils';
7
8
  import { decodeAddress, encodeAddress } from '@polkadot/util-crypto';
8
9
  export class UniqueNftApi extends BaseNftApi {
@@ -15,23 +16,13 @@ export class UniqueNftApi extends BaseNftApi {
15
16
  handleProperties(nft) {
16
17
  const propertiesMap = {};
17
18
  const attRecord = nft.attributes;
18
- if (attRecord) {
19
- for (const item in attRecord) {
20
- const attName = attRecord[item].name._;
21
- const attInfo = attRecord[item].value;
22
- if (Array.isArray(attInfo)) {
23
- const attList = [];
24
- for (const trait of attInfo) {
25
- attList.push(trait._);
26
- }
27
- propertiesMap[attName] = {
28
- value: attList
29
- };
30
- } else {
31
- propertiesMap[attName] = {
32
- value: attInfo._
33
- };
34
- }
19
+ if (attRecord.length) {
20
+ for (const item of attRecord) {
21
+ const attName = item.trait_type;
22
+ const attInfo = item.value;
23
+ propertiesMap[attName] = {
24
+ value: attInfo
25
+ };
35
26
  }
36
27
  }
37
28
  return propertiesMap;
@@ -78,8 +69,10 @@ export class UniqueNftApi extends BaseNftApi {
78
69
  endpoint = OPAL_SCAN_ENDPOINT;
79
70
  uniqueAddress = address;
80
71
  // Opal address: Normal address
72
+ } else if (_NFT_CHAIN_GROUP.unique_evm.includes(this.chain)) {
73
+ endpoint = UNIQUE_SCAN_ENDPOINT;
74
+ uniqueAddress = address.toLowerCase();
81
75
  }
82
-
83
76
  const resp = await fetch(endpoint, {
84
77
  method: 'post',
85
78
  headers: {
@@ -99,7 +92,6 @@ export class UniqueNftApi extends BaseNftApi {
99
92
  if (nfts) {
100
93
  const collectionMap = {};
101
94
  for (const nft of nfts) {
102
- var _nft$image;
103
95
  // Handle case rendering image on Quartz Network (Temporary solution)
104
96
  if (this.chain === 'quartz' && nft.collection_id.toString() === '141') {
105
97
  continue;
@@ -114,7 +106,7 @@ export class UniqueNftApi extends BaseNftApi {
114
106
  chain: this.chain,
115
107
  owner: address,
116
108
  name: nft.token_name,
117
- image: this.parseUrl((_nft$image = nft.image) === null || _nft$image === void 0 ? void 0 : _nft$image.fullUrl),
109
+ image: this.parseUrl(nft.image),
118
110
  description: nft.collection_description,
119
111
  collectionId: nft.collection_id.toString(),
120
112
  properties: propertiesMap
@@ -15,6 +15,7 @@ import { getERC20SpendingApprovalTx } from '@subwallet/extension-base/koni/api/c
15
15
  import { isSnowBridgeGatewayContract } from '@subwallet/extension-base/koni/api/contract-handler/utils';
16
16
  import { resolveAzeroAddressToDomain, resolveAzeroDomainToAddress } from '@subwallet/extension-base/koni/api/dotsama/domain';
17
17
  import { parseSubstrateTransaction } from '@subwallet/extension-base/koni/api/dotsama/parseTransaction';
18
+ import { UNSUPPORTED_TRANSFER_EVM_CHAIN_NAME } from '@subwallet/extension-base/koni/api/nft/config';
18
19
  import { getNftTransferExtrinsic, isRecipientSelf } from '@subwallet/extension-base/koni/api/nft/transfer';
19
20
  import { getBondingExtrinsic, getCancelWithdrawalExtrinsic, getClaimRewardExtrinsic, getNominationPoolsInfo, getUnbondingExtrinsic, getValidatorsInfo, validateBondingCondition, validateUnbondingCondition } from '@subwallet/extension-base/koni/api/staking/bonding';
20
21
  import { getTuringCancelCompoundingExtrinsic, getTuringCompoundExtrinsic } from '@subwallet/extension-base/koni/api/staking/bonding/paraChain';
@@ -1797,6 +1798,17 @@ export default class KoniExtension {
1797
1798
  } = inputData;
1798
1799
  const contractAddress = params.contractAddress;
1799
1800
  const tokenId = params.tokenId;
1801
+ if (UNSUPPORTED_TRANSFER_EVM_CHAIN_NAME.includes(networkKey)) {
1802
+ return await this.#koniState.transactionService.handleTransaction({
1803
+ address: senderAddress,
1804
+ chain: networkKey,
1805
+ chainType: ChainType.EVM,
1806
+ data: inputData,
1807
+ extrinsicType: ExtrinsicType.SEND_NFT,
1808
+ transaction: null,
1809
+ url: EXTENSION_REQUEST_URL
1810
+ });
1811
+ }
1800
1812
  const transaction = await getERC721Transaction(this.#koniState.getEvmApi(networkKey), networkKey, contractAddress, senderAddress, recipientAddress, tokenId);
1801
1813
 
1802
1814
  // this.addContact(recipientAddress);