@subwallet/extension-base 1.3.79-1 → 1.3.80-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 (48) hide show
  1. package/background/KoniTypes.d.ts +13 -3
  2. package/cjs/core/substrate/system-pallet.js +3 -0
  3. package/cjs/koni/api/nft/index.js +0 -14
  4. package/cjs/koni/background/cron.js +0 -17
  5. package/cjs/koni/background/handlers/Extension.js +6 -5
  6. package/cjs/koni/background/handlers/State.js +24 -6
  7. package/cjs/packageInfo.js +1 -1
  8. package/cjs/services/balance-service/helpers/process.js +49 -21
  9. package/cjs/services/balance-service/index.js +2 -2
  10. package/cjs/services/chain-service/constants.js +6 -2
  11. package/cjs/services/earning-service/handlers/special.js +3 -2
  12. package/cjs/services/nft-service/index.js +219 -150
  13. package/cjs/services/nft-service/multi-chain-nft-fetcher.js +145 -0
  14. package/cjs/services/nft-service/nft-handlers/base-nft-handler.js +28 -0
  15. package/cjs/services/nft-service/nft-handlers/evm/evm-nft-handler.js +179 -0
  16. package/cjs/services/nft-service/nft-handlers/registry.js +37 -0
  17. package/cjs/services/nft-service/nft-handlers/unique/unique-nft-handler.js +187 -0
  18. package/cjs/services/storage-service/DatabaseService.js +1 -1
  19. package/core/substrate/system-pallet.js +3 -0
  20. package/koni/api/nft/index.js +1 -15
  21. package/koni/background/cron.d.ts +0 -1
  22. package/koni/background/cron.js +1 -18
  23. package/koni/background/handlers/Extension.d.ts +1 -0
  24. package/koni/background/handlers/Extension.js +6 -5
  25. package/koni/background/handlers/State.d.ts +8 -2
  26. package/koni/background/handlers/State.js +24 -6
  27. package/package.json +31 -6
  28. package/packageInfo.js +1 -1
  29. package/services/balance-service/helpers/process.d.ts +1 -1
  30. package/services/balance-service/helpers/process.js +48 -21
  31. package/services/balance-service/index.js +2 -2
  32. package/services/chain-service/constants.d.ts +3 -0
  33. package/services/chain-service/constants.js +3 -0
  34. package/services/earning-service/handlers/special.js +4 -3
  35. package/services/nft-service/index.d.ts +42 -6
  36. package/services/nft-service/index.js +219 -151
  37. package/services/nft-service/multi-chain-nft-fetcher.d.ts +13 -0
  38. package/services/nft-service/multi-chain-nft-fetcher.js +138 -0
  39. package/services/nft-service/nft-handlers/base-nft-handler.d.ts +13 -0
  40. package/services/nft-service/nft-handlers/base-nft-handler.js +21 -0
  41. package/services/nft-service/nft-handlers/evm/evm-nft-handler.d.ts +9 -0
  42. package/services/nft-service/nft-handlers/evm/evm-nft-handler.js +171 -0
  43. package/services/nft-service/nft-handlers/registry.d.ts +11 -0
  44. package/services/nft-service/nft-handlers/registry.js +29 -0
  45. package/services/nft-service/nft-handlers/unique/unique-nft-handler.d.ts +12 -0
  46. package/services/nft-service/nft-handlers/unique/unique-nft-handler.js +177 -0
  47. package/services/storage-service/DatabaseService.d.ts +1 -1
  48. package/services/storage-service/DatabaseService.js +1 -1
@@ -204,6 +204,11 @@ export interface NftItem extends NftItemExtraInfo {
204
204
  rarity?: string;
205
205
  description?: string;
206
206
  properties?: Record<any, any> | null;
207
+ isBundle?: boolean;
208
+ nestingLevel?: number;
209
+ nestingTokens?: NftItem[];
210
+ parent?: NftItem;
211
+ parentId?: string;
207
212
  }
208
213
  interface NftItemExtraInfo {
209
214
  type?: _AssetType.ERC721 | _AssetType.PSP34 | RMRK_VER;
@@ -817,9 +822,15 @@ export interface NftTransactionRequest extends BaseRequestSign {
817
822
  nftItem: NftItem;
818
823
  }
819
824
  export interface NftFullListRequest {
820
- contractAddress: string;
825
+ collectionId: string;
821
826
  owners: string[];
822
827
  chainInfo: _ChainInfo;
828
+ tokenIds?: string[];
829
+ }
830
+ export interface NftDetailRequest {
831
+ collectionId: string;
832
+ chainSlug: string;
833
+ tokenId: string;
823
834
  }
824
835
  export interface EvmNftTransaction extends ValidateTransactionResponse {
825
836
  tx: Record<string, any> | null;
@@ -1875,11 +1886,10 @@ export interface KoniRequestSignatures {
1875
1886
  'pri(evmNft.getTransaction)': [NftTransactionRequest, EvmNftTransaction];
1876
1887
  'pri(substrateNft.submitTransaction)': [NftTransactionRequest, SWTransactionResponse];
1877
1888
  'pri(substrateNft.getTransaction)': [NftTransactionRequest, SubstrateNftTransaction];
1878
- 'pri(nft.getNft)': [null, NftJson];
1879
1889
  'pri(nft.getSubscription)': [RequestSubscribeNft, NftJson, NftJson];
1880
- 'pri(nftCollection.getNftCollection)': [null, NftCollectionJson];
1881
1890
  'pri(nftCollection.getSubscription)': [null, NftCollection[], NftCollection[]];
1882
1891
  'pri(nft.getFullList)': [NftFullListRequest, boolean];
1892
+ 'pri(nft.getNftdetail)': [NftDetailRequest, NftItem];
1883
1893
  'pri(staking.getStaking)': [null, StakingJson];
1884
1894
  'pri(staking.getSubscription)': [RequestSubscribeStaking, StakingJson, StakingJson];
1885
1895
  'pri(stakingReward.getStakingReward)': [null, StakingRewardJson];
@@ -54,6 +54,9 @@ function _getAppliedExistentialDeposit(accountInfo, existentialDeposit, strictMo
54
54
  if (strictMode) {
55
55
  return bnExistentialDeposit;
56
56
  }
57
+ if (accountInfo.data.free.toString() === existentialDeposit) {
58
+ return BigInt(0);
59
+ }
57
60
  return _canAccountBeReaped(accountInfo) ? BigInt(0) : bnExistentialDeposit; // account for ED here will go better with max transfer logic
58
61
  }
59
62
  function _getSystemPalletTransferableV2(accountInfo, existentialDeposit, strictMode) {
@@ -40,8 +40,6 @@ function createSubstrateNftApi(chain, substrateApi, addresses) {
40
40
  return [new _assethub_unique.default(substrateApi, substrateAddresses, chain), new _assethub_nft.default(substrateApi, substrateAddresses, chain)];
41
41
  } else if (_constants._NFT_CHAIN_GROUP.statemint.includes(chain)) {
42
42
  return [new _assethub_unique.default(substrateApi, substrateAddresses, chain), new _assethub_nft.default(substrateApi, substrateAddresses, chain)];
43
- } else if (_constants._NFT_CHAIN_GROUP.unique_network.includes(chain)) {
44
- return [new _unique_network_nft.UniqueNftApi(chain, substrateAddresses)];
45
43
  } else if (_constants._NFT_CHAIN_GROUP.unique_evm.includes(chain)) {
46
44
  return [new _unique_network_nft.UniqueNftApi(chain, evmAddresses)];
47
45
  } else if (_constants._NFT_CHAIN_GROUP.bitcountry.includes(chain)) {
@@ -63,10 +61,6 @@ function createWasmNftApi(chain, apiProps, addresses) {
63
61
  const substrateAddresses = (0, _utils2.getAddressesByChainType)(addresses, [_KoniTypes.ChainType.SUBSTRATE]);
64
62
  return new _wasm_nft.WasmNftApi(apiProps, substrateAddresses, chain);
65
63
  }
66
- function createWeb3NftApi(chain, evmApi, addresses) {
67
- const evmAddresses = (0, _utils2.getAddressesByChainType)(addresses, [_KoniTypes.ChainType.EVM]);
68
- return new _evm_nft.EvmNftApi(evmApi, evmAddresses, chain);
69
- }
70
64
  const createOrdinalApi = (chain, subscanChain, addresses) => {
71
65
  return new _ordinal_nft.default(addresses, chain, subscanChain);
72
66
  };
@@ -136,14 +130,6 @@ class NftHandler {
136
130
  }
137
131
  }
138
132
  }
139
- if ((0, _utils._isChainSupportEvmNft)(chainInfo)) {
140
- if (this.evmApiMap[chain]) {
141
- const handler = createWeb3NftApi(chain, this.evmApiMap[chain], evmAddresses);
142
- if (handler) {
143
- this.handlers.push(handler);
144
- }
145
- }
146
- }
147
133
  if (chain === 'unique_evm') {
148
134
  const handlers = createSubstrateNftApi(chain, null, evmAddresses);
149
135
  if (handlers && !!handlers.length) {
@@ -98,7 +98,6 @@ class KoniCron {
98
98
  // NFT
99
99
  (commonReload || needUpdateNft) && this.resetNft(address);
100
100
  (commonReload || needUpdateNft) && this.removeCron('refreshNft');
101
- (commonReload || needUpdateNft) && this.removeCron('detectNft');
102
101
  commonReload && this.removeCron('refreshPoolingStakingReward');
103
102
  if (mktCampaignNeedReload) {
104
103
  this.removeCron('fetchMktCampaignData');
@@ -114,7 +113,6 @@ class KoniCron {
114
113
  if (this.checkNetworkAvailable(serviceInfo)) {
115
114
  // only add cron jobs if there's at least 1 active network
116
115
  (commonReload || needUpdateNft) && this.addCron('refreshNft', this.refreshNft(address, serviceInfo.chainApiMap, this.state.getSmartContractNfts(), this.state.getActiveChainInfoMap()), _constants.CRON_REFRESH_NFT_INTERVAL);
117
- (commonReload || needUpdateNft) && this.addCron('detectNft', this.detectEvmCollectionNft(address), _constants.CRON_NFT_DETECT_INTERVAL);
118
116
  reloadMantaPay && this.addCron('syncMantaPay', this.syncMantaPay, _constants.CRON_SYNC_MANTA_PAY);
119
117
  }
120
118
  };
@@ -127,8 +125,6 @@ class KoniCron {
127
125
  if (Object.keys(this.state.getSubstrateApiMap()).length !== 0 || Object.keys(this.state.getEvmApiMap()).length !== 0) {
128
126
  this.resetNft(currentAccountInfo.proxyId);
129
127
  this.addCron('refreshNft', this.refreshNft(currentAccountInfo.proxyId, this.state.getApiMap(), this.state.getSmartContractNfts(), this.state.getActiveChainInfoMap()), _constants.CRON_REFRESH_NFT_INTERVAL);
130
- this.addCron('detectNft', this.detectEvmCollectionNft(currentAccountInfo.proxyId), _constants.CRON_NFT_DETECT_INTERVAL);
131
- // this.addCron('refreshStakingReward', this.refreshStakingReward(currentAccountInfo.address), CRON_REFRESH_STAKING_REWARD_INTERVAL);
132
128
  this.addCron('syncMantaPay', this.syncMantaPay, _constants.CRON_SYNC_MANTA_PAY);
133
129
  }
134
130
  this.status = 'running';
@@ -177,25 +173,12 @@ class KoniCron {
177
173
  checkNetworkAvailable = serviceInfo => {
178
174
  return Object.keys(serviceInfo.chainApiMap.substrate).length > 0 || Object.keys(serviceInfo.chainApiMap.evm).length > 0;
179
175
  };
180
- detectEvmCollectionNft = address => {
181
- return () => {
182
- let addresses = [];
183
- addresses = this.state.keyringService.context.getDecodedAddresses();
184
- if (!addresses.length) {
185
- console.warn('[Cron] No decoded addresses found for ALL_ACCOUNT_KEY');
186
- return;
187
- }
188
- this.state.nftDetectionService.fetchEvmCollectionsWithPreview(addresses).catch(err => console.warn(`[Cron] NFT detection failed for ${address}:`, err));
189
- };
190
- };
191
176
  async reloadNft() {
192
177
  const address = this.state.keyringService.context.currentAccount.proxyId;
193
178
  const serviceInfo = this.state.getServiceInfo();
194
179
  this.resetNft(address);
195
180
  this.removeCron('refreshNft');
196
- this.removeCron('detectNft');
197
181
  this.addCron('refreshNft', this.refreshNft(address, serviceInfo.chainApiMap, this.state.getSmartContractNfts(), this.state.getActiveChainInfoMap()), _constants.CRON_REFRESH_NFT_INTERVAL);
198
- this.addCron('detectNft', this.detectEvmCollectionNft(address), _constants.CRON_NFT_DETECT_INTERVAL);
199
182
  await (0, _utils2.waitTimeout)(1800);
200
183
  return true;
201
184
  }
@@ -1198,7 +1198,10 @@ class KoniExtension {
1198
1198
  return this.getNft();
1199
1199
  }
1200
1200
  async handleGetNftFullList(request) {
1201
- return this.#koniState.nftDetectionService.getFullNftInstancesByCollection(request);
1201
+ return this.#koniState.nftService.fetchFullListNftOfACollection(request);
1202
+ }
1203
+ async handleGetNftDetail(request) {
1204
+ return this.#koniState.nftService.fetchNftDetail(request);
1202
1205
  }
1203
1206
  getStakingReward() {
1204
1207
  return new Promise((resolve, reject) => {
@@ -5758,16 +5761,14 @@ class KoniExtension {
5758
5761
  return this.getCrowdloanContributions(request);
5759
5762
  case 'pri(crowdloan.getSubscription)':
5760
5763
  return this.subscribeCrowdloan(id, port);
5761
- case 'pri(nft.getNft)':
5762
- return await this.getNft();
5763
5764
  case 'pri(nft.getSubscription)':
5764
5765
  return await this.subscribeNft(id, port);
5765
- case 'pri(nftCollection.getNftCollection)':
5766
- return await this.getNftCollection();
5767
5766
  case 'pri(nftCollection.getSubscription)':
5768
5767
  return await this.subscribeNftCollection(id, port);
5769
5768
  case 'pri(nft.getFullList)':
5770
5769
  return await this.handleGetNftFullList(request);
5770
+ case 'pri(nft.getNftdetail)':
5771
+ return await this.handleGetNftDetail(request);
5771
5772
  case 'pri(staking.getStaking)':
5772
5773
  return this.getStaking();
5773
5774
  case 'pri(staking.getSubscription)':
@@ -33,7 +33,7 @@ var _migrationService = _interopRequireDefault(require("@subwallet/extension-bas
33
33
  var _mintCampaignService = _interopRequireDefault(require("@subwallet/extension-base/services/mint-campaign-service"));
34
34
  var _mktCampaignService = _interopRequireDefault(require("@subwallet/extension-base/services/mkt-campaign-service"));
35
35
  var _multisigService = require("@subwallet/extension-base/services/multisig-service");
36
- var _nftService = _interopRequireDefault(require("@subwallet/extension-base/services/nft-service"));
36
+ var _nftService = require("@subwallet/extension-base/services/nft-service");
37
37
  var _NotificationService = _interopRequireDefault(require("@subwallet/extension-base/services/notification-service/NotificationService"));
38
38
  var _openGov = _interopRequireDefault(require("@subwallet/extension-base/services/open-gov"));
39
39
  var _priceService = require("@subwallet/extension-base/services/price-service");
@@ -86,6 +86,12 @@ class KoniState {
86
86
  externalRequest = {};
87
87
  crowdloanMap = generateDefaultCrowdloanMap();
88
88
  crowdloanSubject = new _rxjs.Subject();
89
+
90
+ /**
91
+ * TODO: Remove this subject once NFT migration to the service layer is completed.
92
+ * The state manager should not handle the internal state of the NFT service.
93
+ * The NFT service will manage its own state independently.
94
+ */
89
95
  nftSubject = new _rxjs.Subject();
90
96
  mantaPayConfigSubject = new _rxjs.Subject();
91
97
  isMantaPayEnabled = false;
@@ -123,13 +129,13 @@ class KoniState {
123
129
  this.requestService = new _requestService.default(this.chainService, this.settingService, this.keyringService, this.transactionService);
124
130
  this.priceService = new _priceService.PriceService(this.dbService, this.eventService, this.chainService);
125
131
  this.balanceService = new _balanceService.BalanceService(this);
132
+ this.nftService = new _nftService.NftService(this);
126
133
  this.historyService = new _historyService.HistoryService(this.dbService, this.chainService, this.eventService, this.keyringService, this.subscanService);
127
134
  this.mintCampaignService = new _mintCampaignService.default(this);
128
135
  this.walletConnectService = new _walletConnectService.default(this, this.requestService);
129
136
  this.migrationService = new _migrationService.default(this, this.eventService);
130
137
  this.campaignService = new _campaignService.default(this);
131
138
  this.mktCampaignService = new _mktCampaignService.default(this);
132
- this.nftDetectionService = new _nftService.default(this);
133
139
  this.buyService = new _buyService.default(this);
134
140
  this.earningService = new _service.default(this);
135
141
  this.swapService = new _swapService.SwapService(this);
@@ -241,6 +247,7 @@ class KoniState {
241
247
  this.mktCampaignService.init();
242
248
  this.eventService.emit('chain.ready', true);
243
249
  await this.balanceService.init();
250
+ await this.nftService.init();
244
251
  await this.earningService.init();
245
252
  await this.swapService.init();
246
253
  await this.inappNotificationService.init();
@@ -398,6 +405,7 @@ class KoniState {
398
405
  return this.dbService.getAllNftCollection(this.activeChainSlugs);
399
406
  }
400
407
  subscribeNftCollection() {
408
+ // TODO: Move this logic to the NFT service once migration is complete.
401
409
  const getChains = () => this.activeChainSlugs;
402
410
  return this.dbService.stores.nftCollection.subscribeNftCollection(getChains);
403
411
  }
@@ -1799,7 +1807,7 @@ class KoniState {
1799
1807
  this.campaignService.stop();
1800
1808
  await Promise.all([this.cron.stop(), this.subscription.stop()]);
1801
1809
  await this.pauseAllNetworks(undefined, 'IDLE mode');
1802
- await Promise.all([this.historyService.stop(), this.priceService.stop(), this.balanceService.stop(), this.earningService.stop(), this.swapService.stop(), this.inappNotificationService.stop(), this.openGovService.stop(), this.multisigService.stop()]);
1810
+ await Promise.all([this.historyService.stop(), this.priceService.stop(), this.balanceService.stop(), this.nftService.stop(), this.earningService.stop(), this.swapService.stop(), this.inappNotificationService.stop(), this.openGovService.stop(), this.multisigService.stop()]);
1803
1811
 
1804
1812
  // Complete sleeping
1805
1813
  sleeping.resolve();
@@ -1855,7 +1863,7 @@ class KoniState {
1855
1863
  this.generalStatus = _types.ServiceStatus.STARTING_FULL;
1856
1864
  const startingFull = (0, _promise.createPromiseHandler)();
1857
1865
  this.waitStartingFull = startingFull.promise;
1858
- await Promise.all([this.cron.start(), this.subscription.start(), this.historyService.start(), this.priceService.start(), this.balanceService.start(), this.earningService.start(), this.swapService.start(), this.inappNotificationService.start(), this.openGovService.start(), this.multisigService.start()]);
1866
+ await Promise.all([this.cron.start(), this.subscription.start(), this.historyService.start(), this.priceService.start(), this.balanceService.start(), this.nftService.start(), this.earningService.start(), this.swapService.start(), this.inappNotificationService.start(), this.openGovService.start(), this.multisigService.start()]);
1859
1867
  this.eventService.emit('general.start_full', true);
1860
1868
  this.waitStartingFull = null;
1861
1869
  this.generalStatus = _types.ServiceStatus.STARTED_FULL;
@@ -1917,9 +1925,19 @@ class KoniState {
1917
1925
  });
1918
1926
  }
1919
1927
  async reloadNft() {
1920
- const currentAddress = this.keyringService.context.currentAccount.proxyId;
1928
+ const currentProxyId = this.keyringService.context.currentAccount.proxyId;
1929
+ const currentAddress = this.keyringService.context.addressesByProxyId(currentProxyId);
1921
1930
  await this.dbService.removeNftsByAddress(currentAddress);
1922
- return await this.cron.reloadNft();
1931
+ await this.cron.reloadNft();
1932
+ await this.reloadNftV2();
1933
+ return true;
1934
+ }
1935
+ async reloadNftV2() {
1936
+ // TODO: Recheck: Uncomment this block when migration is complete
1937
+ // const currentAddress = this.keyringService.context.currentAccount.proxyId;
1938
+ //
1939
+ // await this.dbService.removeNftsByAddress(currentAddress);
1940
+ await this.nftService.forceReload();
1923
1941
  }
1924
1942
  async reloadStaking() {
1925
1943
  await this.earningService.reloadEarning(true);
@@ -13,6 +13,6 @@ const packageInfo = {
13
13
  name: '@subwallet/extension-base',
14
14
  path: typeof __dirname === 'string' ? __dirname : 'auto',
15
15
  type: 'cjs',
16
- version: '1.3.79-1'
16
+ version: '1.3.80-0'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
@@ -7,7 +8,11 @@ exports.getAcrossbridgeTransferProcessFromEvm = getAcrossbridgeTransferProcessFr
7
8
  exports.getDefaultTransferProcess = getDefaultTransferProcess;
8
9
  exports.getSnowbridgeTransferProcessFromEvm = getSnowbridgeTransferProcessFromEvm;
9
10
  var _chainList = require("@subwallet/chain-list");
11
+ var _web = require("@subwallet/extension-base/koni/api/contract-handler/evm/web3");
12
+ var _utils = require("@subwallet/extension-base/koni/api/contract-handler/utils");
13
+ var _utils2 = require("@subwallet/extension-base/services/chain-service/utils");
10
14
  var _serviceBase = require("@subwallet/extension-base/types/service-base");
15
+ var _bignumber = _interopRequireDefault(require("bignumber.js"));
11
16
  // Copyright 2019-2022 @subwallet/extension-base
12
17
  // SPDX-License-Identifier: Apache-2.0
13
18
 
@@ -30,18 +35,25 @@ async function getSnowbridgeTransferProcessFromEvm(address, evmApi, tokenInfo, a
30
35
  totalFee: [_serviceBase.MOCK_STEP_FEE],
31
36
  steps: [_serviceBase.DEFAULT_FIRST_STEP]
32
37
  };
33
- // const allowance = await getERC20Allowance(getSnowBridgeGatewayContract(evmApi.chainSlug), address, _getContractAddressOfToken(tokenInfo), evmApi);
34
-
35
- result.steps.push({
36
- // always approve spending because sometimes allowance check fails
37
- id: result.steps.length,
38
- type: _serviceBase.CommonStepType.TOKEN_APPROVAL,
39
- name: 'Approve spending'
40
- });
41
- result.totalFee.push(_serviceBase.MOCK_STEP_FEE);
42
- // if (!allowance || BigInt(allowance) < BigInt(amount)) {
43
- // }
44
-
38
+ try {
39
+ const allowance = await (0, _web.getERC20Allowance)((0, _utils.getSnowBridgeGatewayContract)(evmApi.chainSlug), address, (0, _utils2._getContractAddressOfToken)(tokenInfo), evmApi);
40
+ if (!allowance || new _bignumber.default(allowance).lt(amount)) {
41
+ result.steps.push({
42
+ id: result.steps.length,
43
+ type: _serviceBase.CommonStepType.TOKEN_APPROVAL,
44
+ name: 'Approve spending'
45
+ });
46
+ result.totalFee.push(_serviceBase.MOCK_STEP_FEE);
47
+ }
48
+ } catch (e) {
49
+ console.error(e);
50
+ result.steps.push({
51
+ id: result.steps.length,
52
+ type: _serviceBase.CommonStepType.TOKEN_APPROVAL,
53
+ name: 'Approve spending'
54
+ });
55
+ result.totalFee.push(_serviceBase.MOCK_STEP_FEE);
56
+ }
45
57
  result.steps.push({
46
58
  id: result.steps.length,
47
59
  type: _serviceBase.CommonStepType.TRANSFER,
@@ -50,20 +62,36 @@ async function getSnowbridgeTransferProcessFromEvm(address, evmApi, tokenInfo, a
50
62
  result.totalFee.push(_serviceBase.MOCK_STEP_FEE);
51
63
  return Promise.resolve(result);
52
64
  }
53
- async function getAcrossbridgeTransferProcessFromEvm(SpokePoolAddress) {
65
+ async function getAcrossbridgeTransferProcessFromEvm(SpokePoolAddress, address, tokenInfo, evmApi, amount) {
54
66
  const result = {
55
67
  totalFee: [_serviceBase.MOCK_STEP_FEE],
56
68
  steps: [_serviceBase.DEFAULT_FIRST_STEP]
57
69
  };
58
- result.steps.push({
59
- id: result.steps.length,
60
- type: _serviceBase.CommonStepType.TOKEN_APPROVAL,
61
- name: 'Approve spending',
62
- metadata: {
63
- SpokePoolAddress
70
+ try {
71
+ const allowance = await (0, _web.getERC20Allowance)(SpokePoolAddress, address, (0, _utils2._getContractAddressOfToken)(tokenInfo), evmApi);
72
+ if (!allowance || new _bignumber.default(allowance).lt(amount)) {
73
+ result.steps.push({
74
+ id: result.steps.length,
75
+ type: _serviceBase.CommonStepType.TOKEN_APPROVAL,
76
+ name: 'Approve spending',
77
+ metadata: {
78
+ SpokePoolAddress
79
+ }
80
+ });
81
+ result.totalFee.push(_serviceBase.MOCK_STEP_FEE);
64
82
  }
65
- });
66
- result.totalFee.push(_serviceBase.MOCK_STEP_FEE);
83
+ } catch (e) {
84
+ console.error(e);
85
+ result.steps.push({
86
+ id: result.steps.length,
87
+ type: _serviceBase.CommonStepType.TOKEN_APPROVAL,
88
+ name: 'Approve spending',
89
+ metadata: {
90
+ SpokePoolAddress
91
+ }
92
+ });
93
+ result.totalFee.push(_serviceBase.MOCK_STEP_FEE);
94
+ }
67
95
  result.steps.push({
68
96
  id: result.steps.length,
69
97
  type: _serviceBase.CommonStepType.TRANSFER,
@@ -627,10 +627,10 @@ class BalanceService {
627
627
  return (0, _process.getDefaultTransferProcess)();
628
628
  }
629
629
  const destChainInfo = this.state.chainService.getChainInfoByKey(params.destChain);
630
+ const evmApi = this.state.chainService.getEvmApi(originChainInfo.slug);
630
631
 
631
632
  // xcm
632
633
  if (!(0, _xcmParser._isXcmWithinSameConsensus)(originChainInfo, destChainInfo) && (0, _utils._isPureEvmChain)(originChainInfo)) {
633
- const evmApi = this.state.chainService.getEvmApi(originChainInfo.slug);
634
634
  const tokenInfo = this.state.chainService.getAssetBySlug(params.tokenSlug);
635
635
  return (0, _process.getSnowbridgeTransferProcessFromEvm)(params.address, evmApi, tokenInfo, params.amount);
636
636
  }
@@ -658,7 +658,7 @@ class BalanceService {
658
658
  if (!data) {
659
659
  throw new Error('Failed to fetch Across Bridge Data. Please try again later');
660
660
  }
661
- return (0, _process.getAcrossbridgeTransferProcessFromEvm)(data.to);
661
+ return (0, _process.getAcrossbridgeTransferProcessFromEvm)(data.to, params.address, originTokenInfo, evmApi, params.amount);
662
662
  }
663
663
  }
664
664
  return (0, _process.getDefaultTransferProcess)();
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports._ZK_ASSET_PREFIX = exports._TRANSFER_CHAIN_GROUP = exports._SUBSTRATE_DEFAULT_INFLATION_PARAMS = exports._STAKING_ERA_LENGTH_MAP = exports._PURE_EVM_CHAINS = exports._PREDEFINED_SINGLE_MODES = exports._PARACHAIN_INFLATION_DISTRIBUTION = exports._NFT_CHAIN_GROUP = exports._MANTA_ZK_CHAIN_GROUP = exports._KNOWN_CHAIN_INFLATION_PARAMS = exports._GOVERNANCE_CHAIN_GROUP = exports._EXPECTED_BLOCK_TIME = exports._DEFAULT_MANTA_ZK_CHAIN = exports._DEFAULT_ACTIVE_CHAINS = exports._BTC_SERVICE_TOKEN = exports._BITCOIN_TESTNET_NAME = exports._BITCOIN_TESTNET_CHAIN_SLUG = exports._BITCOIN_NAME = exports._BITCOIN_CHAIN_SLUG = exports._BALANCE_LOCKED_ID_GROUP = exports._BALANCE_CHAIN_GROUP = exports._API_OPTIONS_CHAIN_GROUP = exports.USE_MULTILOCATION_INDEX = exports.LATEST_CHAIN_DATA_FETCHING_INTERVAL = exports.EVM_REFORMAT_DECIMALS = exports.EVM_PASS_CONNECT_STATUS = exports.API_CONNECT_TIMEOUT = exports.API_AUTO_CONNECT_MS = void 0;
6
+ exports._ZK_ASSET_PREFIX = exports._TRANSFER_CHAIN_GROUP = exports._SUBSTRATE_DEFAULT_INFLATION_PARAMS = exports._STAKING_ERA_LENGTH_MAP = exports._PURE_EVM_CHAINS = exports._PREDEFINED_SINGLE_MODES = exports._PARACHAIN_INFLATION_DISTRIBUTION = exports._NFT_CHAIN_GROUP = exports._MANTA_ZK_CHAIN_GROUP = exports._KNOWN_CHAIN_INFLATION_PARAMS = exports._GOVERNANCE_CHAIN_GROUP = exports._EXPECTED_BLOCK_TIME = exports._DEFAULT_MANTA_ZK_CHAIN = exports._DEFAULT_ACTIVE_CHAINS = exports._BTC_SERVICE_TOKEN = exports._BITCOIN_TESTNET_NAME = exports._BITCOIN_TESTNET_CHAIN_SLUG = exports._BITCOIN_NAME = exports._BITCOIN_CHAIN_SLUG = exports._BALANCE_LOCKED_ID_GROUP = exports._BALANCE_CHAIN_GROUP = exports._API_OPTIONS_CHAIN_GROUP = exports.USE_MULTILOCATION_INDEX = exports.NFT_CHAIN_GROUPS_MIGRATED = exports.LATEST_CHAIN_DATA_FETCHING_INTERVAL = exports.EVM_REFORMAT_DECIMALS = exports.EVM_PASS_CONNECT_STATUS = exports.API_CONNECT_TIMEOUT = exports.API_AUTO_CONNECT_MS = void 0;
7
7
  var _chainList = require("@subwallet/chain-list");
8
8
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
9
9
  // Copyright 2019-2022 @subwallet/extension-base
@@ -80,9 +80,13 @@ const _NFT_CHAIN_GROUP = {
80
80
  rari: ['rari'],
81
81
  story_odyssey: ['storyOdyssey', 'storyOdyssey_testnet']
82
82
  };
83
+ exports._NFT_CHAIN_GROUP = _NFT_CHAIN_GROUP;
84
+ const NFT_CHAIN_GROUPS_MIGRATED = {
85
+ unique_network: ['unique_network']
86
+ };
83
87
 
84
88
  // Staking--------------------------------------------------------------------------------------------------------------
85
- exports._NFT_CHAIN_GROUP = _NFT_CHAIN_GROUP;
89
+ exports.NFT_CHAIN_GROUPS_MIGRATED = NFT_CHAIN_GROUPS_MIGRATED;
86
90
  const _STAKING_ERA_LENGTH_MAP = {
87
91
  // in hours
88
92
  alephTest: 24,
@@ -473,6 +473,7 @@ class BaseSpecialStakingPoolHandler extends _base.default {
473
473
  const originChainInfo = this.state.getChainInfo(originTokenInfo.originChain);
474
474
  const originTokenSlug = (0, _utils3._getChainNativeTokenSlug)(originChainInfo);
475
475
  const substrateApi = this.state.getSubstrateApi(originChainInfo.slug);
476
+ const fromAddress = (0, _utils4._reformatAddressWithChain)(address, originChainInfo);
476
477
  const id = (0, _getId.getId)();
477
478
  const feeInfo = await this.state.feeService.subscribeChainFee(id, originChainInfo.slug, 'substrate');
478
479
  const xcmRequest = {
@@ -481,7 +482,7 @@ class BaseSpecialStakingPoolHandler extends _base.default {
481
482
  recipient: address,
482
483
  sendingValue,
483
484
  substrateApi,
484
- sender: address,
485
+ sender: fromAddress,
485
486
  originChain: originChainInfo,
486
487
  destinationChain: this.chainInfo,
487
488
  feeInfo
@@ -493,7 +494,7 @@ class BaseSpecialStakingPoolHandler extends _base.default {
493
494
  const xcmData = {
494
495
  originNetworkKey: originChainInfo.slug,
495
496
  destinationNetworkKey: destinationTokenInfo.originChain,
496
- from: address,
497
+ from: fromAddress,
497
498
  to: address,
498
499
  value: sendingValue,
499
500
  tokenSlug: originTokenSlug,