@subwallet/extension-base 1.3.66-0 → 1.3.68-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 (81) hide show
  1. package/background/KoniTypes.d.ts +12 -1
  2. package/cjs/constants/environment.js +1 -3
  3. package/cjs/constants/index.js +4 -1
  4. package/cjs/core/substrate/system-pallet.js +4 -0
  5. package/cjs/core/substrate/xcm-parser.js +0 -176
  6. package/cjs/koni/api/nft/rari/index.js +1 -1
  7. package/cjs/koni/background/cron.js +16 -0
  8. package/cjs/koni/background/handlers/Extension.js +166 -90
  9. package/cjs/koni/background/handlers/State.js +25 -0
  10. package/cjs/packageInfo.js +1 -1
  11. package/cjs/services/balance-service/helpers/group.js +31 -2
  12. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +51 -13
  13. package/cjs/services/balance-service/helpers/subscribe/substrate/utils.js +69 -0
  14. package/cjs/services/balance-service/index.js +36 -11
  15. package/cjs/services/balance-service/transfer/smart-contract.js +56 -23
  16. package/cjs/services/balance-service/transfer/xcm/index.js +30 -44
  17. package/cjs/services/balance-service/transfer/xcm/utils.js +53 -18
  18. package/cjs/services/chain-service/constants.js +8 -46
  19. package/cjs/services/chain-service/handler/EvmChainHandler.js +6 -3
  20. package/cjs/services/earning-service/handlers/base.js +7 -1
  21. package/cjs/services/nft-service/index.js +173 -0
  22. package/cjs/services/swap-service/handler/base-handler.js +18 -21
  23. package/cjs/services/transaction-service/index.js +1 -1
  24. package/cjs/types/balance/index.js +26 -1
  25. package/cjs/utils/fee/transfer.js +5 -2
  26. package/cjs/utils/index.js +25 -2
  27. package/cjs/utils/setup-api-sdk.js +0 -5
  28. package/constants/environment.d.ts +0 -1
  29. package/constants/environment.js +0 -1
  30. package/constants/index.d.ts +1 -0
  31. package/constants/index.js +1 -0
  32. package/core/substrate/system-pallet.d.ts +1 -0
  33. package/core/substrate/system-pallet.js +3 -0
  34. package/core/substrate/types.d.ts +14 -0
  35. package/core/substrate/xcm-parser.d.ts +1 -49
  36. package/core/substrate/xcm-parser.js +1 -173
  37. package/koni/api/nft/rari/index.js +1 -1
  38. package/koni/background/cron.d.ts +1 -0
  39. package/koni/background/cron.js +17 -1
  40. package/koni/background/handlers/Extension.d.ts +3 -0
  41. package/koni/background/handlers/Extension.js +88 -14
  42. package/koni/background/handlers/State.d.ts +4 -0
  43. package/koni/background/handlers/State.js +25 -0
  44. package/package.json +16 -21
  45. package/packageInfo.js +1 -1
  46. package/services/balance-service/helpers/group.js +31 -2
  47. package/services/balance-service/helpers/subscribe/substrate/index.js +51 -13
  48. package/services/balance-service/helpers/subscribe/substrate/utils.d.ts +7 -0
  49. package/services/balance-service/helpers/subscribe/substrate/utils.js +58 -0
  50. package/services/balance-service/index.d.ts +4 -2
  51. package/services/balance-service/index.js +26 -6
  52. package/services/balance-service/transfer/smart-contract.d.ts +4 -0
  53. package/services/balance-service/transfer/smart-contract.js +54 -23
  54. package/services/balance-service/transfer/xcm/index.d.ts +2 -2
  55. package/services/balance-service/transfer/xcm/index.js +18 -32
  56. package/services/balance-service/transfer/xcm/utils.d.ts +1 -2
  57. package/services/balance-service/transfer/xcm/utils.js +51 -15
  58. package/services/chain-service/constants.d.ts +5 -24
  59. package/services/chain-service/constants.js +6 -35
  60. package/services/chain-service/handler/EvmChainHandler.js +6 -3
  61. package/services/earning-service/handlers/base.js +7 -1
  62. package/services/nft-service/index.d.ts +9 -0
  63. package/services/nft-service/index.js +165 -0
  64. package/services/swap-service/handler/base-handler.d.ts +0 -1
  65. package/services/swap-service/handler/base-handler.js +19 -22
  66. package/services/transaction-service/index.js +1 -1
  67. package/services/transaction-service/types.d.ts +2 -1
  68. package/types/balance/index.d.ts +14 -0
  69. package/types/balance/index.js +21 -1
  70. package/utils/fee/transfer.js +6 -3
  71. package/utils/index.js +25 -2
  72. package/utils/setup-api-sdk.js +1 -6
  73. package/cjs/services/balance-service/transfer/xcm/polkadotXcm.js +0 -30
  74. package/cjs/services/balance-service/transfer/xcm/xTokens.js +0 -32
  75. package/cjs/services/balance-service/transfer/xcm/xcmPallet.js +0 -23
  76. package/services/balance-service/transfer/xcm/polkadotXcm.d.ts +0 -3
  77. package/services/balance-service/transfer/xcm/polkadotXcm.js +0 -24
  78. package/services/balance-service/transfer/xcm/xTokens.d.ts +0 -3
  79. package/services/balance-service/transfer/xcm/xTokens.js +0 -26
  80. package/services/balance-service/transfer/xcm/xcmPallet.d.ts +0 -3
  81. package/services/balance-service/transfer/xcm/xcmPallet.js +0 -17
@@ -306,21 +306,6 @@ class SwapBaseHandler {
306
306
  txData: txData
307
307
  };
308
308
  }
309
- async validateSetFeeTokenStep(params, stepIndex) {
310
- if (!params.selectedQuote) {
311
- return Promise.resolve([new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)]);
312
- }
313
- const feeInfo = params.process.totalFee[stepIndex];
314
- const feeAmount = feeInfo.feeComponent[0];
315
- const feeTokenInfo = this.chainService.getAssetBySlug(feeInfo.defaultFeeToken);
316
- const feeTokenBalance = await this.balanceService.getTransferableBalance(params.address, feeTokenInfo.originChain, feeTokenInfo.slug);
317
- const bnFeeTokenBalance = new _bignumber.default(feeTokenBalance.value);
318
- const bnFeeAmount = new _bignumber.default(feeAmount.amount);
319
- if (bnFeeAmount.gte(bnFeeTokenBalance)) {
320
- return Promise.resolve([new _TransactionError.TransactionError(_types.BasicTxErrorType.NOT_ENOUGH_BALANCE)]);
321
- }
322
- return [];
323
- }
324
309
  async validateBridgeStep(request) {
325
310
  const {
326
311
  bnBridgeAmount,
@@ -385,7 +370,7 @@ class SwapBaseHandler {
385
370
  const xcmRequest = {
386
371
  originTokenInfo: fromToken,
387
372
  destinationTokenInfo: toToken,
388
- sendingValue: bnBridgeAmount.toString(),
373
+ sendingValue: bnBridgeAmount.toFixed(),
389
374
  recipient: receiver,
390
375
  substrateApi: substrateApi,
391
376
  sender: sender,
@@ -393,11 +378,23 @@ class SwapBaseHandler {
393
378
  originChain: fromChain,
394
379
  feeInfo
395
380
  };
396
- const isDryRunSuccess = await (0, _xcm.dryRunXcmExtrinsicV2)(xcmRequest);
397
-
398
- // temp skip dry-run for later step todo: wait for dry-run-predict
399
- if (isFirstBridge && !isDryRunSuccess) {
400
- return [new _TransactionError.TransactionError(_types.BasicTxErrorType.UNABLE_TO_SEND, 'Unable to perform transaction. Select another token or destination chain and try again')];
381
+ if (isFirstBridge) {
382
+ const isDryRunSuccess = await (0, _xcm.dryRunXcmExtrinsicV2)(xcmRequest, false);
383
+ if (!isDryRunSuccess) {
384
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.UNABLE_TO_SEND, 'Swap amount too small. Increase amount and try again')];
385
+ }
386
+ } else {
387
+ const isDryRunPreviewSuccess = await (0, _xcm.dryRunXcmExtrinsicV2)(xcmRequest, true);
388
+ const originFee = await (0, _xcm.getXcmOriginFee)(xcmRequest);
389
+ if (originFee) {
390
+ const isBridgeTokenNativeBalanceEnough = bnFeeTokenBalance.gte(originFee);
391
+ if (!isBridgeTokenNativeBalanceEnough) {
392
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.UNABLE_TO_SEND, 'Swap amount too small. Increase amount and try again')];
393
+ }
394
+ }
395
+ if (!isDryRunPreviewSuccess) {
396
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.UNABLE_TO_SEND, 'Swap amount too small. Increase amount and try again')];
397
+ }
401
398
  }
402
399
  }
403
400
  return [];
@@ -134,7 +134,7 @@ class TransactionService {
134
134
  // Check account signing transaction
135
135
 
136
136
  (0, _transfer.checkSigningAccountForTransaction)(validationResponse, chainInfoMap);
137
- const nativeTokenAvailable = await this.state.balanceService.getTransferableBalance(address, chain, nativeTokenInfo.slug, extrinsicType);
137
+ const nativeTokenAvailable = await this.state.balanceService.getBalanceByType(address, chain, nativeTokenInfo.slug, transactionInput.balanceType, extrinsicType);
138
138
 
139
139
  // Check available balance against transaction fee
140
140
  (0, _transfer.checkBalanceWithTransactionFee)(validationResponse, transactionInput, nativeTokenInfo, nativeTokenAvailable);
@@ -1 +1,26 @@
1
- "use strict";
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.BalanceType = void 0;
7
+ // Copyright 2019-2022 @subwallet/extension-koni-ui authors & contributors
8
+ // SPDX-License-Identifier: Apache-2.0
9
+ let BalanceType;
10
+ /**
11
+ * Balance info of a token on an address
12
+ * @property {string} address - Address
13
+ * @property {string} tokenSlug - Slug of token
14
+ * @property {APIItemState} state - State of information
15
+ * @property {number} [timestamp] - Time to get information
16
+ * @property {string} free - Transferable balance
17
+ * @property {string} locked - Locked balance, cannot be transferred, locked here is only meaningful in the context of token transfer
18
+ * @property {metadata} [metadata] - Could be anything, supposed to be generic to handle various contexts
19
+ */
20
+ exports.BalanceType = BalanceType;
21
+ (function (BalanceType) {
22
+ BalanceType["TRANSFERABLE"] = "transferable";
23
+ BalanceType["TOTAL"] = "total";
24
+ BalanceType["TOTAL_MINUS_RESERVED"] = "totalMinusReserved";
25
+ BalanceType["KEEP_ALIVE"] = "keepAlive";
26
+ })(BalanceType || (exports.BalanceType = BalanceType = {}));
@@ -202,9 +202,13 @@ const calculateTransferMaxTransferable = async (id, request, freeBalance, fee) =
202
202
  var _tx$gas;
203
203
  // Calculate fee for evm transaction
204
204
  const tx = transaction;
205
- const gasLimit = ((_tx$gas = tx.gas) === null || _tx$gas === void 0 ? void 0 : _tx$gas.toString()) || (await evmApi.api.eth.estimateGas(tx)).toString();
205
+ let gasLimit = ((_tx$gas = tx.gas) === null || _tx$gas === void 0 ? void 0 : _tx$gas.toString()) || (await evmApi.api.eth.estimateGas(tx)).toString();
206
206
  const _feeCustom = feeCustom;
207
207
  const combineFee = (0, _combine.combineEthFee)(fee, feeOption, _feeCustom);
208
+ if (srcChain.slug === 'energy_web_chain') {
209
+ gasLimit = _smartContract.gasSettingsForEWC.gasLimit.toString();
210
+ combineFee.maxFeePerGas = _smartContract.gasSettingsForEWC.maxFeePerGas;
211
+ }
208
212
  if (combineFee.maxFeePerGas) {
209
213
  estimatedFee = new _bignumber.default(combineFee.maxFeePerGas).multipliedBy(gasLimit).toFixed(0);
210
214
  } else {
@@ -396,7 +400,6 @@ const calculateXcmMaxTransferable = async (id, request, freeBalance, fee) => {
396
400
  funcCreateExtrinsic = _xcm.createAvailBridgeExtrinsicFromAvail;
397
401
  } else {
398
402
  funcCreateExtrinsic = _xcm.createXcmExtrinsicV2;
399
- params.sendingValue = '1';
400
403
  }
401
404
  const extrinsic = await funcCreateExtrinsic(params);
402
405
 
@@ -632,13 +632,36 @@ const stripUrl = url => {
632
632
  };
633
633
  exports.stripUrl = stripUrl;
634
634
  const baseParseIPFSUrl = (input, customDomain) => {
635
- const selectedDomain = customDomain || (0, _config.getRandomIpfsGateway)();
636
635
  if (!input || input.length === 0) {
637
636
  return undefined;
638
637
  }
639
- if (isUrl(input)) {
638
+
639
+ // Case 1: Return as-is for inline data URLs (e.g. base64-encoded images)
640
+ if (input.startsWith('data:')) {
640
641
  return input;
641
642
  }
643
+ const selectedDomain = customDomain || (0, _config.getRandomIpfsGateway)();
644
+
645
+ // Case 2: Replace Pinata private gateways with a public IPFS gateway
646
+ // ==== EX: https://ikzttp.mypinata.cloud/ipfs/QmYDvPAXtiJg7s8JdRBSLWdgSphQdac8j1YuQNNxcGE1hg/9586.png
647
+ // Case 2b: Blockscout IPFS debug gateway -> rewrite to public gateway
648
+ // ==== EX: http://ipfs-debug.node.blockscout.com/ipfs/QmX2qHy1o27KgmHJSG2wKj2qLiv1gMCJCTn4nxzEVtTdgF
649
+ // Case 2c: http://ipfs.node.blockscout.com/ipfs/QmeTETrnJcG3iowfT3tXtz2jKmyeYbeag3AeYfDk5pBjGg
650
+
651
+ const privateGatewayPattern = /https?:\/\/([^/]*pinata\.cloud|[^/]*\.node\.blockscout\.com)\/ipfs\//;
652
+ if (privateGatewayPattern.test(input)) {
653
+ return input.replace(privateGatewayPattern, selectedDomain);
654
+ }
655
+
656
+ // Case 3: Handle NFT.storage subdomain links (e.g. https://<cid>.ipfs.nftstorage.link/...)
657
+ // Always redirect to selectedDomain to avoid SSL version/cipher mismatch errors
658
+ // ==== EX: https://bafybeias6as7k66hkghst3w4jwk6x5dkfk56oglqh44x6jmok6n7kcvg7m.ipfs.nftstorage.link/0.gif?ext=gif
659
+ const nftStorageMatch = input.match(/^https?:\/\/([a-zA-Z0-9]+)\.ipfs\.nftstorage\.link\/(.*)$/);
660
+ if (nftStorageMatch) {
661
+ const cid = nftStorageMatch[1];
662
+ const pathAndQuery = nftStorageMatch[2] || '';
663
+ return `${selectedDomain}${cid}/${pathAndQuery}`;
664
+ }
642
665
  if (isUrl(input) || input.includes('https://') || input.includes('http')) {
643
666
  return input;
644
667
  }
@@ -19,9 +19,4 @@ function setupApiSDK() {
19
19
  platform: _environment.TARGET_ENV,
20
20
  chainListVersion: CHAIN_LIST_VERSION
21
21
  });
22
-
23
- // Custom the price history API with other different base URL
24
- _subwalletServicesSdk.default.priceHistoryApi.updateConfig({
25
- baseUrl: _constants.BACKEND_PRICE_HISTORY_URL
26
- });
27
22
  }
@@ -1,5 +1,4 @@
1
1
  export declare const APP_VERSION: string;
2
2
  export declare const isProductionMode: boolean;
3
3
  export declare const BACKEND_API_URL: string;
4
- export declare const BACKEND_PRICE_HISTORY_URL: string;
5
4
  export declare const SW_EXTERNAL_SERVICES_API: string;
@@ -6,5 +6,4 @@ const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
6
6
  export const APP_VERSION = process.env.PKG_VERSION || '';
7
7
  export const isProductionMode = PRODUCTION_BRANCHES.indexOf(branchName) > -1;
8
8
  export const BACKEND_API_URL = process.env.SUBWALLET_API || (isProductionMode ? 'https://sw-services.subwallet.app/api' : 'https://be-dev.subwallet.app/api');
9
- export const BACKEND_PRICE_HISTORY_URL = process.env.SUBWALLET_PRICE_HISTORY_API || (isProductionMode ? 'https://price-history.subwallet.app/api' : 'https://price-history-dev.subwallet.app/api');
10
9
  export const SW_EXTERNAL_SERVICES_API = process.env.SW_EXTERNAL_SERVICES_API || (isProductionMode ? 'https://external-services.subwallet.app' : 'https://external-services-dev.subwallet.app');
@@ -15,6 +15,7 @@ export declare const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL = 90000;
15
15
  export declare const CRON_REFRESH_HISTORY_INTERVAL = 900000;
16
16
  export declare const CRON_GET_API_MAP_STATUS = 10000;
17
17
  export declare const CRON_REFRESH_CHAIN_STAKING_METADATA = 90000;
18
+ export declare const CRON_NFT_DETECT_INTERVAL = 7500000;
18
19
  export declare const CRON_REFRESH_CHAIN_NOMINATOR_METADATA = 1800000;
19
20
  export declare const CRON_RECOVER_HISTORY_INTERVAL = 30000;
20
21
  export declare const CRON_SYNC_MANTA_PAY = 300000;
@@ -17,6 +17,7 @@ export const CRON_REFRESH_STAKING_REWARD_FAST_INTERVAL = 90000;
17
17
  export const CRON_REFRESH_HISTORY_INTERVAL = 900000;
18
18
  export const CRON_GET_API_MAP_STATUS = 10000;
19
19
  export const CRON_REFRESH_CHAIN_STAKING_METADATA = 90000;
20
+ export const CRON_NFT_DETECT_INTERVAL = 7500000;
20
21
  export const CRON_REFRESH_CHAIN_NOMINATOR_METADATA = 1800000;
21
22
  export const CRON_RECOVER_HISTORY_INTERVAL = 30000;
22
23
  export const CRON_SYNC_MANTA_PAY = 300000;
@@ -5,3 +5,4 @@ export declare function _canAccountBeReaped(accountInfo: FrameSystemAccountInfo)
5
5
  export declare function _isAccountActive(accountInfo: FrameSystemAccountInfo): boolean;
6
6
  export declare function _getSystemPalletTotalBalance(accountInfo: FrameSystemAccountInfo): bigint;
7
7
  export declare function _getAppliedExistentialDepositWithExtrinsicType(accountInfo: FrameSystemAccountInfo, existentialDeposit: string, extrinsicType?: ExtrinsicType): bigint;
8
+ export declare function _getSystemPalletReservedBalance(accountInfo: FrameSystemAccountInfo): bigint;
@@ -64,4 +64,7 @@ function _getSystemPalletTransferableV1(accountInfo, existentialDeposit, strictM
64
64
  }
65
65
  function _getSystemPalletTotalBalanceV1(accountInfo) {
66
66
  return BigInt(accountInfo.data.free) + BigInt(accountInfo.data.reserved);
67
+ }
68
+ export function _getSystemPalletReservedBalance(accountInfo) {
69
+ return BigInt(accountInfo.data.reserved);
67
70
  }
@@ -18,6 +18,20 @@ export declare type FrameSystemAccountInfoV1 = {
18
18
  feeFrozen: number;
19
19
  };
20
20
  };
21
+ export interface FrameBalancesLocksInfo {
22
+ id: string | Record<string, unknown>;
23
+ amount: string | number | bigint;
24
+ reasons?: string;
25
+ }
26
+ export interface FrameBalancesHoldsInfo {
27
+ id: string | Record<string, unknown>;
28
+ amount: string | number | bigint;
29
+ reason?: string;
30
+ }
31
+ export interface FrameBalancesFreezesInfo {
32
+ id: string | Record<string, unknown>;
33
+ amount: string;
34
+ }
21
35
  export declare type FrameSystemAccountInfo = FrameSystemAccountInfoV1 | FrameSystemAccountInfoV2;
22
36
  export declare type OrmlTokensAccountData = {
23
37
  free: number;
@@ -1,52 +1,4 @@
1
- import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
- import { _Address } from '@subwallet/extension-base/background/KoniTypes';
3
- export declare function _getXcmDestWeight(originChainInfo: _ChainInfo): "Unlimited" | 5000000000;
4
- export declare function _getXcmBeneficiary(destChainInfo: _ChainInfo, recipient: _Address, version: number): {
5
- [x: string]: {
6
- parents: number;
7
- interior: {
8
- X1: {
9
- AccountId32: {
10
- network: string | undefined;
11
- id: Uint8Array;
12
- };
13
- AccountKey20?: undefined;
14
- } | {
15
- AccountKey20: {
16
- network: string | undefined;
17
- key: string;
18
- };
19
- AccountId32?: undefined;
20
- } | ({
21
- AccountId32: {
22
- network: string | undefined;
23
- id: Uint8Array;
24
- };
25
- AccountKey20?: undefined;
26
- } | {
27
- AccountKey20: {
28
- network: string | undefined;
29
- key: string;
30
- };
31
- AccountId32?: undefined;
32
- })[];
33
- };
34
- };
35
- };
36
- export declare function _getXcmMultiAssets(tokenInfo: _ChainAsset, value: string, version: number): {
37
- [x: string]: {
38
- id: Record<string, any>;
39
- fun: {
40
- Fungible: string;
41
- };
42
- }[];
43
- };
44
- export declare function _getXcmMultiLocation(originChainInfo: _ChainInfo, destChainInfo: _ChainInfo, version: number, recipient?: _Address): {
45
- [x: string]: {
46
- parents: number;
47
- interior: unknown;
48
- };
49
- };
1
+ import { _ChainInfo } from '@subwallet/chain-list/types';
50
2
  export declare function _isXcmTransferUnstable(originChainInfo: _ChainInfo, destChainInfo: _ChainInfo, assetSlug: string): boolean;
51
3
  export declare function _getXcmUnstableWarning(originChainInfo: _ChainInfo, destChainInfo: _ChainInfo, assetSlug: string): string;
52
4
  export declare function _isXcmWithinSameConsensus(originChainInfo: _ChainInfo, destChainInfo: _ChainInfo): boolean;
@@ -6,50 +6,7 @@ import { _isAcrossChainBridge } from '@subwallet/extension-base/services/balance
6
6
  import { isAvailChainBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/availBridge';
7
7
  import { _isPolygonChainBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/polygonBridge';
8
8
  import { _isPosChainBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/posBridge';
9
- import { _getChainSubstrateAddressPrefix, _getEvmChainId, _getSubstrateParaId, _getSubstrateRelayParent, _getXcmAssetMultilocation, _isChainEvmCompatible, _isPureEvmChain, _isSubstrateParaChain } from '@subwallet/extension-base/services/chain-service/utils';
10
- import { decodeAddress, evmToAddress } from '@polkadot/util-crypto';
11
- const FOUR_INSTRUCTIONS_WEIGHT = 5000000000;
12
- const UNLIMITED_WEIGHT = 'Unlimited';
13
- export function _getXcmDestWeight(originChainInfo) {
14
- if (['pioneer'].includes(originChainInfo.slug)) {
15
- return FOUR_INSTRUCTIONS_WEIGHT;
16
- }
17
- return UNLIMITED_WEIGHT;
18
- }
19
- export function _getXcmBeneficiary(destChainInfo, recipient, version) {
20
- const receiverLocation = version < 4 // from V4, X1 is also an array
21
- ? _getRecipientLocation(destChainInfo, recipient, version) : [_getRecipientLocation(destChainInfo, recipient, version)];
22
- return {
23
- [`V${version}`]: {
24
- parents: 0,
25
- interior: {
26
- X1: receiverLocation
27
- }
28
- }
29
- };
30
- }
31
- export function _getXcmMultiAssets(tokenInfo, value, version) {
32
- const assetId = _getAssetIdentifier(tokenInfo, version);
33
- return {
34
- [`V${version}`]: [{
35
- id: assetId,
36
- fun: {
37
- Fungible: value
38
- }
39
- }]
40
- };
41
- }
42
- export function _getXcmMultiLocation(originChainInfo, destChainInfo, version, recipient) {
43
- const isWithinSameConsensus = _isXcmWithinSameConsensus(originChainInfo, destChainInfo);
44
- const parents = _getMultiLocationParent(originChainInfo, isWithinSameConsensus);
45
- const interior = _getMultiLocationInterior(destChainInfo, isWithinSameConsensus, version, recipient);
46
- return {
47
- [`V${version}`]: {
48
- parents,
49
- interior
50
- }
51
- };
52
- }
9
+ import { _getSubstrateRelayParent, _isPureEvmChain } from '@subwallet/extension-base/services/chain-service/utils';
53
10
  export function _isXcmTransferUnstable(originChainInfo, destChainInfo, assetSlug) {
54
11
  return !_isXcmWithinSameConsensus(originChainInfo, destChainInfo) || _isMythosFromHydrationToMythos(originChainInfo, destChainInfo, assetSlug) || _isPolygonBridgeXcm(originChainInfo, destChainInfo) || _isPosBridgeXcm(originChainInfo, destChainInfo);
55
12
  }
@@ -133,123 +90,6 @@ export function _isAcrossBridgeXcm(originChainInfo, destChainInfo) {
133
90
  }
134
91
  // ---------------------------------------------------------------------------------------------------------------------
135
92
 
136
- function _getMultiLocationParent(originChainInfo, isWithinSameConsensus) {
137
- let parent = 0; // how many hops up the hierarchy
138
-
139
- if (_isSubstrateParaChain(originChainInfo)) {
140
- parent += 1;
141
- }
142
- if (!isWithinSameConsensus) {
143
- parent += 1;
144
- }
145
- return parent;
146
- }
147
- function _getMultiLocationInterior(destChainInfo, isWithinSameConsensus, version, recipient) {
148
- const junctions = [];
149
- if (isWithinSameConsensus) {
150
- if (_isSubstrateParaChain(destChainInfo)) {
151
- junctions.push({
152
- Parachain: _getSubstrateParaId(destChainInfo)
153
- });
154
- }
155
- } else {
156
- junctions.push({
157
- GlobalConsensus: _getGlobalConsensusJunction(destChainInfo, version)
158
- });
159
- if (_isSubstrateParaChain(destChainInfo)) {
160
- junctions.push({
161
- Parachain: _getSubstrateParaId(destChainInfo)
162
- });
163
- }
164
- }
165
- if (recipient) {
166
- junctions.push(_getRecipientLocation(destChainInfo, recipient, version));
167
- }
168
- if (junctions.length === 0 && !recipient) {
169
- return 'Here';
170
- }
171
- if (version < 4 && junctions.length === 1) {
172
- return {
173
- X1: junctions[0]
174
- };
175
- }
176
- return {
177
- [`X${junctions.length}`]: junctions
178
- };
179
- }
180
- function _getGlobalConsensusJunction(destChainInfo, version) {
181
- let chainSlug = destChainInfo.slug;
182
- let evmChainId;
183
- if (_isSubstrateParaChain(destChainInfo)) {
184
- const relaySlug = _getSubstrateRelayParent(destChainInfo);
185
- if (!relaySlug) {
186
- throw Error('Parachain must have a parent chainSlug');
187
- }
188
- chainSlug = relaySlug;
189
- } else {
190
- evmChainId = _getEvmChainId(destChainInfo);
191
- }
192
- if (evmChainId) {
193
- return {
194
- Ethereum: {
195
- chainId: evmChainId
196
- }
197
- };
198
- }
199
- switch (chainSlug) {
200
- case COMMON_CHAIN_SLUGS.POLKADOT:
201
- return version < 4 ? {
202
- Polkadot: null
203
- } : 'Polkadot';
204
- case COMMON_CHAIN_SLUGS.KUSAMA:
205
- return version < 4 ? {
206
- Kusama: null
207
- } : 'Kusama';
208
- default:
209
- return version < 4 ? {
210
- Rococo: null
211
- } : 'Rococo';
212
- }
213
- }
214
- function _getRecipientLocation(destChainInfo, recipient, version) {
215
- const network = _getNetworkByVersion(version);
216
- if (destChainInfo.slug === COMMON_CHAIN_SLUGS.ASTAR_EVM) {
217
- const ss58Address = evmToAddress(recipient, _getChainSubstrateAddressPrefix(destChainInfo)); // TODO: shouldn't pass addressPrefix directly
218
-
219
- return {
220
- AccountId32: {
221
- network,
222
- id: decodeAddress(ss58Address)
223
- }
224
- };
225
- }
226
- if (_isChainEvmCompatible(destChainInfo)) {
227
- return {
228
- AccountKey20: {
229
- network,
230
- key: recipient
231
- }
232
- };
233
- }
234
- return {
235
- AccountId32: {
236
- network,
237
- id: decodeAddress(recipient)
238
- }
239
- };
240
- }
241
- function _getAssetIdentifier(tokenInfo, version) {
242
- const _assetIdentifier = _getXcmAssetMultilocation(tokenInfo);
243
- if (!_assetIdentifier) {
244
- throw new Error('Asset must have multilocation');
245
- }
246
- const assetIdentifier = ['statemint-LOCAL-KSM', 'statemine-LOCAL-DOT'].includes(tokenInfo.slug) // todo: hotfix for ksm statemint recheck all chain
247
- ? _assetIdentifier : _adaptX1Interior(_assetIdentifier, version);
248
- return version >= 4 // from V4, Concrete is removed
249
- ? assetIdentifier : {
250
- Concrete: assetIdentifier
251
- };
252
- }
253
93
  export function _adaptX1Interior(_assetIdentifier, version) {
254
94
  const assetIdentifier = structuredClone(_assetIdentifier);
255
95
  const interior = assetIdentifier.interior;
@@ -262,16 +102,4 @@ export function _adaptX1Interior(_assetIdentifier, version) {
262
102
  interior.X1 = interior.X1[0];
263
103
  }
264
104
  return assetIdentifier;
265
- }
266
- function _getNetworkByVersion(version) {
267
- switch (version) {
268
- case 1:
269
- case 2:
270
- return 'Any';
271
- case 3:
272
- case 4:
273
- return undefined;
274
- default:
275
- return undefined;
276
- }
277
105
  }
@@ -6,7 +6,7 @@ const options = {
6
6
  method: 'GET',
7
7
  headers: {
8
8
  accept: 'application/json',
9
- 'X-API-KEY': 'ed9df6bf-7eba-4ca2-8a42-9006706be064'
9
+ 'X-API-KEY': 'e5c3b30b-f241-47f6-88b7-7859837ff17c'
10
10
  }
11
11
  };
12
12
  export class RariNftApi extends BaseNftApi {
@@ -29,6 +29,7 @@ export declare class KoniCron {
29
29
  refreshNft: (address: string, apiMap: ApiMap, smartContractNfts: _ChainAsset[], chainInfoMap: Record<string, _ChainInfo>) => () => void;
30
30
  resetNft: (newAddress: string) => void;
31
31
  checkNetworkAvailable: (serviceInfo: ServiceInfo) => boolean;
32
+ detectEvmCollectionNft: (address: string) => () => void;
32
33
  reloadNft(): Promise<boolean>;
33
34
  reloadStaking(): Promise<boolean>;
34
35
  private needUpdateNft;
@@ -1,7 +1,7 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-koni authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { CRON_REFRESH_CHAIN_STAKING_METADATA, CRON_REFRESH_MKT_CAMPAIGN_INTERVAL, CRON_REFRESH_NFT_INTERVAL, CRON_SYNC_MANTA_PAY } from '@subwallet/extension-base/constants';
4
+ import { CRON_NFT_DETECT_INTERVAL, CRON_REFRESH_CHAIN_STAKING_METADATA, CRON_REFRESH_MKT_CAMPAIGN_INTERVAL, CRON_REFRESH_NFT_INTERVAL, CRON_SYNC_MANTA_PAY } from '@subwallet/extension-base/constants';
5
5
  import { _isChainSupportEvmNft, _isChainSupportNativeNft, _isChainSupportWasmNft } from '@subwallet/extension-base/services/chain-service/utils';
6
6
  import { waitTimeout } from '@subwallet/extension-base/utils';
7
7
  import { Subject } from 'rxjs';
@@ -88,6 +88,7 @@ export class KoniCron {
88
88
  // NFT
89
89
  (commonReload || needUpdateNft) && this.resetNft(address);
90
90
  (commonReload || needUpdateNft) && this.removeCron('refreshNft');
91
+ (commonReload || needUpdateNft) && this.removeCron('detectNft');
91
92
  commonReload && this.removeCron('refreshPoolingStakingReward');
92
93
  if (mktCampaignNeedReload) {
93
94
  this.removeCron('fetchMktCampaignData');
@@ -103,6 +104,7 @@ export class KoniCron {
103
104
  if (this.checkNetworkAvailable(serviceInfo)) {
104
105
  // only add cron jobs if there's at least 1 active network
105
106
  (commonReload || needUpdateNft) && this.addCron('refreshNft', this.refreshNft(address, serviceInfo.chainApiMap, this.state.getSmartContractNfts(), this.state.getActiveChainInfoMap()), CRON_REFRESH_NFT_INTERVAL);
107
+ (commonReload || needUpdateNft) && this.addCron('detectNft', this.detectEvmCollectionNft(address), CRON_NFT_DETECT_INTERVAL);
106
108
  reloadMantaPay && this.addCron('syncMantaPay', this.syncMantaPay, CRON_SYNC_MANTA_PAY);
107
109
  }
108
110
  };
@@ -115,6 +117,7 @@ export class KoniCron {
115
117
  if (Object.keys(this.state.getSubstrateApiMap()).length !== 0 || Object.keys(this.state.getEvmApiMap()).length !== 0) {
116
118
  this.resetNft(currentAccountInfo.proxyId);
117
119
  this.addCron('refreshNft', this.refreshNft(currentAccountInfo.proxyId, this.state.getApiMap(), this.state.getSmartContractNfts(), this.state.getActiveChainInfoMap()), CRON_REFRESH_NFT_INTERVAL);
120
+ this.addCron('detectNft', this.detectEvmCollectionNft(currentAccountInfo.proxyId), CRON_NFT_DETECT_INTERVAL);
118
121
  // this.addCron('refreshStakingReward', this.refreshStakingReward(currentAccountInfo.address), CRON_REFRESH_STAKING_REWARD_INTERVAL);
119
122
  this.addCron('syncMantaPay', this.syncMantaPay, CRON_SYNC_MANTA_PAY);
120
123
  }
@@ -164,12 +167,25 @@ export class KoniCron {
164
167
  checkNetworkAvailable = serviceInfo => {
165
168
  return Object.keys(serviceInfo.chainApiMap.substrate).length > 0 || Object.keys(serviceInfo.chainApiMap.evm).length > 0;
166
169
  };
170
+ detectEvmCollectionNft = address => {
171
+ return () => {
172
+ let addresses = [];
173
+ addresses = this.state.keyringService.context.getDecodedAddresses();
174
+ if (!addresses.length) {
175
+ console.warn('[Cron] No decoded addresses found for ALL_ACCOUNT_KEY');
176
+ return;
177
+ }
178
+ this.state.nftDetectionService.fetchEvmCollectionsWithPreview(addresses).catch(err => console.warn(`[Cron] NFT detection failed for ${address}:`, err));
179
+ };
180
+ };
167
181
  async reloadNft() {
168
182
  const address = this.state.keyringService.context.currentAccount.proxyId;
169
183
  const serviceInfo = this.state.getServiceInfo();
170
184
  this.resetNft(address);
171
185
  this.removeCron('refreshNft');
186
+ this.removeCron('detectNft');
172
187
  this.addCron('refreshNft', this.refreshNft(address, serviceInfo.chainApiMap, this.state.getSmartContractNfts(), this.state.getActiveChainInfoMap()), CRON_REFRESH_NFT_INTERVAL);
188
+ this.addCron('detectNft', this.detectEvmCollectionNft(address), CRON_NFT_DETECT_INTERVAL);
173
189
  await waitTimeout(1800);
174
190
  return true;
175
191
  }
@@ -116,6 +116,7 @@ export default class KoniExtension {
116
116
  private subscribeNftCollection;
117
117
  private getNft;
118
118
  private subscribeNft;
119
+ private handleGetNftFullList;
119
120
  private getStakingReward;
120
121
  private subscribeStakingReward;
121
122
  private getStaking;
@@ -145,10 +146,12 @@ export default class KoniExtension {
145
146
  private deleteCustomAsset;
146
147
  private validateCustomAsset;
147
148
  private getAddressTransferableBalance;
149
+ private getAddressAvailableBalanceByType;
148
150
  private getAddressTotalBalance;
149
151
  private subscribeMaxTransferable;
150
152
  private subscribeTransferableWhenConfirmation;
151
153
  private subscribeAddressTransferableBalance;
154
+ private subscribeAddressAvailableBalanceByType;
152
155
  private substrateNftSubmitTransaction;
153
156
  private enableChains;
154
157
  private accountsCreateExternalV2;