@subwallet/extension-base 1.2.14-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 (46) hide show
  1. package/cjs/core/substrate/nominationpools-pallet.js +2 -1
  2. package/cjs/koni/api/nft/config.js +9 -5
  3. package/cjs/koni/api/nft/index.js +9 -1
  4. package/cjs/koni/api/nft/unique_network_nft/index.js +12 -20
  5. package/cjs/koni/background/handlers/Extension.js +12 -0
  6. package/cjs/packageInfo.js +1 -1
  7. package/cjs/services/chain-service/constants.js +1 -0
  8. package/cjs/services/chain-service/health-check/constants/index.js +4 -4
  9. package/cjs/services/chain-service/health-check/utils/asset-info.js +23 -6
  10. package/cjs/services/chain-service/health-check/utils/chain-info.js +25 -2
  11. package/cjs/services/chain-service/health-check/utils/new-utils/asset-asset-validate.js +160 -0
  12. package/cjs/services/chain-service/health-check/utils/new-utils/asset-validate.js +45 -0
  13. package/cjs/services/chain-service/health-check/utils/new-utils/chain-asset-validate.js +73 -0
  14. package/cjs/services/chain-service/health-check/utils/new-utils/chain-validate.js +34 -0
  15. package/cjs/services/chain-service/index.js +30 -1
  16. package/cjs/services/earning-service/handlers/liquid-staking/acala.js +49 -19
  17. package/cjs/services/price-service/coingecko.js +57 -32
  18. package/cjs/services/price-service/index.js +30 -11
  19. package/core/substrate/nominationpools-pallet.js +2 -1
  20. package/koni/api/nft/config.d.ts +1 -0
  21. package/koni/api/nft/config.js +3 -1
  22. package/koni/api/nft/index.js +9 -1
  23. package/koni/api/nft/unique_network_nft/index.js +12 -20
  24. package/koni/background/handlers/Extension.js +12 -0
  25. package/package.json +26 -6
  26. package/packageInfo.js +1 -1
  27. package/services/chain-service/constants.d.ts +1 -0
  28. package/services/chain-service/constants.js +1 -0
  29. package/services/chain-service/health-check/constants/index.js +4 -4
  30. package/services/chain-service/health-check/utils/asset-info.d.ts +1 -0
  31. package/services/chain-service/health-check/utils/asset-info.js +20 -4
  32. package/services/chain-service/health-check/utils/chain-info.d.ts +4 -2
  33. package/services/chain-service/health-check/utils/chain-info.js +20 -0
  34. package/services/chain-service/health-check/utils/new-utils/asset-asset-validate.d.ts +10 -0
  35. package/services/chain-service/health-check/utils/new-utils/asset-asset-validate.js +146 -0
  36. package/services/chain-service/health-check/utils/new-utils/asset-validate.d.ts +3 -0
  37. package/services/chain-service/health-check/utils/new-utils/asset-validate.js +38 -0
  38. package/services/chain-service/health-check/utils/new-utils/chain-asset-validate.d.ts +5 -0
  39. package/services/chain-service/health-check/utils/new-utils/chain-asset-validate.js +64 -0
  40. package/services/chain-service/health-check/utils/new-utils/chain-validate.d.ts +4 -0
  41. package/services/chain-service/health-check/utils/new-utils/chain-validate.js +26 -0
  42. package/services/chain-service/index.js +30 -1
  43. package/services/chain-service/types.d.ts +5 -0
  44. package/services/earning-service/handlers/liquid-staking/acala.js +46 -17
  45. package/services/price-service/coingecko.js +54 -32
  46. package/services/price-service/index.js +29 -11
@@ -28,7 +28,7 @@ const filterChainInfoMap = (data, ignoredChains) => {
28
28
  return !info.bitcoinInfo && !ignoredChains.includes(slug);
29
29
  }));
30
30
  };
31
- const ignoredList = ['bevm', 'bevmTest', 'bevm_testnet', 'layerEdge_testnet', 'merlinEvm', 'botanixEvmTest', 'syscoin_evm', 'rollux_evm'];
31
+ const ignoredList = ['bevm', 'bevmTest', 'bevm_testnet', 'layerEdge_testnet', 'merlinEvm', 'botanixEvmTest', 'syscoin_evm', 'syscoin_evm_testnet', 'rollux_evm', 'rollux_testnet', 'boolAlpha', 'boolBeta_testnet'];
32
32
  const filterAssetInfoMap = (chainInfo, assets) => {
33
33
  return Object.fromEntries(Object.entries(assets).filter(_ref2 => {
34
34
  let [, info] = _ref2;
@@ -683,6 +683,34 @@ class ChainService {
683
683
  }
684
684
  const onUpdateStatus = status => {
685
685
  const slug = chainInfo.slug;
686
+ const isActive = this.getChainStateByKey(slug).active;
687
+ const isConnectProblem = status !== _types3._ChainConnectionStatus.CONNECTING && status !== _types3._ChainConnectionStatus.CONNECTED;
688
+ const isLightRpc = endpoint.startsWith('light');
689
+ if (isActive && isConnectProblem && !isLightRpc) {
690
+ const reportApiUrl = 'https://api-cache.subwallet.app/api/health-check/report-rpc';
691
+ const requestBody = {
692
+ chainSlug: slug,
693
+ chainStatus: status,
694
+ rpcReport: {
695
+ [providerName]: endpoint
696
+ },
697
+ configStatus: {
698
+ countUnstable: 10,
699
+ countDie: 20
700
+ }
701
+ };
702
+ fetch(reportApiUrl, {
703
+ // can get status from this response
704
+ method: 'POST',
705
+ headers: {
706
+ 'X-API-KEY': '9b1c94a5e1f3a2d9f8b2a4d6e1f3a2d9',
707
+ 'Content-Type': 'application/json'
708
+ },
709
+ body: JSON.stringify(requestBody)
710
+ })
711
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
712
+ .then(() => {}).catch(error => console.error('Error connecting to the report API:', error));
713
+ }
686
714
  this.updateChainConnectionStatus(slug, status);
687
715
  };
688
716
  if (chainInfo.substrateInfo !== null && chainInfo.substrateInfo !== undefined) {
@@ -692,6 +720,7 @@ class ChainService {
692
720
  //
693
721
  // this.substrateChainHandler.setSubstrateApi(chainInfo.slug, chainApi);
694
722
  // } else {
723
+
695
724
  const chainApi = await this.substrateChainHandler.initApi(chainInfo.slug, endpoint, {
696
725
  providerName,
697
726
  onUpdateStatus
@@ -6,8 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.default = void 0;
8
8
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
9
+ var _constants = require("@subwallet/extension-base/services/chain-service/constants");
9
10
  var _utils = require("@subwallet/extension-base/services/chain-service/utils");
10
- var _constants = require("@subwallet/extension-base/services/earning-service/constants");
11
+ var _constants2 = require("@subwallet/extension-base/services/earning-service/constants");
11
12
  var _types = require("@subwallet/extension-base/types");
12
13
  var _util = require("@polkadot/util");
13
14
  var _base = _interopRequireDefault(require("./base"));
@@ -16,6 +17,9 @@ var _base = _interopRequireDefault(require("./base"));
16
17
 
17
18
  const GRAPHQL_API = 'https://api.polkawallet.io/acala-liquid-staking-subql';
18
19
  const EXCHANGE_RATE_REQUEST = 'query { dailySummaries(first:30, orderBy:TIMESTAMP_DESC) {nodes { exchangeRate timestamp }}}';
20
+ function convertDerivativeToken(amount, exchangeRate, decimals) {
21
+ return amount.mul(new _util.BN(exchangeRate)).div(_util.BN_TEN.pow(new _util.BN(decimals)));
22
+ }
19
23
  class AcalaLiquidStakingPoolHandler extends _base.default {
20
24
  altInputAsset = 'polkadot-NATIVE-DOT';
21
25
  derivativeAssets = ['acala-LOCAL-LDOT'];
@@ -29,8 +33,7 @@ class AcalaLiquidStakingPoolHandler extends _base.default {
29
33
  defaultUnstake: true,
30
34
  fastUnstake: true,
31
35
  cancelUnstake: false,
32
- withdraw: false,
33
- // TODO: Change after verify unstake info
36
+ withdraw: true,
34
37
  claimReward: false
35
38
  };
36
39
  constructor(state, chain) {
@@ -118,30 +121,56 @@ class AcalaLiquidStakingPoolHandler extends _base.default {
118
121
  return;
119
122
  }
120
123
  const balances = _balances;
121
- const redeemRequests = await substrateApi.api.query.homa.redeemRequests.multi(useAddresses);
122
- // This rate is multiple with decimals
123
- const exchangeRate = await this.getExchangeRate();
124
- const decimals = _util.BN_TEN.pow(new _util.BN(this.rateDecimals));
124
+ const [redeemRequests, exchangeRate, _currentEra] = await Promise.all([substrateApi.api.query.homa.redeemRequests.multi(useAddresses), this.getExchangeRate(), substrateApi.api.query.homa.relayChainCurrentEra()]);
125
+ const currentEra = _currentEra.toPrimitive();
125
126
  for (let i = 0; i < balances.length; i++) {
126
127
  const balanceItem = balances[i];
127
128
  const address = useAddresses[i];
128
129
  const activeTotalBalance = balanceItem.free || _util.BN_ZERO;
129
- let totalBalance = activeTotalBalance.mul(new _util.BN(exchangeRate)).div(decimals);
130
+ let totalBalance = convertDerivativeToken(activeTotalBalance, exchangeRate, this.rateDecimals);
130
131
  let unlockingBalance = _util.BN_ZERO;
131
132
  const unstakings = [];
133
+
134
+ // Handle redeem request
132
135
  const redeemRequest = redeemRequests[i].toPrimitive();
133
136
  if (redeemRequest) {
134
- // If withdrawable = false, redeem request is claimed
135
- const [redeemAmount, withdrawable] = redeemRequest;
136
-
137
- // Redeem amount in derivative token
138
- const amount = new _util.BN(redeemAmount).mul(new _util.BN(exchangeRate)).div(decimals);
139
- totalBalance = totalBalance.add(amount);
140
- unlockingBalance = unlockingBalance.add(amount);
137
+ const [derivativeRedeemAmount, _] = redeemRequest;
138
+ const redeemAmount = convertDerivativeToken(new _util.BN(derivativeRedeemAmount), exchangeRate, this.rateDecimals);
139
+ totalBalance = totalBalance.add(redeemAmount);
140
+ unlockingBalance = unlockingBalance.add(redeemAmount);
141
141
  unstakings.push({
142
142
  chain: this.chain,
143
- status: withdrawable ? _types.UnstakingStatus.CLAIMABLE : _types.UnstakingStatus.UNLOCKING,
144
- claimable: amount.toString()
143
+ status: _types.UnstakingStatus.UNLOCKING,
144
+ claimable: redeemAmount.toString(),
145
+ waitingTime: 28 * _constants._STAKING_ERA_LENGTH_MAP.polkadot // up to 29 day (in case non-fast-match
146
+ });
147
+ }
148
+
149
+ // Handle unbondings
150
+ const unbondings = await substrateApi.api.query.homa.unbondings.entries(address);
151
+ if (unbondings.length > 0) {
152
+ unbondings.forEach(_ref => {
153
+ let [unbondingInfo, unbondingValue] = _ref;
154
+ // @ts-ignore
155
+ const _targetEra = unbondingInfo.toHuman()[1];
156
+ const targetEra = parseInt(_targetEra.replaceAll(',', ''));
157
+ const amount = new _util.BN(unbondingValue.toPrimitive());
158
+ totalBalance = totalBalance.add(amount);
159
+ unlockingBalance = unlockingBalance.add(amount);
160
+ if (targetEra > currentEra) {
161
+ unstakings.push({
162
+ chain: this.chain,
163
+ status: _types.UnstakingStatus.UNLOCKING,
164
+ claimable: amount.toString(),
165
+ waitingTime: (targetEra - currentEra) * _constants._STAKING_ERA_LENGTH_MAP.polkadot // Todo: Handle exact timestamp?
166
+ });
167
+ } else {
168
+ unstakings.push({
169
+ chain: this.chain,
170
+ status: _types.UnstakingStatus.CLAIMABLE,
171
+ claimable: amount.toString()
172
+ });
173
+ }
145
174
  });
146
175
  }
147
176
  const result = {
@@ -181,7 +210,7 @@ class AcalaLiquidStakingPoolHandler extends _base.default {
181
210
  const poolOriginSubstrateApi = await this.substrateApi.isReady;
182
211
  const defaultFeeTokenSlug = this.feeAssets[0];
183
212
  if (new _util.BN(params.amount).gt(_util.BN_ZERO)) {
184
- const _mintFeeInfo = await poolOriginSubstrateApi.api.tx.homa.mint(params.amount).paymentInfo(_constants.fakeAddress);
213
+ const _mintFeeInfo = await poolOriginSubstrateApi.api.tx.homa.mint(params.amount).paymentInfo(_constants2.fakeAddress);
185
214
  const mintFeeInfo = _mintFeeInfo.toPrimitive();
186
215
  return {
187
216
  amount: mintFeeInfo.partialFee.toString(),
@@ -232,7 +261,8 @@ class AcalaLiquidStakingPoolHandler extends _base.default {
232
261
  }
233
262
  async handleYieldUnstake(amount, address, selectedTarget) {
234
263
  const chainApi = await this.substrateApi.isReady;
235
- const extrinsic = chainApi.api.tx.homa.requestRedeem(amount, false);
264
+ const extrinsic = chainApi.api.tx.homa.requestRedeem(amount, true); // set true to allow fast match
265
+
236
266
  return [_KoniTypes.ExtrinsicType.UNSTAKE_LDOT, extrinsic];
237
267
  }
238
268
  async handleYieldWithdraw(address, unstakingInfo) {
@@ -5,15 +5,25 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getPriceMap = exports.getExchangeRateMap = void 0;
7
7
  var _staticData = require("@subwallet/extension-base/utils/staticData");
8
+ var _util = require("@polkadot/util");
8
9
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
9
10
  // SPDX-License-Identifier: Apache-2.0
10
11
 
11
12
  const DEFAULT_CURRENCY = 'USD';
12
13
  let useBackupApi = false;
13
14
  const getExchangeRateMap = async () => {
15
+ let response;
14
16
  try {
15
- const response = await fetch('https://api-cache.subwallet.app/exchange-rate');
16
- const responseDataExchangeRate = (await response.json()) || {};
17
+ var _response, _response2;
18
+ try {
19
+ response = await fetch('https://api-cache.subwallet.app/exchange-rate');
20
+ } catch (e) {}
21
+ if (((_response = response) === null || _response === void 0 ? void 0 : _response.status) !== 200) {
22
+ try {
23
+ response = await fetch('https://static-cache.subwallet.app/exchange-rate/data.json');
24
+ } catch (e) {}
25
+ }
26
+ const responseDataExchangeRate = (await ((_response2 = response) === null || _response2 === void 0 ? void 0 : _response2.json())) || {};
17
27
  const exchangeRateMap = Object.keys(responseDataExchangeRate.conversion_rates).reduce((map, exchangeKey) => {
18
28
  if (!_staticData.staticData[_staticData.StaticKey.CURRENCY_SYMBOL][exchangeKey]) {
19
29
  return map;
@@ -26,45 +36,60 @@ const getExchangeRateMap = async () => {
26
36
  }, {});
27
37
  return exchangeRateMap;
28
38
  } catch (e) {
29
- console.warn('Failed to get exchange rate');
30
39
  return {};
31
40
  }
32
41
  };
33
42
  exports.getExchangeRateMap = getExchangeRateMap;
34
43
  const getPriceMap = async function (priceIds) {
35
- var _rs, _rs2;
36
44
  let currency = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'USD';
37
45
  const idStr = Array.from(priceIds).join(',');
38
- let rs;
39
- if (!useBackupApi) {
40
- try {
41
- rs = await fetch(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency.toLowerCase()}&per_page=250&ids=${idStr}`);
42
- } catch (err) {
46
+ let response;
47
+ try {
48
+ var _response3, _response5;
49
+ if (!useBackupApi) {
50
+ try {
51
+ response = await fetch(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency.toLowerCase()}&per_page=250&ids=${idStr}`);
52
+ } catch (err) {
53
+ useBackupApi = true;
54
+ }
55
+ }
56
+ if (useBackupApi || ((_response3 = response) === null || _response3 === void 0 ? void 0 : _response3.status) !== 200) {
57
+ var _response4;
43
58
  useBackupApi = true;
59
+ try {
60
+ response = await fetch(`https://api-cache.subwallet.app/api/price/get?ids=${idStr}`);
61
+ } catch (e) {}
62
+ if (((_response4 = response) === null || _response4 === void 0 ? void 0 : _response4.status) !== 200) {
63
+ try {
64
+ response = await fetch('https://static-cache.subwallet.app/price/data.json');
65
+ } catch (e) {}
66
+ }
44
67
  }
68
+ const generateDataPriceRaw = (await ((_response5 = response) === null || _response5 === void 0 ? void 0 : _response5.json())) || [];
69
+ const responseDataPrice = (0, _util.isArray)(generateDataPriceRaw) ? generateDataPriceRaw : Object.entries(generateDataPriceRaw).map(_ref => {
70
+ let [id, value] = _ref;
71
+ return {
72
+ ...value,
73
+ id
74
+ };
75
+ });
76
+ const currencyData = _staticData.staticData[_staticData.StaticKey.CURRENCY_SYMBOL][currency || DEFAULT_CURRENCY];
77
+ const priceMap = {};
78
+ const price24hMap = {};
79
+ responseDataPrice.forEach(val => {
80
+ const currentPrice = val.current_price || 0;
81
+ const price24h = currentPrice - (val.price_change_24h || 0);
82
+ priceMap[val.id] = currentPrice;
83
+ price24hMap[val.id] = price24h;
84
+ });
85
+ return {
86
+ currency,
87
+ currencyData,
88
+ priceMap,
89
+ price24hMap
90
+ };
91
+ } catch (e) {
92
+ return {};
45
93
  }
46
- if (useBackupApi || ((_rs = rs) === null || _rs === void 0 ? void 0 : _rs.status) !== 200) {
47
- useBackupApi = true;
48
- rs = await fetch(`https://chain-data.subwallet.app/api/price/get?ids=${idStr}`);
49
- }
50
- if (((_rs2 = rs) === null || _rs2 === void 0 ? void 0 : _rs2.status) !== 200) {
51
- console.warn('Failed to get token price');
52
- }
53
- const responseDataPrice = (await rs.json()) || [];
54
- const currencyData = _staticData.staticData[_staticData.StaticKey.CURRENCY_SYMBOL][currency || DEFAULT_CURRENCY];
55
- const priceMap = {};
56
- const price24hMap = {};
57
- responseDataPrice.forEach(val => {
58
- const currentPrice = val.current_price || 0;
59
- const price24h = currentPrice - (val.price_change_24h || 0);
60
- priceMap[val.id] = currentPrice;
61
- price24hMap[val.id] = price24h;
62
- });
63
- return {
64
- currency,
65
- currencyData,
66
- priceMap,
67
- price24hMap
68
- };
69
94
  };
70
95
  exports.getPriceMap = getPriceMap;
@@ -9,6 +9,7 @@ var _types = require("@subwallet/extension-base/services/base/types");
9
9
  var _coingecko = require("@subwallet/extension-base/services/price-service/coingecko");
10
10
  var _storage = require("@subwallet/extension-base/storage");
11
11
  var _stores = require("@subwallet/extension-base/stores");
12
+ var _utils = require("@subwallet/extension-base/utils");
12
13
  var _promise = require("@subwallet/extension-base/utils/promise");
13
14
  var _staticData = require("@subwallet/extension-base/utils/staticData");
14
15
  var _rxjs = require("rxjs");
@@ -28,6 +29,9 @@ const DEFAULT_PRICE_SUBJECT = {
28
29
  price24hMap: {},
29
30
  exchangeRateMap: {}
30
31
  };
32
+ const checkFetchSuccess = (obj1, obj2) => {
33
+ return Object.keys(obj1).length > 0 && Object.keys(obj2).length > 0;
34
+ };
31
35
  class PriceService {
32
36
  priceIds = new Set();
33
37
  currency = new _stores.CurrentCurrencyStore();
@@ -49,11 +53,16 @@ class PriceService {
49
53
  this.init().then(() => this.getCurrentCurrency(updateCurrency)).catch(console.error);
50
54
  }
51
55
  async getTokenPrice(priceIds, currency, resolve, reject) {
52
- await Promise.all([(0, _coingecko.getExchangeRateMap)(), (0, _coingecko.getPriceMap)(priceIds, currency)]).then(_ref => {
53
- let [exchangeRateMap, priceMap] = _ref;
54
- this.rawExchangeRateMap.next(exchangeRateMap);
55
- this.rawPriceSubject.next(priceMap);
56
- });
56
+ const getPriceData = async () => {
57
+ await Promise.all([(0, _coingecko.getExchangeRateMap)(), (0, _coingecko.getPriceMap)(priceIds, currency)]).then(_ref => {
58
+ let [exchangeRateMap, priceMap] = _ref;
59
+ if (checkFetchSuccess(priceMap, exchangeRateMap)) {
60
+ this.rawExchangeRateMap.next(exchangeRateMap);
61
+ this.rawPriceSubject.next(priceMap);
62
+ }
63
+ });
64
+ };
65
+ await Promise.race([getPriceData(), (0, _utils.wait)(10 * 1000)]);
57
66
  }
58
67
  getCurrentCurrencySubject() {
59
68
  return this.currency.getSubject();
@@ -89,17 +98,27 @@ class PriceService {
89
98
  })();
90
99
  }
91
100
  async calculatePriceMap(currency) {
92
- const {
101
+ let {
93
102
  price24hMap,
94
103
  priceMap
95
104
  } = this.rawPriceSubject.value;
96
- const exchangeRateData = this.rawExchangeRateMap.value;
105
+ let exchangeRateData = this.rawExchangeRateMap.value;
106
+ const priceStored = await this.dbService.getPriceStore(currency);
97
107
  const currencyKey = currency || DEFAULT_CURRENCY;
98
108
  if (Object.keys(this.rawPriceSubject.value).length === 0) {
99
- return;
109
+ if (priceStored !== null && priceStored !== void 0 && priceStored.exchangeRateMap) {
110
+ exchangeRateData = priceStored.exchangeRateMap;
111
+ }
100
112
  }
101
113
  if (Object.keys(exchangeRateData).length === 0) {
102
- return;
114
+ if (priceStored !== null && priceStored !== void 0 && priceStored.price24hMap) {
115
+ price24hMap = {
116
+ ...priceStored.price24hMap
117
+ };
118
+ priceMap = {
119
+ ...priceStored.priceMap
120
+ };
121
+ }
103
122
  }
104
123
  const finalPriceMap = {
105
124
  priceMap: {
@@ -165,8 +184,8 @@ class PriceService {
165
184
  this.refreshPriceMapByAction();
166
185
  }
167
186
  };
168
- this.getCurrentCurrencySubject().subscribe(currency => {
169
- console.log('Currency changed', currency);
187
+ (0, _rxjs.combineLatest)([this.getCurrentCurrencySubject(), this.rawPriceSubject, this.rawExchangeRateMap]).subscribe(_ref2 => {
188
+ let [currency] = _ref2;
170
189
  this.calculatePriceMap(currency).then(data => {
171
190
  if (data) {
172
191
  this.priceSubject.next(data);
@@ -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,
@@ -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);
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.2.14-0",
20
+ "version": "1.2.15-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -719,6 +719,26 @@
719
719
  "require": "./cjs/services/chain-service/health-check/utils/chain-info.js",
720
720
  "default": "./services/chain-service/health-check/utils/chain-info.js"
721
721
  },
722
+ "./services/chain-service/health-check/utils/new-utils/asset-asset-validate": {
723
+ "types": "./services/chain-service/health-check/utils/new-utils/asset-asset-validate.d.ts",
724
+ "require": "./cjs/services/chain-service/health-check/utils/new-utils/asset-asset-validate.js",
725
+ "default": "./services/chain-service/health-check/utils/new-utils/asset-asset-validate.js"
726
+ },
727
+ "./services/chain-service/health-check/utils/new-utils/asset-validate": {
728
+ "types": "./services/chain-service/health-check/utils/new-utils/asset-validate.d.ts",
729
+ "require": "./cjs/services/chain-service/health-check/utils/new-utils/asset-validate.js",
730
+ "default": "./services/chain-service/health-check/utils/new-utils/asset-validate.js"
731
+ },
732
+ "./services/chain-service/health-check/utils/new-utils/chain-asset-validate": {
733
+ "types": "./services/chain-service/health-check/utils/new-utils/chain-asset-validate.d.ts",
734
+ "require": "./cjs/services/chain-service/health-check/utils/new-utils/chain-asset-validate.js",
735
+ "default": "./services/chain-service/health-check/utils/new-utils/chain-asset-validate.js"
736
+ },
737
+ "./services/chain-service/health-check/utils/new-utils/chain-validate": {
738
+ "types": "./services/chain-service/health-check/utils/new-utils/chain-validate.d.ts",
739
+ "require": "./cjs/services/chain-service/health-check/utils/new-utils/chain-validate.js",
740
+ "default": "./services/chain-service/health-check/utils/new-utils/chain-validate.js"
741
+ },
722
742
  "./services/chain-service/health-check/utils/provider": {
723
743
  "types": "./services/chain-service/health-check/utils/provider.d.ts",
724
744
  "require": "./cjs/services/chain-service/health-check/utils/provider.js",
@@ -1973,11 +1993,11 @@
1973
1993
  "@reduxjs/toolkit": "^1.9.1",
1974
1994
  "@sora-substrate/type-definitions": "^1.17.7",
1975
1995
  "@substrate/connect": "^0.8.9",
1976
- "@subwallet/chain-list": "0.2.73",
1977
- "@subwallet/extension-base": "^1.2.14-0",
1978
- "@subwallet/extension-chains": "^1.2.14-0",
1979
- "@subwallet/extension-dapp": "^1.2.14-0",
1980
- "@subwallet/extension-inject": "^1.2.14-0",
1996
+ "@subwallet/chain-list": "0.2.74",
1997
+ "@subwallet/extension-base": "^1.2.15-0",
1998
+ "@subwallet/extension-chains": "^1.2.15-0",
1999
+ "@subwallet/extension-dapp": "^1.2.15-0",
2000
+ "@subwallet/extension-inject": "^1.2.15-0",
1981
2001
  "@subwallet/keyring": "^0.1.5",
1982
2002
  "@subwallet/ui-keyring": "^0.1.5",
1983
2003
  "@walletconnect/keyvaluestorage": "^1.1.1",
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.2.14-0'
10
+ version: '1.2.15-0'
11
11
  };
@@ -32,6 +32,7 @@ export declare const _NFT_CHAIN_GROUP: {
32
32
  statemine: string[];
33
33
  statemint: string[];
34
34
  unique_network: string[];
35
+ unique_evm: string[];
35
36
  bitcountry: string[];
36
37
  vara: string[];
37
38
  };
@@ -48,6 +48,7 @@ export const _NFT_CHAIN_GROUP = {
48
48
  statemine: ['statemine'],
49
49
  statemint: ['statemint'],
50
50
  unique_network: ['unique_network', 'quartz', 'opal'],
51
+ unique_evm: ['unique_evm'],
51
52
  bitcountry: ['bitcountry', 'pioneer', 'continuum_network'],
52
53
  vara: ['vara_network']
53
54
  };
@@ -4,11 +4,11 @@
4
4
  import BigN from 'bignumber.js';
5
5
  export const chainProvider = {
6
6
  default: 0,
7
- ethereum: 1,
7
+ ethereum: 0,
8
8
  polygon: 2,
9
- shidenEvm: 2,
10
- shiden: 2,
11
- ajunaPolkadot: 1,
9
+ shidenEvm: 1,
10
+ shiden: 1,
11
+ ajunaPolkadot: 0,
12
12
  crabParachain: 1,
13
13
  astarEvm: 1,
14
14
  shibuya: 1,
@@ -12,3 +12,4 @@ export declare const getPsp22AssetInfo: (asset: _ChainAsset, api: ApiPromise) =>
12
12
  export declare const getEvmNativeInfo: (api: _EvmApi) => Promise<AssetSpec>;
13
13
  export declare const getErc20AssetInfo: (asset: _ChainAsset, api: _EvmApi) => Promise<AssetSpec>;
14
14
  export declare const compareAsset: (assetInfo: AssetSpec, asset: _ChainAsset, errors: string[]) => void;
15
+ export declare const validateAsset: (onchainAsset: AssetSpec, chainlistAsset: _ChainAsset) => boolean;