@subwallet/extension-base 1.3.67-0 → 1.3.68-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/background/KoniTypes.d.ts +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/koni/api/nft/rari/index.js +1 -1
  6. package/cjs/koni/background/cron.js +16 -0
  7. package/cjs/koni/background/handlers/Extension.js +165 -89
  8. package/cjs/koni/background/handlers/State.js +25 -0
  9. package/cjs/packageInfo.js +1 -1
  10. package/cjs/services/balance-service/helpers/group.js +31 -2
  11. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +51 -13
  12. package/cjs/services/balance-service/helpers/subscribe/substrate/utils.js +69 -0
  13. package/cjs/services/balance-service/index.js +36 -11
  14. package/cjs/services/balance-service/transfer/smart-contract.js +2 -0
  15. package/cjs/services/chain-service/constants.js +8 -46
  16. package/cjs/services/chain-service/handler/EvmChainHandler.js +6 -3
  17. package/cjs/services/earning-service/handlers/base.js +7 -1
  18. package/cjs/services/nft-service/index.js +173 -0
  19. package/cjs/services/transaction-service/index.js +1 -1
  20. package/cjs/types/balance/index.js +26 -1
  21. package/cjs/utils/index.js +25 -2
  22. package/cjs/utils/setup-api-sdk.js +0 -5
  23. package/constants/environment.d.ts +0 -1
  24. package/constants/environment.js +0 -1
  25. package/constants/index.d.ts +1 -0
  26. package/constants/index.js +1 -0
  27. package/core/substrate/system-pallet.d.ts +1 -0
  28. package/core/substrate/system-pallet.js +3 -0
  29. package/core/substrate/types.d.ts +14 -0
  30. package/koni/api/nft/rari/index.js +1 -1
  31. package/koni/background/cron.d.ts +1 -0
  32. package/koni/background/cron.js +17 -1
  33. package/koni/background/handlers/Extension.d.ts +3 -0
  34. package/koni/background/handlers/Extension.js +87 -13
  35. package/koni/background/handlers/State.d.ts +4 -0
  36. package/koni/background/handlers/State.js +25 -0
  37. package/package.json +16 -6
  38. package/packageInfo.js +1 -1
  39. package/services/balance-service/helpers/group.js +31 -2
  40. package/services/balance-service/helpers/subscribe/substrate/index.js +51 -13
  41. package/services/balance-service/helpers/subscribe/substrate/utils.d.ts +7 -0
  42. package/services/balance-service/helpers/subscribe/substrate/utils.js +58 -0
  43. package/services/balance-service/index.d.ts +4 -2
  44. package/services/balance-service/index.js +26 -6
  45. package/services/balance-service/transfer/smart-contract.js +2 -0
  46. package/services/chain-service/constants.d.ts +5 -24
  47. package/services/chain-service/constants.js +6 -35
  48. package/services/chain-service/handler/EvmChainHandler.js +6 -3
  49. package/services/earning-service/handlers/base.js +7 -1
  50. package/services/nft-service/index.d.ts +9 -0
  51. package/services/nft-service/index.js +165 -0
  52. package/services/transaction-service/index.js +1 -1
  53. package/services/transaction-service/types.d.ts +2 -1
  54. package/types/balance/index.d.ts +14 -0
  55. package/types/balance/index.js +21 -1
  56. package/utils/index.js +25 -2
  57. package/utils/setup-api-sdk.js +1 -6
@@ -28,6 +28,7 @@ import { KeyringService } from '@subwallet/extension-base/services/keyring-servi
28
28
  import MigrationService from '@subwallet/extension-base/services/migration-service';
29
29
  import MintCampaignService from '@subwallet/extension-base/services/mint-campaign-service';
30
30
  import MktCampaignService from '@subwallet/extension-base/services/mkt-campaign-service';
31
+ import NftService from '@subwallet/extension-base/services/nft-service';
31
32
  import NotificationService from '@subwallet/extension-base/services/notification-service/NotificationService';
32
33
  import { PriceService } from '@subwallet/extension-base/services/price-service';
33
34
  import RequestService from '@subwallet/extension-base/services/request-service';
@@ -112,6 +113,7 @@ export default class KoniState {
112
113
  this.migrationService = new MigrationService(this, this.eventService);
113
114
  this.campaignService = new CampaignService(this);
114
115
  this.mktCampaignService = new MktCampaignService(this);
116
+ this.nftDetectionService = new NftService(this);
115
117
  this.buyService = new BuyService(this);
116
118
  this.earningService = new EarningService(this);
117
119
  this.swapService = new SwapService(this);
@@ -393,6 +395,29 @@ export default class KoniState {
393
395
  deleteNftCollection(chain, collectionId) {
394
396
  return this.dbService.deleteNftCollection(chain, collectionId);
395
397
  }
398
+ async handleDetectedNfts(address, nftItems) {
399
+ try {
400
+ const chainSlugs = this.activeChainSlugs;
401
+ const currentNfts = await this.dbService.getNft([address], chainSlugs);
402
+ const newNfts = nftItems.filter(n => !currentNfts.some(c => c.id === n.id));
403
+ for (const nft of newNfts) {
404
+ this.updateNftData(nft.chain, nft, address);
405
+ }
406
+ } catch (e) {
407
+ this.logger.warn('handleDetectedNfts error:', e);
408
+ }
409
+ }
410
+ async handleDetectedNftCollections(collections) {
411
+ try {
412
+ const currentCollections = await this.getNftCollection();
413
+ const newCollections = collections.filter(col => !currentCollections.some(c => c.collectionId === col.collectionId && c.chain === col.chain));
414
+ for (const col of newCollections) {
415
+ this.setNftCollection(col.chain, col);
416
+ }
417
+ } catch (e) {
418
+ this.logger.warn('handleDetectedNftCollections error:', e);
419
+ }
420
+ }
396
421
  cleanUpNfts(chain, owner, collectionId, nftIds, ownNothing) {
397
422
  this.dbService.cleanUpNft(chain, owner, collectionId, nftIds, ownNothing).catch(e => this.logger.warn(e));
398
423
  }
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.3.67-0",
20
+ "version": "1.3.68-1",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -739,6 +739,11 @@
739
739
  "require": "./cjs/services/balance-service/helpers/subscribe/substrate/gear.js",
740
740
  "default": "./services/balance-service/helpers/subscribe/substrate/gear.js"
741
741
  },
742
+ "./services/balance-service/helpers/subscribe/substrate/utils": {
743
+ "types": "./services/balance-service/helpers/subscribe/substrate/utils.d.ts",
744
+ "require": "./cjs/services/balance-service/helpers/subscribe/substrate/utils.js",
745
+ "default": "./services/balance-service/helpers/subscribe/substrate/utils.js"
746
+ },
742
747
  "./services/balance-service/helpers/subscribe/ton/consts": {
743
748
  "types": "./services/balance-service/helpers/subscribe/ton/consts.d.ts",
744
749
  "require": "./cjs/services/balance-service/helpers/subscribe/ton/consts.js",
@@ -1706,6 +1711,11 @@
1706
1711
  "require": "./cjs/services/mkt-campaign-service/types.js",
1707
1712
  "default": "./services/mkt-campaign-service/types.js"
1708
1713
  },
1714
+ "./services/nft-service": {
1715
+ "types": "./services/nft-service/index.d.ts",
1716
+ "require": "./cjs/services/nft-service/index.js",
1717
+ "default": "./services/nft-service/index.js"
1718
+ },
1709
1719
  "./services/notification-service/NotificationService": {
1710
1720
  "types": "./services/notification-service/NotificationService.d.ts",
1711
1721
  "require": "./cjs/services/notification-service/NotificationService.js",
@@ -2907,12 +2917,12 @@
2907
2917
  "@snowbridge/registry": "^0.2.0",
2908
2918
  "@sora-substrate/type-definitions": "^1.17.7",
2909
2919
  "@substrate/connect": "^0.8.9",
2910
- "@subwallet-monorepos/subwallet-services-sdk": "0.1.13",
2920
+ "@subwallet-monorepos/subwallet-services-sdk": "0.1.14",
2911
2921
  "@subwallet/chain-list": "0.2.121",
2912
- "@subwallet/extension-base": "^1.3.67-0",
2913
- "@subwallet/extension-chains": "^1.3.67-0",
2914
- "@subwallet/extension-dapp": "^1.3.67-0",
2915
- "@subwallet/extension-inject": "^1.3.67-0",
2922
+ "@subwallet/extension-base": "^1.3.68-1",
2923
+ "@subwallet/extension-chains": "^1.3.68-1",
2924
+ "@subwallet/extension-dapp": "^1.3.68-1",
2925
+ "@subwallet/extension-inject": "^1.3.68-1",
2916
2926
  "@subwallet/keyring": "^0.1.13",
2917
2927
  "@subwallet/ui-keyring": "^0.1.13",
2918
2928
  "@ton/core": "^0.56.3",
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.3.67-0'
10
+ version: '1.3.68-1'
11
11
  };
@@ -13,11 +13,40 @@ import BigN from 'bignumber.js';
13
13
  */
14
14
  export const groupBalance = (items, address, token) => {
15
15
  const states = items.map(item => item.state);
16
+ const sum = selector => BigN.sum.apply(null, items.map(selector)).toFixed();
17
+ const staking = sum(i => {
18
+ var _i$lockedDetails$stak, _i$lockedDetails;
19
+ return (_i$lockedDetails$stak = (_i$lockedDetails = i.lockedDetails) === null || _i$lockedDetails === void 0 ? void 0 : _i$lockedDetails.staking) !== null && _i$lockedDetails$stak !== void 0 ? _i$lockedDetails$stak : '0';
20
+ });
21
+ const governance = sum(i => {
22
+ var _i$lockedDetails$gove, _i$lockedDetails2;
23
+ return (_i$lockedDetails$gove = (_i$lockedDetails2 = i.lockedDetails) === null || _i$lockedDetails2 === void 0 ? void 0 : _i$lockedDetails2.governance) !== null && _i$lockedDetails$gove !== void 0 ? _i$lockedDetails$gove : '0';
24
+ });
25
+ const democracy = sum(i => {
26
+ var _i$lockedDetails$demo, _i$lockedDetails3;
27
+ return (_i$lockedDetails$demo = (_i$lockedDetails3 = i.lockedDetails) === null || _i$lockedDetails3 === void 0 ? void 0 : _i$lockedDetails3.democracy) !== null && _i$lockedDetails$demo !== void 0 ? _i$lockedDetails$demo : '0';
28
+ });
29
+ const reserved = sum(i => {
30
+ var _i$lockedDetails$rese, _i$lockedDetails4;
31
+ return (_i$lockedDetails$rese = (_i$lockedDetails4 = i.lockedDetails) === null || _i$lockedDetails4 === void 0 ? void 0 : _i$lockedDetails4.reserved) !== null && _i$lockedDetails$rese !== void 0 ? _i$lockedDetails$rese : '0';
32
+ });
33
+ const others = sum(i => {
34
+ var _i$lockedDetails$othe, _i$lockedDetails5;
35
+ return (_i$lockedDetails$othe = (_i$lockedDetails5 = i.lockedDetails) === null || _i$lockedDetails5 === void 0 ? void 0 : _i$lockedDetails5.others) !== null && _i$lockedDetails$othe !== void 0 ? _i$lockedDetails$othe : '0';
36
+ });
37
+ const hasLockedDetails = new BigN(staking).gt(0) || new BigN(governance).gt(0) || new BigN(democracy).gt(0) || new BigN(others).gt(0);
16
38
  return {
17
39
  address,
18
40
  tokenSlug: token,
19
- free: BigN.sum.apply(null, items.map(item => item.free)).toFixed(),
20
- locked: BigN.sum.apply(null, items.map(item => item.locked)).toFixed(),
41
+ free: sum(i => i.free),
42
+ locked: sum(i => i.locked),
43
+ lockedDetails: hasLockedDetails ? {
44
+ staking,
45
+ governance,
46
+ democracy,
47
+ reserved,
48
+ others
49
+ } : undefined,
21
50
  state: states.every(item => item === APIItemState.NOT_SUPPORT) ? APIItemState.NOT_SUPPORT : states.some(item => item === APIItemState.READY) ? APIItemState.READY : APIItemState.PENDING
22
51
  };
23
52
  };
@@ -8,7 +8,7 @@ import { _getAssetsPalletLocked, _getAssetsPalletTransferable } from '@subwallet
8
8
  import { _getForeignAssetPalletLockedBalance, _getForeignAssetPalletTransferable } from '@subwallet/extension-base/core/substrate/foreign-asset-pallet';
9
9
  import { _getTotalStakeInNominationPool } from '@subwallet/extension-base/core/substrate/nominationpools-pallet';
10
10
  import { _getOrmlTokensPalletLockedBalance, _getOrmlTokensPalletTransferable } from '@subwallet/extension-base/core/substrate/ormlTokens-pallet';
11
- import { _getSystemPalletTotalBalance, _getSystemPalletTransferable } from '@subwallet/extension-base/core/substrate/system-pallet';
11
+ import { _getSystemPalletReservedBalance, _getSystemPalletTotalBalance, _getSystemPalletTransferable } from '@subwallet/extension-base/core/substrate/system-pallet';
12
12
  import { _getTokensPalletLocked, _getTokensPalletTransferable } from '@subwallet/extension-base/core/substrate/tokens-pallet';
13
13
  import { _adaptX1Interior } from '@subwallet/extension-base/core/substrate/xcm-parser';
14
14
  import { getPSP22ContractPromise } from '@subwallet/extension-base/koni/api/contract-handler/wasm';
@@ -21,6 +21,7 @@ import { timer } from 'rxjs';
21
21
  import { subscribeERC20Interval } from "../evm.js";
22
22
  import { subscribeEquilibriumTokenBalance } from "./equilibrium.js";
23
23
  import { subscribeGRC20Balance, subscribeVftBalance } from "./gear.js";
24
+ import { buildLockedDetails, getSpecialStakingBalances } from "./utils.js";
24
25
  export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap, substrateApi, evmApi, callback, extrinsicType) => {
25
26
  let unsubNativeToken;
26
27
  let unsubLocalToken;
@@ -109,7 +110,6 @@ export const subscribeSubstrateBalance = async (addresses, chainInfo, assetMap,
109
110
  };
110
111
  };
111
112
 
112
- // handler according to different logic
113
113
  // eslint-disable-next-line @typescript-eslint/require-await
114
114
  const subscribeWithSystemAccountPallet = async ({
115
115
  addresses,
@@ -140,15 +140,10 @@ const subscribeWithSystemAccountPallet = async ({
140
140
  const subscription = substrateApi.subscribeDataWithMulti(params, async rs => {
141
141
  const balances = rs[systemAccountKey];
142
142
  const poolMemberInfos = rs[poolMembersKey];
143
- let bittensorStakingBalances = new Array(addresses.length).fill(new BigN(0));
144
- if (_BALANCE_CHAIN_GROUP.bittensor.includes(chainInfo.slug)) {
145
- const rawData = await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkeys(addresses);
146
- const values = rawData.toPrimitive();
147
- bittensorStakingBalances = values.map(([, stakes]) => {
148
- return stakes.filter(i => i.netuid === 0).reduce((previousValue, currentValue) => previousValue.plus(currentValue.stake), BigN(0));
149
- });
150
- }
151
- const items = balances.map((_balance, index) => {
143
+ const bittensorStakingBalances = await getSpecialStakingBalances(chainInfo, addresses, substrateApi);
144
+
145
+ // Precompute totalLockedFromTransfer for each account to decide if need fetch locks/holds
146
+ const preItems = balances.map((_balance, index) => {
152
147
  const balanceInfo = _balance;
153
148
  const transferableBalance = _getSystemPalletTransferable(balanceInfo, _getChainExistentialDeposit(chainInfo), extrinsicType);
154
149
  const totalBalance = _getSystemPalletTotalBalance(balanceInfo);
@@ -158,14 +153,57 @@ const subscribeWithSystemAccountPallet = async ({
158
153
  const nominationPoolBalance = poolMemberInfo ? _getTotalStakeInNominationPool(poolMemberInfo) : BigInt(0);
159
154
  totalLockedFromTransfer += nominationPoolBalance;
160
155
  }
161
- const stakeValue = BigInt(bittensorStakingBalances[index].toString());
162
- totalLockedFromTransfer += stakeValue;
156
+ totalLockedFromTransfer += BigInt(bittensorStakingBalances[index].toString());
157
+ return {
158
+ index,
159
+ totalLockedFromTransfer,
160
+ balanceInfo
161
+ };
162
+ });
163
+
164
+ // Filter account's locked > 0
165
+ const accountsWithLocks = preItems.filter(i => i.totalLockedFromTransfer > 0).map(i => addresses[i.index]);
166
+ let locks = [];
167
+ let holds = [];
168
+ let freezes = [];
169
+
170
+ // Fetch locks/holds only for accounts that have locked balances
171
+ if (accountsWithLocks.length > 0) {
172
+ const [rawLocks, rawHolds, rawFreezes] = await Promise.all([substrateApi.api.query.balances.locks.multi(accountsWithLocks), substrateApi.api.query.balances.holds.multi(accountsWithLocks), substrateApi.api.query.balances.freezes.multi(accountsWithLocks)]);
173
+ locks = rawLocks.map(lockArr => lockArr.map(l => ({
174
+ id: l.id.toPrimitive(),
175
+ amount: l.amount.toString()
176
+ })));
177
+ holds = rawHolds.map(holdArr => holdArr.map(h => ({
178
+ id: h.id.toPrimitive(),
179
+ amount: h.amount.toString()
180
+ })));
181
+ freezes = rawFreezes.map(freezeArr => freezeArr.map(f => ({
182
+ id: f.id.toPrimitive(),
183
+ amount: f.amount.toString()
184
+ })));
185
+ }
186
+
187
+ // Map locks/holds back to original index
188
+ const items = preItems.map(({
189
+ balanceInfo,
190
+ index,
191
+ totalLockedFromTransfer
192
+ }) => {
193
+ const lockIndex = accountsWithLocks.indexOf(addresses[index]);
194
+ const lockItems = lockIndex >= 0 ? locks[lockIndex] || [] : [];
195
+ const holdItems = lockIndex >= 0 ? holds[lockIndex] || [] : [];
196
+ const freezeItems = lockIndex >= 0 ? freezes[lockIndex] || [] : [];
197
+ const allLockEntries = [...lockItems, ...holdItems, ...freezeItems];
198
+ const lockedDetails = buildLockedDetails(allLockEntries, totalLockedFromTransfer, _getSystemPalletReservedBalance(balanceInfo), bittensorStakingBalances[index]);
199
+ const transferableBalance = _getSystemPalletTransferable(balanceInfo, _getChainExistentialDeposit(chainInfo), extrinsicType);
163
200
  return {
164
201
  address: addresses[index],
165
202
  tokenSlug: _getChainNativeTokenSlug(chainInfo),
166
203
  free: transferableBalance.toString(),
167
204
  locked: totalLockedFromTransfer.toString(),
168
205
  state: APIItemState.READY,
206
+ lockedDetails,
169
207
  metadata: balanceInfo
170
208
  };
171
209
  });
@@ -0,0 +1,7 @@
1
+ import { _ChainInfo } from '@subwallet/chain-list/types';
2
+ import { FrameBalancesFreezesInfo, FrameBalancesHoldsInfo, FrameBalancesLocksInfo } from '@subwallet/extension-base/core/substrate/types';
3
+ import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
4
+ import { LockedBalanceDetails } from '@subwallet/extension-base/types';
5
+ import BigN from 'bignumber.js';
6
+ export declare function getSpecialStakingBalances(chainInfo: _ChainInfo, addresses: string[], substrateApi: _SubstrateApi): Promise<BigN[]>;
7
+ export declare function buildLockedDetails(item: (FrameBalancesLocksInfo | FrameBalancesHoldsInfo | FrameBalancesFreezesInfo)[], totalLockedFromTransfer: bigint, reserved: bigint, externalStaking?: BigN): LockedBalanceDetails;
@@ -0,0 +1,58 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { _BALANCE_CHAIN_GROUP, _BALANCE_LOCKED_ID_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
5
+ import BigN from 'bignumber.js';
6
+ export async function getSpecialStakingBalances(chainInfo, addresses, substrateApi) {
7
+ // Default: 0 for all addresses
8
+ let balances = new Array(addresses.length).fill(new BigN(0));
9
+
10
+ // --- Bittensor ----------------------------------------------------------------
11
+ if (_BALANCE_CHAIN_GROUP.bittensor.includes(chainInfo.slug)) {
12
+ const rawData = await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkeys(addresses);
13
+ const values = rawData.toPrimitive();
14
+ balances = values.map(([, stakes]) => stakes.filter(i => i.netuid === 0).reduce((prev, curr) => prev.plus(curr.stake), BigN(0)));
15
+ return balances;
16
+ }
17
+ return balances;
18
+ }
19
+
20
+ // handler according to different logic
21
+ const extractId = id => {
22
+ if (!id) {
23
+ return '';
24
+ }
25
+ if (typeof id === 'string') {
26
+ return id.replace(/\0/g, '').trim();
27
+ }
28
+ const keys = Object.keys(id);
29
+ return keys.length ? keys[0] : '';
30
+ };
31
+ export function buildLockedDetails(item, totalLockedFromTransfer, reserved, externalStaking) {
32
+ let stakingBalance = externalStaking || new BigN(0);
33
+ let govBalance = new BigN(0);
34
+ let democracyBalance = new BigN(0);
35
+ const reservedBN = new BigN(reserved.toString());
36
+ for (const entry of item) {
37
+ const id = extractId(entry.id);
38
+ const amount = new BigN(String(entry.amount || 0));
39
+ if (_BALANCE_LOCKED_ID_GROUP.staking.includes(id)) {
40
+ stakingBalance = stakingBalance.plus(amount);
41
+ } else if (_BALANCE_LOCKED_ID_GROUP.gov.includes(id)) {
42
+ govBalance = govBalance.plus(amount);
43
+ } else if (_BALANCE_LOCKED_ID_GROUP.democracy.includes(id)) {
44
+ democracyBalance = democracyBalance.plus(amount);
45
+ }
46
+ }
47
+
48
+ // others = total locked - max(staking, gov, democracy, reserved)
49
+ const maxMain = BigN.max(stakingBalance, govBalance, democracyBalance, reservedBN);
50
+ const others = new BigN(totalLockedFromTransfer.toString()).minus(maxMain);
51
+ return {
52
+ staking: stakingBalance.toFixed(),
53
+ governance: govBalance.toFixed(),
54
+ democracy: democracyBalance.toFixed(),
55
+ reserved: reservedBN.toFixed(),
56
+ others: others.gt(0) ? others.toFixed() : '0'
57
+ };
58
+ }
@@ -3,7 +3,7 @@ import KoniState from '@subwallet/extension-base/koni/background/handlers/State'
3
3
  import { RequestOptimalTransferProcess } from '@subwallet/extension-base/services/balance-service/helpers/process';
4
4
  import { ServiceStatus, StoppableServiceInterface } from '@subwallet/extension-base/services/base/types';
5
5
  import { EventItem, EventType } from '@subwallet/extension-base/services/event-service/types';
6
- import { BalanceItem, BalanceJson, CommonOptimalTransferPath } from '@subwallet/extension-base/types';
6
+ import { BalanceItem, BalanceJson, BalanceType, CommonOptimalTransferPath } from '@subwallet/extension-base/types';
7
7
  import { PromiseHandler } from '@subwallet/extension-base/utils';
8
8
  import { BehaviorSubject } from 'rxjs';
9
9
  /**
@@ -48,9 +48,10 @@ export declare class BalanceService implements StoppableServiceInterface {
48
48
  getBalanceDetectCache(update: (value: DetectBalanceCache) => void): void;
49
49
  setBalanceDetectCache(addresses: string[]): void;
50
50
  /** Subscribe token free balance of an address on chain */
51
- subscribeBalance(address: string, chain: string, tokenSlug: string | undefined, balanceType?: 'transferable' | 'total' | 'keepAlive', extrinsicType?: ExtrinsicType, callback?: (rs: AmountData) => void): Promise<[() => void, AmountData]>;
51
+ subscribeBalance(address: string, chain: string, tokenSlug: string | undefined, balanceType?: BalanceType, extrinsicType?: ExtrinsicType, callback?: (rs: AmountData) => void): Promise<[() => void, AmountData]>;
52
52
  subscribeTransferableBalance(address: string, chain: string, tokenSlug: string | undefined, extrinsicType?: ExtrinsicType, callback?: (rs: AmountData) => void): Promise<[() => void, AmountData]>;
53
53
  subscribeTotalBalance(address: string, chain: string, tokenSlug: string | undefined, extrinsicType?: ExtrinsicType, callback?: (rs: AmountData) => void): Promise<[() => void, AmountData]>;
54
+ subscribeBalanceByType(address: string, chain: string, tokenSlug: string | undefined, balanceType?: BalanceType, extrinsicType?: ExtrinsicType, callback?: (rs: AmountData) => void): Promise<[() => void, AmountData]>;
54
55
  /**
55
56
  * @public
56
57
  * @async
@@ -64,6 +65,7 @@ export declare class BalanceService implements StoppableServiceInterface {
64
65
  */
65
66
  getTransferableBalance(address: string, chain: string, tokenSlug?: string, extrinsicType?: ExtrinsicType): Promise<AmountData>;
66
67
  getTotalBalance(address: string, chain: string, tokenSlug?: string, extrinsicType?: ExtrinsicType): Promise<AmountData>;
68
+ getBalanceByType(address: string, chain: string, tokenSlug?: string, balanceType?: BalanceType, extrinsicType?: ExtrinsicType): Promise<AmountData>;
67
69
  /** Remove balance from the subject object by addresses */
68
70
  removeBalanceByAddresses(addresses: string[]): void;
69
71
  /** Remove inactive asset from the balance map */
@@ -9,6 +9,7 @@ import { getAcrossbridgeTransferProcessFromEvm, getDefaultTransferProcess, getSn
9
9
  import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
10
10
  import { _getChainNativeTokenSlug, _isCustomAsset, _isNativeToken, _isPureEvmChain } from '@subwallet/extension-base/services/chain-service/utils';
11
11
  import DetectAccountBalanceStore from '@subwallet/extension-base/stores/DetectAccountBalance';
12
+ import { BalanceType } from '@subwallet/extension-base/types';
12
13
  import { addLazy, createPromiseHandler, isAccountAll, waitTimeout } from '@subwallet/extension-base/utils';
13
14
  import { getKeypairTypeByAddress } from '@subwallet/keyring';
14
15
  import { EthereumKeypairTypes, SubstrateKeypairTypes } from '@subwallet/keyring/types';
@@ -18,6 +19,7 @@ import BigN from 'bignumber.js';
18
19
  import { t } from 'i18next';
19
20
  import { BehaviorSubject } from 'rxjs';
20
21
  import { noop } from '@polkadot/util';
22
+ import { _BALANCE_CHAIN_GROUP } from "../chain-service/constants.js";
21
23
  import { _isAcrossChainBridge, getAcrossQuote } from "./transfer/xcm/acrossBridge/index.js";
22
24
  import { BalanceMapImpl } from "./BalanceMapImpl.js";
23
25
  import { subscribeBalance } from "./helpers/index.js";
@@ -175,7 +177,7 @@ export class BalanceService {
175
177
  }
176
178
 
177
179
  /** Subscribe token free balance of an address on chain */
178
- async subscribeBalance(address, chain, tokenSlug, balanceType = 'transferable', extrinsicType, callback) {
180
+ async subscribeBalance(address, chain, tokenSlug, balanceType = BalanceType.TRANSFERABLE, extrinsicType, callback) {
179
181
  const chainInfo = this.state.chainService.getChainInfoByKey(chain);
180
182
  const chainState = this.state.chainService.getChainStateByKey(chain);
181
183
  if (!chainInfo || !chainState || !chainState.active) {
@@ -208,9 +210,20 @@ export class BalanceService {
208
210
  const rs = result[0];
209
211
  let value;
210
212
  switch (balanceType) {
211
- case 'total':
213
+ case BalanceType.TOTAL:
212
214
  value = new BigN(rs.free).plus(new BigN(rs.locked)).toFixed();
213
215
  break;
216
+ case BalanceType.TOTAL_MINUS_RESERVED:
217
+ if (_BALANCE_CHAIN_GROUP.notSupportGetBalanceByType.includes(chainInfo.slug)) {
218
+ // TODO: Currently Vara and Avail staking from nomination pools is not fully supported.
219
+ // Return `free` to avoid incorrect TOTAL_MINUS_RESERVED calculation.
220
+ // Improve later when full staking breakdown is available.
221
+ value = rs.free;
222
+ } else {
223
+ var _rs$lockedDetails, _rs$lockedDetails2;
224
+ value = new BigN(rs.free).plus(new BigN(rs.locked)).minus(BigN.max(new BigN(((_rs$lockedDetails = rs.lockedDetails) === null || _rs$lockedDetails === void 0 ? void 0 : _rs$lockedDetails.reserved) || 0), new BigN(((_rs$lockedDetails2 = rs.lockedDetails) === null || _rs$lockedDetails2 === void 0 ? void 0 : _rs$lockedDetails2.staking) || 0))).toFixed();
225
+ }
226
+ break;
214
227
  default:
215
228
  value = rs.free;
216
229
  }
@@ -242,10 +255,13 @@ export class BalanceService {
242
255
  });
243
256
  }
244
257
  async subscribeTransferableBalance(address, chain, tokenSlug, extrinsicType, callback) {
245
- return this.subscribeBalance(address, chain, tokenSlug, 'transferable', extrinsicType, callback);
258
+ return this.subscribeBalance(address, chain, tokenSlug, BalanceType.TRANSFERABLE, extrinsicType, callback);
246
259
  }
247
260
  async subscribeTotalBalance(address, chain, tokenSlug, extrinsicType, callback) {
248
- return this.subscribeBalance(address, chain, tokenSlug, 'total', extrinsicType, callback);
261
+ return this.subscribeBalance(address, chain, tokenSlug, BalanceType.TOTAL, extrinsicType, callback);
262
+ }
263
+ async subscribeBalanceByType(address, chain, tokenSlug, balanceType = BalanceType.TRANSFERABLE, extrinsicType, callback) {
264
+ return this.subscribeBalance(address, chain, tokenSlug, balanceType, extrinsicType, callback);
249
265
  }
250
266
 
251
267
  /**
@@ -267,6 +283,10 @@ export class BalanceService {
267
283
  const [, balance] = await this.subscribeTotalBalance(address, chain, tokenSlug, extrinsicType);
268
284
  return balance;
269
285
  }
286
+ async getBalanceByType(address, chain, tokenSlug, balanceType = BalanceType.TRANSFERABLE, extrinsicType) {
287
+ const [, balance] = await this.subscribeBalanceByType(address, chain, tokenSlug, balanceType, extrinsicType);
288
+ return balance;
289
+ }
270
290
 
271
291
  /** Remove balance from the subject object by addresses */
272
292
  removeBalanceByAddresses(addresses) {
@@ -452,7 +472,7 @@ export class BalanceService {
452
472
  const type = getKeypairTypeByAddress(address);
453
473
  const typeValid = [...EthereumKeypairTypes].includes(type);
454
474
  if (typeValid) {
455
- return subwalletApiSdk.balanceDetectionApi.getSubWalletTokenBalance(address).catch(e => {
475
+ return subwalletApiSdk.balanceDetectionApi.getSwEvmTokenBalance(address).catch(e => {
456
476
  console.error(e);
457
477
  return null;
458
478
  });
@@ -632,7 +652,7 @@ export class BalanceService {
632
652
  async evmDetectBalanceToken(addresses) {
633
653
  const assetMap = this.state.chainService.getAssetRegistry();
634
654
  const evmPromiseList = addresses.map(address => {
635
- return subwalletApiSdk.balanceDetectionApi.getSubWalletTokenBalance(address).catch(e => {
655
+ return subwalletApiSdk.balanceDetectionApi.getSwEvmTokenBalance(address).catch(e => {
636
656
  console.error(e);
637
657
  return null;
638
658
  });
@@ -161,7 +161,9 @@ export async function getERC721Transaction(web3Api, chain, contractAddress, send
161
161
  const error = e;
162
162
  if (error.message.includes('transfer to non ERC721Receiver implementer')) {
163
163
  error.message = t('bg.BALANCE.services.service.balance.transfer.smartContract.nftNotSupportedOnRecipient');
164
+ throw error;
164
165
  }
166
+ error.message = t('bg.BALANCE.services.service.balance.transfer.smartContract.temporarilyNontransferableNFT');
165
167
  throw error;
166
168
  }
167
169
  const feeInfo = _feeInfo;
@@ -1,7 +1,6 @@
1
1
  import { SingleModeJson } from '@subwallet/extension-base/background/KoniTypes';
2
2
  export declare const API_AUTO_CONNECT_MS = 3000;
3
3
  export declare const API_CONNECT_TIMEOUT = 30000;
4
- export declare const API_MAX_RETRY = 2;
5
4
  export declare const _API_OPTIONS_CHAIN_GROUP: {
6
5
  acala: string[];
7
6
  turing: string[];
@@ -22,10 +21,12 @@ export declare const _BALANCE_CHAIN_GROUP: {
22
21
  supportBridged: string[];
23
22
  bittensor: string[];
24
23
  moonbeam: string[];
24
+ notSupportGetBalanceByType: string[];
25
25
  };
26
- export declare const _BALANCE_TOKEN_GROUP: {
27
- crab: string[];
28
- bitcountry: string[];
26
+ export declare const _BALANCE_LOCKED_ID_GROUP: {
27
+ staking: string[];
28
+ gov: string[];
29
+ democracy: string[];
29
30
  };
30
31
  export declare const _NFT_CHAIN_GROUP: {
31
32
  acala: string[];
@@ -59,7 +60,6 @@ export interface _SubstrateUniformEraPayoutInflationParams extends _SubstrateInf
59
60
  }
60
61
  export declare const _SUBSTRATE_DEFAULT_INFLATION_PARAMS: _SubstrateInflationParams;
61
62
  export declare const _KNOWN_CHAIN_INFLATION_PARAMS: Record<string, _SubstrateInflationParams>;
62
- export declare const _TRANSFER_NOT_SUPPORTED_CHAINS: string[];
63
63
  export declare const _TRANSFER_CHAIN_GROUP: {
64
64
  acala: string[];
65
65
  kintsugi: string[];
@@ -74,22 +74,9 @@ export declare const _TRANSFER_CHAIN_GROUP: {
74
74
  disable_transfer: string[];
75
75
  truth: string[];
76
76
  };
77
- export declare const _BALANCE_PARSING_CHAIN_GROUP: {
78
- bobabeam: string[];
79
- };
80
77
  export declare const _MANTA_ZK_CHAIN_GROUP: string[];
81
78
  export declare const _ZK_ASSET_PREFIX = "zk";
82
79
  export declare const _DEFAULT_MANTA_ZK_CHAIN = "calamari";
83
- export declare const _XCM_CHAIN_GROUP: {
84
- polkadotXcm: string[];
85
- polkadotXcmSpecialCases: string[];
86
- xcmPallet: string[];
87
- };
88
- export declare const _XCM_TYPE: {
89
- RP: string;
90
- PP: string;
91
- PR: string;
92
- };
93
80
  export declare const _DEFAULT_ACTIVE_CHAINS: string[];
94
81
  export declare const EVM_PASS_CONNECT_STATUS: Record<string, string[]>;
95
82
  export declare const EVM_REFORMAT_DECIMALS: {
@@ -100,10 +87,4 @@ export declare const _BITCOIN_CHAIN_SLUG = "bitcoin";
100
87
  export declare const _BITCOIN_TESTNET_CHAIN_SLUG = "bitcoinTestnet";
101
88
  export declare const _BITCOIN_NAME = "Bitcoin";
102
89
  export declare const _BITCOIN_TESTNET_NAME = "Bitcoin Testnet";
103
- export declare const _CHAIN_INFO_SRC: string;
104
- export declare const _CHAIN_ASSET_SRC: string;
105
- export declare const _ASSET_REF_SRC: string;
106
- export declare const _MULTI_CHAIN_ASSET_SRC: string;
107
- export declare const _CHAIN_LOGO_MAP_SRC: string;
108
- export declare const _ASSET_LOGO_MAP_SRC: string;
109
90
  export declare const _BTC_SERVICE_TOKEN: string;
@@ -2,11 +2,9 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { _DEFAULT_CHAINS } from '@subwallet/chain-list';
5
- import { _SubstrateChainType } from '@subwallet/chain-list/types';
6
5
  import { ThemeNames } from '@subwallet/extension-base/background/KoniTypes';
7
6
  export const API_AUTO_CONNECT_MS = 3000;
8
7
  export const API_CONNECT_TIMEOUT = 30000;
9
- export const API_MAX_RETRY = 2;
10
8
  export const _API_OPTIONS_CHAIN_GROUP = {
11
9
  acala: ['acala', 'karura', 'origintrail', 'kintsugi'],
12
10
  turing: ['turingStaging', 'turing'],
@@ -36,11 +34,13 @@ export const _BALANCE_CHAIN_GROUP = {
36
34
  centrifuge: ['centrifuge'],
37
35
  supportBridged: ['rococo_assethub', 'statemint', 'statemine', 'polimec'],
38
36
  bittensor: ['bittensor', 'bittensor_testnet'],
39
- moonbeam: ['moonbeam', 'moonriver', 'moonbase']
37
+ moonbeam: ['moonbeam', 'moonriver', 'moonbase'],
38
+ notSupportGetBalanceByType: ['vara_network', 'vara_testnet', 'availTuringTest', 'avail_mainnet']
40
39
  };
41
- export const _BALANCE_TOKEN_GROUP = {
42
- crab: ['CKTON', 'PKTON'],
43
- bitcountry: ['BIT']
40
+ export const _BALANCE_LOCKED_ID_GROUP = {
41
+ staking: ['staking', 'delegatedStaking', 'pooledStaking', 'stkngdel', 'stk_stks', 'dappStaking', 'parachainStaking', 'appstakeappstake', 'collatorStaking'],
42
+ gov: ['pyconvot'],
43
+ democracy: ['democrac']
44
44
  };
45
45
  export const _NFT_CHAIN_GROUP = {
46
46
  acala: ['acala'],
@@ -274,12 +274,10 @@ export const _KNOWN_CHAIN_INFLATION_PARAMS = {
274
274
 
275
275
  // Send fund------------------------------------------------------------------------------------------------------------
276
276
 
277
- export const _TRANSFER_NOT_SUPPORTED_CHAINS = ['subspace_gemini_3a', 'kulupu', 'joystream', 'equilibrium_parachain', 'genshiro_testnet', 'genshiro'];
278
277
  export const _TRANSFER_CHAIN_GROUP = {
279
278
  acala: ['karura', 'acala', 'acala_testnet'],
280
279
  kintsugi: ['kintsugi', 'kintsugi_test', 'interlay', 'mangatax_para'],
281
280
  genshiro: ['genshiro_testnet', 'genshiro', 'equilibrium_parachain'],
282
- // crab: ['crab', 'pangolin'],
283
281
  bitcountry: ['pioneer', 'bitcountry'],
284
282
  statemine: ['statemint', 'statemine', 'darwinia2', 'astar', 'shiden', 'shibuya', 'parallel', 'liberland', 'liberlandTest', 'dentnet', 'dbcchain', 'westend_assethub', 'chainflip_assethub', 'origintrail', 'xode', 'paseo_assethub'],
285
283
  riochain: ['riochain'],
@@ -290,30 +288,12 @@ export const _TRANSFER_CHAIN_GROUP = {
290
288
  disable_transfer: ['crab', 'pangolin'],
291
289
  truth: ['truth_network']
292
290
  };
293
- export const _BALANCE_PARSING_CHAIN_GROUP = {
294
- bobabeam: ['bobabeam', 'bobabase']
295
- };
296
291
  export const _MANTA_ZK_CHAIN_GROUP = ['calamari'];
297
292
  export const _ZK_ASSET_PREFIX = 'zk';
298
293
  export const _DEFAULT_MANTA_ZK_CHAIN = 'calamari';
299
294
 
300
295
  // XCM------------------------------------------------------------------------------------------------------------------
301
296
 
302
- export const _XCM_CHAIN_GROUP = {
303
- polkadotXcm: ['statemine', 'statemint', 'equilibrium_parachain', 'rococo_assethub', 'mythos', 'westend_assethub'],
304
- polkadotXcmSpecialCases: ['astar', 'shiden'],
305
- xcmPallet: ['polkadot', 'kusama', 'rococo', 'westend']
306
- // default is xTokens pallet
307
- };
308
-
309
- export const _XCM_TYPE = {
310
- RP: `${_SubstrateChainType.RELAYCHAIN}-${_SubstrateChainType.PARACHAIN}`,
311
- // DMP
312
- PP: `${_SubstrateChainType.PARACHAIN}-${_SubstrateChainType.PARACHAIN}`,
313
- // HRMP
314
- PR: `${_SubstrateChainType.PARACHAIN}-${_SubstrateChainType.RELAYCHAIN}` // UMP
315
- };
316
-
317
297
  export const _DEFAULT_ACTIVE_CHAINS = [..._DEFAULT_CHAINS, 'vara_network', 'ton'];
318
298
  export const EVM_PASS_CONNECT_STATUS = {
319
299
  arbitrum_one: ['*'],
@@ -326,17 +306,8 @@ export const EVM_REFORMAT_DECIMALS = {
326
306
  acala: ['acala_evm', 'karura_evm']
327
307
  };
328
308
  export const LATEST_CHAIN_DATA_FETCHING_INTERVAL = 120000;
329
-
330
- // TODO: review
331
- const TARGET_BRANCH = process.env.NODE_ENV !== 'production' ? 'koni-dev' : 'master';
332
309
  export const _BITCOIN_CHAIN_SLUG = 'bitcoin';
333
310
  export const _BITCOIN_TESTNET_CHAIN_SLUG = 'bitcoinTestnet';
334
311
  export const _BITCOIN_NAME = 'Bitcoin';
335
312
  export const _BITCOIN_TESTNET_NAME = 'Bitcoin Testnet';
336
- export const _CHAIN_INFO_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainInfo.json`;
337
- export const _CHAIN_ASSET_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainAsset.json`;
338
- export const _ASSET_REF_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/AssetRef.json`;
339
- export const _MULTI_CHAIN_ASSET_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/MultiChainAsset.json`;
340
- export const _CHAIN_LOGO_MAP_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainLogoMap.json`;
341
- export const _ASSET_LOGO_MAP_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/AssetLogoMap.json`;
342
313
  export const _BTC_SERVICE_TOKEN = process.env.BTC_SERVICE_TOKEN || '';
@@ -118,6 +118,9 @@ export class EvmChainHandler extends AbstractChainHandler {
118
118
  tokenContract.methods.symbol().call()]);
119
119
  name = _name;
120
120
  symbol = _symbol;
121
+ if (name === '') {
122
+ contractError = true;
123
+ }
121
124
  } else {
122
125
  tokenContract = new evmApi.api.eth.Contract(_ERC20_ABI, contractAddress);
123
126
  const [_decimals, _symbol, _name] = await Promise.all([
@@ -130,9 +133,9 @@ export class EvmChainHandler extends AbstractChainHandler {
130
133
  name = _name;
131
134
  decimals = new BigN(_decimals).toNumber();
132
135
  symbol = _symbol;
133
- }
134
- if (name === '' || symbol === '') {
135
- contractError = true;
136
+ if (name === '' || symbol === '') {
137
+ contractError = true;
138
+ }
136
139
  }
137
140
  return {
138
141
  name,