@subwallet/extension-base 1.3.45-1 → 1.3.46-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 (73) hide show
  1. package/background/KoniTypes.d.ts +5 -0
  2. package/background/KoniTypes.js +5 -0
  3. package/background/types.d.ts +2 -0
  4. package/cjs/background/KoniTypes.js +7 -1
  5. package/cjs/core/logic-validation/request.js +55 -28
  6. package/cjs/core/utils.js +22 -0
  7. package/cjs/koni/background/handlers/Extension.js +84 -61
  8. package/cjs/koni/background/handlers/Tabs.js +11 -3
  9. package/cjs/packageInfo.js +1 -1
  10. package/cjs/page/evm/index.js +64 -105
  11. package/cjs/page/index.js +5 -3
  12. package/cjs/page/substrate/Accounts.js +2 -1
  13. package/cjs/services/balance-service/helpers/subscribe/index.js +3 -76
  14. package/cjs/services/chain-service/index.js +3 -0
  15. package/cjs/services/chain-service/utils/index.js +31 -1
  16. package/cjs/services/earning-service/constants/chains.js +2 -1
  17. package/cjs/services/earning-service/handlers/native-staking/base.js +3 -0
  18. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +9 -2
  19. package/cjs/services/earning-service/handlers/nomination-pool/index.js +6 -3
  20. package/cjs/services/earning-service/service.js +39 -17
  21. package/cjs/services/keyring-service/context/handlers/Json.js +2 -1
  22. package/cjs/services/keyring-service/context/handlers/Ledger.js +7 -2
  23. package/cjs/services/request-service/handler/AuthRequestHandler.js +30 -6
  24. package/cjs/types/account/info/keyring.js +1 -0
  25. package/cjs/utils/account/analyze.js +5 -2
  26. package/cjs/utils/account/common.js +93 -2
  27. package/cjs/utils/account/transform.js +10 -0
  28. package/cjs/utils/asset.js +9 -2
  29. package/cjs/utils/staticData/index.js +7 -2
  30. package/core/logic-validation/request.js +31 -4
  31. package/core/types.d.ts +3 -2
  32. package/core/utils.js +24 -2
  33. package/koni/background/handlers/Extension.js +31 -8
  34. package/koni/background/handlers/Tabs.js +11 -4
  35. package/package.json +7 -6
  36. package/packageInfo.js +1 -1
  37. package/page/evm/index.d.ts +9 -18
  38. package/page/evm/index.js +62 -101
  39. package/page/index.js +5 -3
  40. package/page/substrate/Accounts.js +2 -1
  41. package/services/balance-service/helpers/subscribe/index.d.ts +1 -11
  42. package/services/balance-service/helpers/subscribe/index.js +3 -74
  43. package/services/chain-service/index.d.ts +1 -0
  44. package/services/chain-service/index.js +3 -0
  45. package/services/chain-service/utils/index.d.ts +10 -2
  46. package/services/chain-service/utils/index.js +26 -2
  47. package/services/earning-service/constants/chains.d.ts +1 -0
  48. package/services/earning-service/constants/chains.js +2 -1
  49. package/services/earning-service/handlers/native-staking/base.d.ts +1 -0
  50. package/services/earning-service/handlers/native-staking/base.js +3 -0
  51. package/services/earning-service/handlers/native-staking/relay-chain.js +9 -2
  52. package/services/earning-service/handlers/nomination-pool/index.d.ts +1 -0
  53. package/services/earning-service/handlers/nomination-pool/index.js +6 -3
  54. package/services/earning-service/service.d.ts +2 -0
  55. package/services/earning-service/service.js +42 -20
  56. package/services/keyring-service/context/handlers/Json.js +2 -1
  57. package/services/keyring-service/context/handlers/Ledger.js +7 -2
  58. package/services/request-service/handler/AuthRequestHandler.d.ts +1 -0
  59. package/services/request-service/handler/AuthRequestHandler.js +30 -6
  60. package/services/request-service/types.d.ts +1 -0
  61. package/types/account/action/subscribe.d.ts +3 -0
  62. package/types/account/info/keyring.d.ts +3 -0
  63. package/types/account/info/keyring.js +1 -0
  64. package/types/balance/transfer.d.ts +1 -0
  65. package/utils/account/analyze.js +5 -2
  66. package/utils/account/common.d.ts +13 -1
  67. package/utils/account/common.js +91 -2
  68. package/utils/account/transform.js +10 -0
  69. package/utils/asset.d.ts +2 -1
  70. package/utils/asset.js +7 -1
  71. package/utils/staticData/assetHubStaking.json +1 -0
  72. package/utils/staticData/index.d.ts +4 -1
  73. package/utils/staticData/index.js +5 -1
package/core/utils.js CHANGED
@@ -4,9 +4,11 @@
4
4
  import { _AssetType } from '@subwallet/chain-list/types';
5
5
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
6
6
  import { BalanceAccountType } from '@subwallet/extension-base/core/substrate/types';
7
+ import { ActionType } from '@subwallet/extension-base/core/types';
7
8
  import { tonAddressInfo } from '@subwallet/extension-base/services/balance-service/helpers/subscribe/ton/utils';
8
- import { _getTokenOnChainAssetId, _getXcmAssetMultilocation, _isBridgedToken, _isChainBitcoinCompatible, _isChainCardanoCompatible, _isChainEvmCompatible, _isChainSubstrateCompatible, _isChainTonCompatible } from '@subwallet/extension-base/services/chain-service/utils';
9
- import { isAddressAndChainCompatible, isSameAddress, reformatAddress } from '@subwallet/extension-base/utils';
9
+ import { _getTokenOnChainAssetId, _getXcmAssetMultilocation, _isBridgedToken, _isChainBitcoinCompatible, _isChainCardanoCompatible, _isChainCompatibleLedgerEvm, _isChainEvmCompatible, _isChainSubstrateCompatible, _isChainTonCompatible, _isSubstrateEvmCompatibleChain } from '@subwallet/extension-base/services/chain-service/utils';
10
+ import { AccountChainType, AccountSignMode } from '@subwallet/extension-base/types';
11
+ import { isAddressAndChainCompatible, isSameAddress, isSubstrateEcdsaLedgerAssetSupported, reformatAddress } from '@subwallet/extension-base/utils';
10
12
  import { isAddress, isCardanoTestnetAddress, isTonAddress } from '@subwallet/keyring';
11
13
  import { getBitcoinAddressInfo, validateBitcoinAddress } from '@subwallet/keyring/utils';
12
14
  import { isEthereumAddress } from '@polkadot/util-crypto';
@@ -122,7 +124,9 @@ export function _isNotDuplicateAddress(validateRecipientParams) {
122
124
  export function _isSupportLedgerAccount(validateRecipientParams) {
123
125
  const {
124
126
  account,
127
+ actionType,
125
128
  allowLedgerGenerics,
129
+ assetInfo,
126
130
  destChainInfo
127
131
  } = validateRecipientParams;
128
132
  if (account !== null && account !== void 0 && account.isHardware) {
@@ -135,6 +139,24 @@ export function _isSupportLedgerAccount(validateRecipientParams) {
135
139
  return 'Your Ledger account is not supported by {{network}} network.'.replace('{{network}}', destChainName);
136
140
  }
137
141
  } else {
142
+ if (account.chainType === AccountChainType.ETHEREUM) {
143
+ // For ecdsa substrate account in polkadot ledger app
144
+ if (account.signMode === AccountSignMode.ECDSA_SUBSTRATE_LEDGER) {
145
+ if (actionType === ActionType.SEND_NFT) {
146
+ return 'Ledger Polkadot (EVM) address is not supported for NFT transfer';
147
+ }
148
+ if (!_isSubstrateEvmCompatibleChain(destChainInfo)) {
149
+ return 'Ledger Polkadot (EVM) address is not supported for this transfer';
150
+ } else if (assetInfo && !isSubstrateEcdsaLedgerAssetSupported(assetInfo, destChainInfo)) {
151
+ return 'Ledger Polkadot (EVM) address is not supported for this transfer';
152
+ }
153
+ } else {
154
+ if (!_isChainCompatibleLedgerEvm(destChainInfo)) {
155
+ return 'Ledger EVM address is not supported for this transfer';
156
+ }
157
+ }
158
+ }
159
+
138
160
  // For ledger generic
139
161
  const ledgerCheck = ledgerMustCheckNetwork(account);
140
162
  if (ledgerCheck !== 'unnecessary' && !allowLedgerGenerics.includes(destChainInfo.slug)) {
@@ -11,6 +11,7 @@ import { CampaignDataType, ChainType, ExternalRequestPromiseStatus, ExtrinsicTyp
11
11
  import { _SUPPORT_TOKEN_PAY_FEE_GROUP, ALL_ACCOUNT_KEY, BTC_DUST_AMOUNT, LATEST_SESSION } from '@subwallet/extension-base/constants';
12
12
  import { additionalValidateTransferForRecipient, validateTransferRequest, validateXcmMinAmountToMythos, validateXcmTransferRequest } from '@subwallet/extension-base/core/logic-validation/transfer';
13
13
  import { _isSnowBridgeXcm } from '@subwallet/extension-base/core/substrate/xcm-parser';
14
+ import { ActionType } from '@subwallet/extension-base/core/types';
14
15
  import { _isSufficientToken } from '@subwallet/extension-base/core/utils';
15
16
  import { ALLOWED_PATH } from '@subwallet/extension-base/defaults';
16
17
  import { getERC20SpendingApprovalTx } from '@subwallet/extension-base/koni/api/contract-handler/evm/web3';
@@ -47,7 +48,7 @@ import { isProposalExpired, isSupportWalletConnectChain, isSupportWalletConnectN
47
48
  import { SWStorage } from '@subwallet/extension-base/storage';
48
49
  import { AccountsStore } from '@subwallet/extension-base/stores';
49
50
  import { AccountSignMode, BasicTxErrorType, BasicTxWarningCode, CommonStepType, EarningProcessType, ProcessType, StakingTxErrorType, StepStatus, SwapFeeType, YieldPoolType, YieldStepType } from '@subwallet/extension-base/types';
50
- import { _analyzeAddress, calculateMaxTransferable, combineAllAccountProxy, combineBitcoinFee, createPromiseHandler, createTransactionFromRLP, detectTransferTxType, filterUneconomicalUtxos, getAccountSignMode, getSizeInfo, getTransferableBitcoinUtxos, isSameAddress, MODULE_SUPPORT, reformatAddress, signatureToHex, transformAccounts, transformAddresses, uniqueStringArray } from '@subwallet/extension-base/utils';
51
+ import { _analyzeAddress, calculateMaxTransferable, combineAllAccountProxy, combineBitcoinFee, createPromiseHandler, createTransactionFromRLP, detectTransferTxType, filterUneconomicalUtxos, getAccountSignMode, getSizeInfo, getTransferableBitcoinUtxos, isSameAddress, isSubstrateEcdsaLedgerAssetSupported, MODULE_SUPPORT, reformatAddress, signatureToHex, transformAccounts, transformAddresses, uniqueStringArray } from '@subwallet/extension-base/utils';
51
52
  import { parseContractInput, parseEvmRlp } from '@subwallet/extension-base/utils/eth/parseTransaction';
52
53
  import { getId } from '@subwallet/extension-base/utils/getId';
53
54
  import { getKeypairTypeByAddress, isAddress, isCardanoAddress, isSubstrateAddress, isTonAddress } from '@subwallet/keyring';
@@ -296,16 +297,32 @@ export default class KoniExtension {
296
297
  }
297
298
  async subscribeInputAddressData(request, id, port) {
298
299
  const {
300
+ actionType,
299
301
  chain,
300
- data
302
+ data,
303
+ token
301
304
  } = request;
302
305
  const cb = createSubscription(id, port);
303
- const combineFunction = async (chainInfoMap, accountProxyMap, _contacts) => {
306
+ const combineFunction = async (chainInfoMap, tokenInfoMap, accountProxyMap, _contacts) => {
304
307
  const accountProxies = Object.values(accountProxyMap);
305
308
  const contacts = transformAddresses(_contacts);
306
309
  const chainInfo = chainInfoMap[chain];
310
+ const tokenInfo = tokenInfoMap[token || ''];
307
311
  const substrateApi = this.#koniState.chainService.getSubstrateApi(chain);
308
- const rs = await _analyzeAddress(data, accountProxies, contacts, chainInfo, substrateApi);
312
+ const accountProxiesFiltered = accountProxies.filter(accountProxy => {
313
+ var _accountProxy$account;
314
+ const signMode = (_accountProxy$account = accountProxy.accounts[0]) === null || _accountProxy$account === void 0 ? void 0 : _accountProxy$account.signMode;
315
+ if (signMode === AccountSignMode.ECDSA_SUBSTRATE_LEDGER) {
316
+ if (actionType === ActionType.SEND_NFT) {
317
+ return false;
318
+ }
319
+ if (tokenInfo) {
320
+ return isSubstrateEcdsaLedgerAssetSupported(tokenInfo, chainInfo);
321
+ }
322
+ }
323
+ return true;
324
+ });
325
+ const rs = await _analyzeAddress(data, accountProxiesFiltered, contacts, chainInfo, substrateApi);
309
326
  return {
310
327
  id,
311
328
  ...rs
@@ -314,16 +331,19 @@ export default class KoniExtension {
314
331
  const accountObservable = this.#koniState.keyringService.context.observable.accounts;
315
332
  const contactObservable = this.#koniState.keyringService.context.observable.contacts;
316
333
  const chainInfoMapObservable = this.#koniState.chainService.subscribeChainInfoMap().asObservable();
334
+ const tokenInfoMapObservable = this.#koniState.chainService.subscribeAssetRegistry().asObservable();
317
335
  const subscription = combineLatest({
318
336
  chainInfoMap: chainInfoMapObservable,
337
+ tokenInfoMap: tokenInfoMapObservable,
319
338
  accountProxies: accountObservable,
320
339
  contacts: contactObservable
321
340
  }).subscribe(({
322
341
  accountProxies,
323
342
  chainInfoMap,
324
- contacts
343
+ contacts,
344
+ tokenInfoMap
325
345
  }) => {
326
- combineFunction(chainInfoMap, accountProxies, contacts).then(rs => cb(rs)).catch(console.error);
346
+ combineFunction(chainInfoMap, tokenInfoMap, accountProxies, contacts).then(rs => cb(rs)).catch(console.error);
327
347
  });
328
348
  this.createUnsubscriptionHandle(id, () => {
329
349
  subscription.unsubscribe();
@@ -334,7 +354,8 @@ export default class KoniExtension {
334
354
  const accountProxyMap = this.#koniState.keyringService.context.value.accounts;
335
355
  const contacts = this.#koniState.keyringService.context.value.contacts;
336
356
  const chainInfoMap = this.#koniState.chainService.getChainInfoMap();
337
- return combineFunction(chainInfoMap, accountProxyMap, contacts);
357
+ const tokenInfoMap = this.#koniState.chainService.getAssetRegistry();
358
+ return combineFunction(chainInfoMap, tokenInfoMap, accountProxyMap, contacts);
338
359
  }
339
360
 
340
361
  /**
@@ -1242,6 +1263,8 @@ export default class KoniExtension {
1242
1263
  const isTransferLocalTokenAndPayThatTokenAsFee = !isTransferNativeToken && tokenPayFeeSlug === tokenSlug;
1243
1264
  const isCustomTokenPayFeeAssetHub = tokenPayFeeSlug && !_isNativeTokenBySlug(tokenPayFeeSlug) && _SUPPORT_TOKEN_PAY_FEE_GROUP.assetHub.includes(chain);
1244
1265
  const isCustomTokenPayFeeHydration = tokenPayFeeSlug && !_isNativeTokenBySlug(tokenPayFeeSlug) && _SUPPORT_TOKEN_PAY_FEE_GROUP.hydration.includes(chain);
1266
+ const pairFrom = keyring.getPair(from);
1267
+ const isSubstrateECDSATransaction = pairFrom.meta.isSubstrateECDSA;
1245
1268
  const extrinsicType = isTransferNativeToken ? ExtrinsicType.TRANSFER_BALANCE : ExtrinsicType.TRANSFER_TOKEN;
1246
1269
  let chainType = ChainType.SUBSTRATE;
1247
1270
  const transferAmount = {
@@ -1258,7 +1281,7 @@ export default class KoniExtension {
1258
1281
  extrinsicType
1259
1282
  });
1260
1283
  try {
1261
- if (isEthereumAddress(from) && isEthereumAddress(to) && _isTokenTransferredByEvm(transferTokenInfo)) {
1284
+ if (isEthereumAddress(from) && isEthereumAddress(to) && _isTokenTransferredByEvm(transferTokenInfo) && !isSubstrateECDSATransaction) {
1262
1285
  chainType = ChainType.EVM;
1263
1286
  const txVal = transferAll ? transferTokenAvailable.value : value || '0';
1264
1287
  const evmApi = this.#koniState.getEvmApi(chain);
@@ -26,7 +26,7 @@ import Web3 from 'web3';
26
26
  import { checkIfDenied } from '@polkadot/phishing';
27
27
  import { hexStripPrefix, isArray, isNumber, u8aToHex } from '@polkadot/util';
28
28
  import { isEthereumAddress } from '@polkadot/util-crypto';
29
- function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthTypes) {
29
+ function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthTypes, isSubstrateConnector) {
30
30
  const accountSelected = authInfo ? authInfo.isAllowed ? Object.keys(authInfo.isAllowedMap).filter(address => authInfo.isAllowedMap[address]) : [] : [];
31
31
  const authTypeFilter = ({
32
32
  json,
@@ -55,6 +55,12 @@ function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthTyp
55
55
  if (type === 'cardano' && json.meta.isReadOnly) {
56
56
  return false;
57
57
  }
58
+ const canConnectSubstrateEcdsa = (authInfo === null || authInfo === void 0 ? void 0 : authInfo.canConnectSubstrateEcdsa) && isSubstrateConnector;
59
+
60
+ // If the dApp has not connected to the Substrate type yet, we do not return Substrate ECDSA accounts.
61
+ if (type === 'ethereum' && json.meta.isSubstrateECDSA && !canConnectSubstrateEcdsa) {
62
+ return false;
63
+ }
58
64
  return true;
59
65
  } else {
60
66
  return true;
@@ -267,7 +273,8 @@ export default class KoniTabs {
267
273
  }
268
274
  async accountsListV2(url, {
269
275
  accountAuthType,
270
- anyType
276
+ anyType,
277
+ isSubstrateConnector
271
278
  }) {
272
279
  const authInfo = await this.getAuthInfo(url);
273
280
  const accountAuthTypes = [];
@@ -287,7 +294,7 @@ export default class KoniTabs {
287
294
  accountAuthTypes.push('cardano');
288
295
  }
289
296
  }
290
- return transformAccountsV2(this.#koniState.keyringService.context.pairs, anyType, authInfo, accountAuthTypes);
297
+ return transformAccountsV2(this.#koniState.keyringService.context.pairs, anyType, authInfo, accountAuthTypes, isSubstrateConnector);
291
298
  }
292
299
 
293
300
  // TODO: Update logic
@@ -311,7 +318,7 @@ export default class KoniTabs {
311
318
  }
312
319
  }
313
320
  const accounts = this.#koniState.keyringService.context.pairs;
314
- return cb(transformAccountsV2(accounts, false, authInfo, accountAuthTypes));
321
+ return cb(transformAccountsV2(accounts, false, authInfo, accountAuthTypes, true));
315
322
  }).catch(console.error);
316
323
  }),
317
324
  url
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.3.45-1",
20
+ "version": "1.3.46-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -2796,6 +2796,7 @@
2796
2796
  "require": "./cjs/utils/staticData/index.js",
2797
2797
  "default": "./utils/staticData/index.js"
2798
2798
  },
2799
+ "./utils/staticData/assetHubStaking.json": "./utils/staticData/assetHubStaking.json",
2799
2800
  "./utils/staticData/blockedActions.json": "./utils/staticData/blockedActions.json",
2800
2801
  "./utils/staticData/blockedActionsFeatures.json": "./utils/staticData/blockedActionsFeatures.json",
2801
2802
  "./utils/staticData/buyServiceInfos.json": "./utils/staticData/buyServiceInfos.json",
@@ -2855,12 +2856,12 @@
2855
2856
  "@sora-substrate/type-definitions": "^1.17.7",
2856
2857
  "@substrate/connect": "^0.8.9",
2857
2858
  "@subwallet/chain-list": "0.2.107",
2858
- "@subwallet/extension-base": "^1.3.45-1",
2859
- "@subwallet/extension-chains": "^1.3.45-1",
2860
- "@subwallet/extension-dapp": "^1.3.45-1",
2861
- "@subwallet/extension-inject": "^1.3.45-1",
2859
+ "@subwallet/extension-base": "^1.3.46-0",
2860
+ "@subwallet/extension-chains": "^1.3.46-0",
2861
+ "@subwallet/extension-dapp": "^1.3.46-0",
2862
+ "@subwallet/extension-inject": "^1.3.46-0",
2862
2863
  "@subwallet/keyring": "^0.1.12",
2863
- "@subwallet/subwallet-api-sdk": "^1.3.45-1",
2864
+ "@subwallet/subwallet-api-sdk": "^1.3.46-0",
2864
2865
  "@subwallet/ui-keyring": "^0.1.12",
2865
2866
  "@ton/core": "^0.56.3",
2866
2867
  "@ton/crypto": "^3.2.0",
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.45-1'
10
+ version: '1.3.46-0'
11
11
  };
@@ -1,29 +1,20 @@
1
+ import type { SendRequest } from '@subwallet/extension-base/page/types';
1
2
  import type { EvmProvider } from '@subwallet/extension-inject/types';
3
+ import type { JsonRpcRequest, JsonRpcResponse } from 'json-rpc-engine';
4
+ import type { RequestArguments } from 'web3-core';
2
5
  import SafeEventEmitter from '@metamask/safe-event-emitter';
3
- import { SendRequest } from '@subwallet/extension-base/page/types';
4
- import { JsonRpcRequest, JsonRpcResponse } from 'json-rpc-engine';
5
- import { RequestArguments } from 'web3-core';
6
6
  interface SendSyncJsonRpcRequest extends JsonRpcRequest<unknown> {
7
7
  method: 'net_version';
8
8
  }
9
- export default class SubWalletEvmProvider extends SafeEventEmitter implements EvmProvider {
10
- readonly isSubWallet = true;
11
- readonly isMetaMask = false;
12
- readonly version: string;
13
- protected sendMessage: SendRequest;
14
- protected _connected: boolean;
15
- constructor(sendMessage: SendRequest, version: string);
16
- get connected(): boolean;
17
- isConnected(): boolean;
18
- protected subscribeExtensionEvents(): void;
9
+ export interface SubWalletEvmProvider extends EvmProvider, SafeEventEmitter {
19
10
  enable(): Promise<string[]>;
20
- on(eventName: string | symbol, listener: (...args: any[]) => void): this;
21
- once(eventName: string | symbol, listener: (...args: any[]) => void): this;
22
- request<T>({ method, params }: RequestArguments): Promise<T>;
23
- private _sendSync;
11
+ request<T>(args: RequestArguments): Promise<T>;
24
12
  send<T>(method: string, params?: T[]): Promise<JsonRpcResponse<T>>;
25
13
  send<T>(payload: JsonRpcRequest<unknown>, callback: (error: Error | null, result?: JsonRpcResponse<T>) => void): void;
26
14
  send<T>(payload: SendSyncJsonRpcRequest): JsonRpcResponse<T>;
27
- sendAsync<T>(payload: JsonRpcRequest<T>, callback: (error: (Error | null), result?: JsonRpcResponse<T>) => void): void;
15
+ sendAsync<T>(payload: JsonRpcRequest<T>, callback: (error: Error | null, result?: JsonRpcResponse<T>) => void): void;
16
+ on(eventName: string | symbol, listener: (...args: any[]) => void): this;
17
+ once(eventName: string | symbol, listener: (...args: any[]) => void): this;
28
18
  }
19
+ export declare function createSubWalletEvmProvider(sendMessage: SendRequest, version: string): SubWalletEvmProvider;
29
20
  export {};
package/page/evm/index.js CHANGED
@@ -2,117 +2,45 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import SafeEventEmitter from '@metamask/safe-event-emitter';
5
- let subscribeFlag = false;
6
- export default class SubWalletEvmProvider extends SafeEventEmitter {
7
- isSubWallet = true;
8
- isMetaMask = false;
9
- _connected = false;
10
- constructor(sendMessage, version) {
11
- super();
12
- this.version = version;
13
- this.sendMessage = sendMessage;
14
- this._connected = true;
15
- }
16
- get connected() {
17
- return this._connected;
18
- }
19
- isConnected() {
20
- return this._connected;
21
- }
22
- subscribeExtensionEvents() {
5
+ export function createSubWalletEvmProvider(sendMessage, version) {
6
+ const emitter = new SafeEventEmitter();
7
+ let connected = true;
8
+ let subscribeFlag = false;
9
+ const provider = Object.assign(emitter, {
10
+ isSubWallet: true,
11
+ isMetaMask: false,
12
+ version
13
+ });
14
+ function subscribeExtensionEvents() {
23
15
  if (subscribeFlag) {
24
16
  return;
25
17
  }
26
- this.sendMessage('evm(events.subscribe)', null, ({
18
+ sendMessage('evm(events.subscribe)', null, ({
27
19
  payload,
28
20
  type
29
21
  }) => {
30
22
  if (['connect', 'disconnect', 'accountsChanged', 'chainChanged', 'message', 'data', 'reconnect', 'error'].includes(type)) {
31
23
  if (type === 'connect') {
32
- this._connected = true;
24
+ connected = true;
33
25
  } else if (type === 'disconnect') {
34
- this._connected = false;
26
+ connected = false;
35
27
  }
36
28
  const finalType = type === 'data' ? 'message' : type;
37
-
38
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
39
- this.emit(finalType, payload);
29
+ emitter.emit(finalType, payload);
40
30
  } else {
41
31
  console.warn('Can not handle event', type, payload);
42
32
  }
43
- }).then(done => {
33
+ }).then(() => {
44
34
  subscribeFlag = true;
45
35
  }).catch(() => {
46
36
  subscribeFlag = false;
47
37
  });
48
- subscribeFlag = true;
49
- }
50
- async enable() {
51
- return this.request({
52
- method: 'eth_requestAccounts'
53
- });
54
- }
55
- on(eventName, listener) {
56
- this.subscribeExtensionEvents();
57
- super.on(eventName, listener);
58
- return this;
59
38
  }
60
- once(eventName, listener) {
61
- this.subscribeExtensionEvents();
62
- super.once(eventName, listener);
63
- return this;
64
- }
65
- request({
66
- method,
67
- params
68
- }) {
69
- // if (!this._isEnable) {
70
- // if (method === 'eth_accounts') {
71
- // return this.request<T>({ method: 'eth_requestAccounts' });
72
- // }
73
- // }
74
-
75
- // Subscribe events
76
- switch (method) {
77
- case 'eth_requestAccounts':
78
- return new Promise((resolve, reject) => {
79
- const origin = document.title !== '' ? document.title : window.location.hostname;
80
- this.sendMessage('pub(authorize.tabV2)', {
81
- origin,
82
- accountAuthTypes: ['evm']
83
- }).then(() => {
84
- // Return account list
85
- this.request({
86
- method: 'eth_accounts'
87
- }).then(accounts => {
88
- // @ts-ignore
89
- resolve(accounts);
90
- }).catch(e => {
91
- reject(e);
92
- });
93
- }).catch(e => {
94
- reject(e);
95
- });
96
- });
97
- default:
98
- return new Promise((resolve, reject) => {
99
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
100
- this.sendMessage('evm(request)', {
101
- params,
102
- method
103
- }).then(result => {
104
- resolve(result);
105
- }).catch(e => {
106
- reject(e);
107
- });
108
- });
109
- }
110
- }
111
- _sendSync(payload) {
39
+ const _sendSync = payload => {
112
40
  let result;
113
41
  switch (payload.method) {
114
42
  case 'net_version':
115
- result = this.version ? `SubWallet v${this.version}` : null;
43
+ result = version ? `SubWallet v${version}` : null;
116
44
  break;
117
45
  default:
118
46
  throw new Error(`Not support ${payload.method}`);
@@ -122,28 +50,61 @@ export default class SubWalletEvmProvider extends SafeEventEmitter {
122
50
  jsonrpc: payload.jsonrpc,
123
51
  result
124
52
  };
125
- }
126
- send(methodOrPayload, callbackOrArgs) {
53
+ };
54
+ provider.isConnected = () => connected;
55
+ provider.request = arg => {
56
+ if (arg.method === 'eth_requestAccounts') {
57
+ const origin = document.title || window.location.hostname;
58
+ return sendMessage('pub(authorize.tabV2)', {
59
+ origin,
60
+ accountAuthTypes: ['evm']
61
+ }).then(() => provider.request({
62
+ method: 'eth_accounts'
63
+ }));
64
+ }
65
+ return sendMessage('evm(request)', arg);
66
+ };
67
+ provider.send = (methodOrPayload, callbackOrArgs) => {
127
68
  if (typeof methodOrPayload === 'string' && (!callbackOrArgs || Array.isArray(callbackOrArgs))) {
128
- return this.request({
69
+ return provider.request({
129
70
  method: methodOrPayload,
130
71
  params: callbackOrArgs
131
72
  });
132
- } else if (methodOrPayload && typeof methodOrPayload === 'object' && typeof callbackOrArgs === 'function') {
133
- return this.request(methodOrPayload).then(rs => {
134
- callbackOrArgs(rs);
73
+ } else if (typeof methodOrPayload === 'object' && typeof callbackOrArgs === 'function') {
74
+ return provider.request(methodOrPayload).then(result => {
75
+ callbackOrArgs(null, result);
135
76
  });
136
77
  }
137
- return this._sendSync(methodOrPayload);
138
- }
139
- sendAsync(payload, callback) {
140
- this.request(payload).then(result => {
141
- // @ts-ignore
78
+ return _sendSync(methodOrPayload);
79
+ };
80
+ provider.enable = async () => {
81
+ const accounts = await provider.request({
82
+ method: 'eth_requestAccounts'
83
+ });
84
+ connected = accounts.length > 0;
85
+ return accounts;
86
+ };
87
+ provider.sendAsync = (payload, callback) => {
88
+ provider.request(payload).then(result => {
142
89
  callback(null, {
90
+ id: payload.id,
91
+ jsonrpc: payload.jsonrpc,
92
+ // @ts-ignore
143
93
  result
144
94
  });
145
95
  }).catch(e => {
146
96
  callback(e);
147
97
  });
148
- }
98
+ };
99
+ provider.on = (eventName, listener) => {
100
+ subscribeExtensionEvents();
101
+ SafeEventEmitter.prototype.on.call(emitter, eventName, listener);
102
+ return provider;
103
+ };
104
+ provider.once = (eventName, listener) => {
105
+ subscribeExtensionEvents();
106
+ SafeEventEmitter.prototype.once.call(emitter, eventName, listener);
107
+ return provider;
108
+ };
109
+ return provider;
149
110
  }
package/page/index.js CHANGED
@@ -5,7 +5,7 @@ import { ProviderError } from '@subwallet/extension-base/background/errors/Provi
5
5
  import { ProviderErrorType } from '@subwallet/extension-base/background/KoniTypes';
6
6
  import SubWalletBitcoinProvider from '@subwallet/extension-base/page/bitcoin';
7
7
  import SubWalletCardanoProvider from '@subwallet/extension-base/page/cardano';
8
- import SubWalletEvmProvider from '@subwallet/extension-base/page/evm';
8
+ import { createSubWalletEvmProvider } from '@subwallet/extension-base/page/evm';
9
9
  import Injected from '@subwallet/extension-base/page/substrate';
10
10
  import { MESSAGE_ORIGIN_PAGE } from "../defaults.js";
11
11
  import { getId } from "../utils/getId.js";
@@ -43,9 +43,11 @@ export function sendMessage(message, request, subscriber) {
43
43
 
44
44
  export async function enable(origin, opt) {
45
45
  const accountAuthTypes = (opt === null || opt === void 0 ? void 0 : opt.accountAuthType) === 'both' ? ['substrate', 'evm'] : [(opt === null || opt === void 0 ? void 0 : opt.accountAuthType) || 'substrate'];
46
+ const canConnectSubstrateEcdsa = accountAuthTypes.includes('evm');
46
47
  await sendMessage('pub(authorize.tabV2)', {
47
48
  origin,
48
- accountAuthTypes
49
+ accountAuthTypes,
50
+ canConnectSubstrateEcdsa
49
51
  });
50
52
  return new Injected(sendMessage);
51
53
  }
@@ -69,7 +71,7 @@ export function handleResponse(data) {
69
71
  }
70
72
  }
71
73
  export function initEvmProvider(version) {
72
- return new SubWalletEvmProvider(sendMessage, version);
74
+ return createSubWalletEvmProvider(sendMessage, version);
73
75
  }
74
76
  export function initCardanoProvider() {
75
77
  return new SubWalletCardanoProvider(sendMessage);
@@ -9,7 +9,8 @@ export default class Accounts {
9
9
  }
10
10
  get(anyType) {
11
11
  return sendRequest('pub(accounts.listV2)', {
12
- anyType
12
+ anyType,
13
+ isSubstrateConnector: true
13
14
  });
14
15
  }
15
16
  subscribe(cb) {
@@ -1,15 +1,5 @@
1
1
  import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
3
3
  import { _BitcoinApi, _CardanoApi, _EvmApi, _SubstrateApi, _TonApi } from '@subwallet/extension-base/services/chain-service/types';
4
- import { AccountJson, BalanceItem } from '@subwallet/extension-base/types';
5
- /**
6
- * @function getAccountJsonByAddress
7
- * @desc Get account info by address
8
- * <p>
9
- * Note: Use on the background only
10
- * </p>
11
- * @param {string} address - Address
12
- * @returns {AccountJson|null} - Account info or null if not found
13
- */
14
- export declare const getAccountJsonByAddress: (address: string) => AccountJson | null;
4
+ import { BalanceItem } from '@subwallet/extension-base/types';
15
5
  export declare function subscribeBalance(addresses: string[], chains: string[], tokens: string[], _chainAssetMap: Record<string, _ChainAsset>, _chainInfoMap: Record<string, _ChainInfo>, substrateApiMap: Record<string, _SubstrateApi>, evmApiMap: Record<string, _EvmApi>, tonApiMap: Record<string, _TonApi>, cardanoApiMap: Record<string, _CardanoApi>, bitcoinApiMap: Record<string, _BitcoinApi>, callback: (rs: BalanceItem[]) => void, extrinsicType?: ExtrinsicType): () => void;
@@ -5,82 +5,11 @@ import { _AssetType } from '@subwallet/chain-list/types';
5
5
  import { APIItemState } from '@subwallet/extension-base/background/KoniTypes';
6
6
  import { subscribeBitcoinBalance } from '@subwallet/extension-base/services/balance-service/helpers/subscribe/bitcoin';
7
7
  import { subscribeCardanoBalance } from '@subwallet/extension-base/services/balance-service/helpers/subscribe/cardano';
8
- import { _getSubstrateGenesisHash, _isChainBitcoinCompatible, _isChainCardanoCompatible, _isChainEvmCompatible, _isChainTonCompatible, _isPureBitcoinChain, _isPureCardanoChain, _isPureEvmChain, _isPureTonChain } from '@subwallet/extension-base/services/chain-service/utils';
9
- import { filterAssetsByChainAndType, getAddressesByChainTypeMap, pairToAccount } from '@subwallet/extension-base/utils';
10
- import keyring from '@subwallet/ui-keyring';
8
+ import { _isPureBitcoinChain, _isPureCardanoChain, _isPureEvmChain, _isPureTonChain } from '@subwallet/extension-base/services/chain-service/utils';
9
+ import { filterAddressByChainInfo, filterAssetsByChainAndType } from '@subwallet/extension-base/utils';
11
10
  import { subscribeTonBalance } from "./ton/ton.js";
12
11
  import { subscribeEVMBalance } from "./evm.js";
13
12
  import { subscribeSubstrateBalance } from "./substrate/index.js";
14
-
15
- /**
16
- * @function getAccountJsonByAddress
17
- * @desc Get account info by address
18
- * <p>
19
- * Note: Use on the background only
20
- * </p>
21
- * @param {string} address - Address
22
- * @returns {AccountJson|null} - Account info or null if not found
23
- */
24
- export const getAccountJsonByAddress = address => {
25
- try {
26
- const pair = keyring.getPair(address);
27
- if (pair) {
28
- return pairToAccount(pair);
29
- } else {
30
- return null;
31
- }
32
- } catch (e) {
33
- console.warn(e);
34
- return null;
35
- }
36
- };
37
-
38
- /** Filter addresses to subscribe by chain info */
39
- const filterAddress = (addresses, chainInfo) => {
40
- const {
41
- _bitcoin,
42
- bitcoin,
43
- cardano,
44
- evm,
45
- substrate,
46
- ton
47
- } = getAddressesByChainTypeMap(addresses, chainInfo);
48
- if (_isChainEvmCompatible(chainInfo)) {
49
- return [evm, [bitcoin, substrate, ton, cardano, _bitcoin].flat()];
50
- } else if (_isChainBitcoinCompatible(chainInfo)) {
51
- return [bitcoin, [evm, substrate, ton, cardano, _bitcoin].flat()];
52
- } else if (_isChainTonCompatible(chainInfo)) {
53
- return [ton, [bitcoin, evm, substrate, cardano, _bitcoin].flat()];
54
- } else if (_isChainCardanoCompatible(chainInfo)) {
55
- return [cardano, [bitcoin, evm, substrate, ton, _bitcoin].flat()];
56
- } else {
57
- const fetchList = [];
58
- const unfetchList = [];
59
- substrate.forEach(address => {
60
- const account = getAccountJsonByAddress(address);
61
- if (account) {
62
- if (account.isHardware) {
63
- if (account.isGeneric) {
64
- fetchList.push(address);
65
- } else {
66
- const availGen = account.availableGenesisHashes || [];
67
- const gen = _getSubstrateGenesisHash(chainInfo);
68
- if (availGen.includes(gen)) {
69
- fetchList.push(address);
70
- } else {
71
- unfetchList.push(address);
72
- }
73
- }
74
- } else {
75
- fetchList.push(address);
76
- }
77
- } else {
78
- fetchList.push(address);
79
- }
80
- });
81
- return [fetchList, [unfetchList, bitcoin, evm, ton, cardano, _bitcoin].flat()];
82
- }
83
- };
84
13
  const handleUnsupportedOrPendingAddresses = (addresses, chainSlug, chainAssetMap, state, callback) => {
85
14
  const tokens = filterAssetsByChainAndType(chainAssetMap, chainSlug, [_AssetType.NATIVE, _AssetType.ERC20, _AssetType.PSP22, _AssetType.LOCAL, _AssetType.GRC20, _AssetType.VFT, _AssetType.TEP74, _AssetType.CIP26]);
86
15
  const now = new Date().getTime();
@@ -106,7 +35,7 @@ export function subscribeBalance(addresses, chains, tokens, _chainAssetMap, _cha
106
35
  // Looping over each chain
107
36
  const unsubList = Object.values(chainInfoMap).map(async chainInfo => {
108
37
  const chainSlug = chainInfo.slug;
109
- const [useAddresses, notSupportAddresses] = filterAddress(addresses, chainInfo);
38
+ const [useAddresses, notSupportAddresses] = filterAddressByChainInfo(addresses, chainInfo);
110
39
  if (notSupportAddresses.length) {
111
40
  handleUnsupportedOrPendingAddresses(notSupportAddresses, chainSlug, chainAssetMap, APIItemState.NOT_SUPPORT, callback);
112
41
  }
@@ -140,6 +140,7 @@ export declare class ChainService {
140
140
  private fetchLatestLedgerGenericAllowChains;
141
141
  private fetchLatestPriorityTokens;
142
142
  private fetchLatestSufficientChains;
143
+ fetchAhMapChain(): Promise<Record<string, string>>;
143
144
  private initChains;
144
145
  private initAssetRegistry;
145
146
  private updateChainStateMapSubscription;