@subwallet/extension-base 1.2.24-2 → 1.2.25-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 (60) hide show
  1. package/background/KoniTypes.d.ts +9 -0
  2. package/background/errors/EvmProviderError.d.ts +1 -1
  3. package/background/errors/EvmProviderError.js +2 -2
  4. package/background/errors/SWError.d.ts +1 -1
  5. package/background/errors/SWError.js +4 -1
  6. package/background/errors/TransactionError.d.ts +1 -1
  7. package/background/errors/TransactionError.js +2 -2
  8. package/cjs/background/errors/EvmProviderError.js +2 -2
  9. package/cjs/background/errors/SWError.js +4 -1
  10. package/cjs/background/errors/TransactionError.js +2 -2
  11. package/cjs/core/logic-validation/index.js +49 -0
  12. package/cjs/core/logic-validation/request.js +488 -0
  13. package/cjs/core/logic-validation/transfer.js +25 -8
  14. package/cjs/koni/api/staking/bonding/utils.js +2 -2
  15. package/cjs/koni/background/handlers/Extension.js +33 -8
  16. package/cjs/koni/background/handlers/State.js +41 -160
  17. package/cjs/koni/background/handlers/Tabs.js +35 -33
  18. package/cjs/packageInfo.js +1 -1
  19. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +16 -8
  20. package/cjs/services/chain-service/constants.js +6 -1
  21. package/cjs/services/chain-service/index.js +32 -2
  22. package/cjs/services/chain-service/utils/index.js +2 -2
  23. package/cjs/services/earning-service/constants/chains.js +2 -2
  24. package/cjs/services/earning-service/handlers/liquid-staking/bifrost.js +1 -1
  25. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +5 -4
  26. package/cjs/services/earning-service/service.js +1 -1
  27. package/cjs/services/event-service/index.js +1 -0
  28. package/cjs/services/request-service/handler/EvmRequestHandler.js +2 -1
  29. package/cjs/services/transaction-service/index.js +11 -7
  30. package/cjs/services/wallet-connect-service/handler/Eip155RequestHandler.js +12 -36
  31. package/core/logic-validation/index.d.ts +4 -0
  32. package/core/logic-validation/index.js +7 -0
  33. package/core/logic-validation/request.d.ts +23 -0
  34. package/core/logic-validation/request.js +475 -0
  35. package/core/logic-validation/transfer.d.ts +1 -1
  36. package/core/logic-validation/transfer.js +25 -8
  37. package/koni/api/staking/bonding/utils.js +2 -2
  38. package/koni/background/handlers/Extension.d.ts +1 -0
  39. package/koni/background/handlers/Extension.js +33 -8
  40. package/koni/background/handlers/State.d.ts +2 -2
  41. package/koni/background/handlers/State.js +42 -161
  42. package/koni/background/handlers/Tabs.d.ts +0 -1
  43. package/koni/background/handlers/Tabs.js +36 -34
  44. package/package.json +16 -6
  45. package/packageInfo.js +1 -1
  46. package/services/balance-service/helpers/subscribe/substrate/index.js +16 -8
  47. package/services/chain-service/constants.js +6 -1
  48. package/services/chain-service/index.d.ts +9 -0
  49. package/services/chain-service/index.js +32 -2
  50. package/services/chain-service/utils/index.js +2 -2
  51. package/services/earning-service/constants/chains.js +2 -2
  52. package/services/earning-service/handlers/liquid-staking/bifrost.js +1 -1
  53. package/services/earning-service/handlers/native-staking/relay-chain.js +5 -4
  54. package/services/earning-service/service.js +1 -1
  55. package/services/event-service/index.d.ts +1 -0
  56. package/services/event-service/index.js +1 -0
  57. package/services/event-service/types.d.ts +1 -0
  58. package/services/request-service/handler/EvmRequestHandler.js +2 -1
  59. package/services/transaction-service/index.js +11 -7
  60. package/services/wallet-connect-service/handler/Eip155RequestHandler.js +9 -33
@@ -7,7 +7,7 @@ import { OptionalSWTransaction, SWTransactionInput, SWTransactionResponse } from
7
7
  import { KeyringPair } from '@subwallet/keyring/types';
8
8
  import BigN from 'bignumber.js';
9
9
  export declare function validateTransferRequest(tokenInfo: _ChainAsset, from: _Address, to: _Address, value: string | undefined, transferAll: boolean | undefined): [TransactionError[], KeyringPair | undefined, BigN | undefined];
10
- export declare function additionalValidateTransfer(tokenInfo: _ChainAsset, extrinsicType: ExtrinsicType, receiverTransferTokenFreeBalance: string, transferAmount: string, senderTransferTokenTransferable?: string): [TransactionWarning | undefined, TransactionError | undefined];
10
+ export declare function additionalValidateTransfer(tokenInfo: _ChainAsset, nativeTokenInfo: _ChainAsset, extrinsicType: ExtrinsicType, receiverTransferTokenFreeBalance: string, transferAmount: string, senderTransferTokenTransferable?: string, receiverNativeTransferable?: string): [TransactionWarning[], TransactionError[]];
11
11
  export declare function validateXcmTransferRequest(destTokenInfo: _ChainAsset | undefined, sender: _Address, sendingValue: string): [TransactionError[], KeyringPair | undefined, BigN | undefined];
12
12
  export declare function additionalValidateXcmTransfer(originTokenInfo: _ChainAsset, destinationTokenInfo: _ChainAsset, sendingAmount: string, senderTransferable: string, receiverNativeBalance: string, destChainInfo: _ChainInfo, isSnowBridge?: boolean): [TransactionWarning | undefined, TransactionError | undefined];
13
13
  export declare function checkSupportForTransaction(validationResponse: SWTransactionResponse, transaction: OptionalSWTransaction): void;
@@ -37,32 +37,49 @@ export function validateTransferRequest(tokenInfo, from, to, value, transferAll)
37
37
  }
38
38
  return [errors, keypair, transferValue];
39
39
  }
40
- export function additionalValidateTransfer(tokenInfo, extrinsicType, receiverTransferTokenFreeBalance, transferAmount, senderTransferTokenTransferable) {
40
+ export function additionalValidateTransfer(tokenInfo, nativeTokenInfo, extrinsicType, receiverTransferTokenFreeBalance, transferAmount, senderTransferTokenTransferable, receiverNativeTransferable) {
41
41
  const minAmount = _getTokenMinAmount(tokenInfo);
42
- let warning;
43
- let error;
42
+ const nativeMinAmount = _getTokenMinAmount(nativeTokenInfo);
43
+ const warnings = [];
44
+ const errors = [];
44
45
 
45
- // Check ed of not native token for sender
46
+ // Check ed of not native token for sender after sending
46
47
  if (extrinsicType === ExtrinsicType.TRANSFER_TOKEN && senderTransferTokenTransferable) {
47
48
  if (new BigN(senderTransferTokenTransferable).minus(transferAmount).lt(minAmount)) {
48
- warning = new TransactionWarning(BasicTxWarningCode.NOT_ENOUGH_EXISTENTIAL_DEPOSIT);
49
+ const warning = new TransactionWarning(BasicTxWarningCode.NOT_ENOUGH_EXISTENTIAL_DEPOSIT);
50
+ warnings.push(warning);
51
+ }
52
+ }
53
+
54
+ // Check ed for receiver before sending
55
+ if (extrinsicType === ExtrinsicType.TRANSFER_TOKEN && receiverNativeTransferable) {
56
+ if (new BigN(receiverNativeTransferable).lt(nativeMinAmount)) {
57
+ const error = new TransactionError(TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, t('The recipient account has {{amount}} {{nativeSymbol}} which can lead to your {{localSymbol}} being lost. Change recipient account and try again', {
58
+ replace: {
59
+ amount: receiverNativeTransferable,
60
+ nativeSymbol: nativeTokenInfo.symbol,
61
+ localSymbol: tokenInfo.symbol
62
+ }
63
+ }));
64
+ errors.push(error);
49
65
  }
50
66
  }
51
67
 
52
- // Check ed for receiver
68
+ // Check ed for receiver after sending
53
69
  if (new BigN(receiverTransferTokenFreeBalance).plus(transferAmount).lt(minAmount)) {
54
70
  const atLeast = new BigN(minAmount).minus(receiverTransferTokenFreeBalance).plus((tokenInfo.decimals || 0) === 0 ? 0 : 1);
55
71
  const atLeastStr = formatNumber(atLeast, tokenInfo.decimals || 0, balanceFormatter, {
56
72
  maxNumberFormat: tokenInfo.decimals || 6
57
73
  });
58
- error = new TransactionError(TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, t('You must transfer at least {{amount}} {{symbol}} to keep the destination account alive', {
74
+ const error = new TransactionError(TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, t('You must transfer at least {{amount}} {{symbol}} to keep the destination account alive', {
59
75
  replace: {
60
76
  amount: atLeastStr,
61
77
  symbol: tokenInfo.symbol
62
78
  }
63
79
  }));
80
+ errors.push(error);
64
81
  }
65
- return [warning, error];
82
+ return [warnings, errors];
66
83
  }
67
84
 
68
85
  // xcm transfer
@@ -88,7 +88,7 @@ export function calculateChainStakedReturnV2(chainInfo, totalIssuance, erasPerDa
88
88
  const multiplier = dayRewardRate.dividedBy(100).plus(1).exponentiatedBy(365);
89
89
  inflationToStakers = new BigNumber(100).multipliedBy(multiplier).minus(100);
90
90
  }
91
- const averageRewardRate = (['avail_mainnet'].includes(chainInfo.slug) ? inflation : inflationToStakers).dividedBy(supplyStaked);
91
+ const averageRewardRate = (['avail_mainnet', 'dentnet'].includes(chainInfo.slug) ? inflation : inflationToStakers).dividedBy(supplyStaked);
92
92
  return averageRewardRate.toNumber();
93
93
  }
94
94
  export function calculateAlephZeroValidatorReturn(chainStakedReturn, commission) {
@@ -345,7 +345,7 @@ export function getAvgValidatorEraReward(supportedDays, eraRewardHistory) {
345
345
  return sumEraReward.dividedBy(new BigNumber(supportedDays - failEra));
346
346
  }
347
347
  export function getSupportedDaysByHistoryDepth(erasPerDay, maxSupportedEras, liveDay) {
348
- const maxSupportDay = maxSupportedEras / erasPerDay;
348
+ const maxSupportDay = Math.floor(maxSupportedEras / erasPerDay);
349
349
  if (liveDay && liveDay <= 30) {
350
350
  return Math.min(liveDay - 1, maxSupportDay);
351
351
  }
@@ -255,5 +255,6 @@ export default class KoniExtension {
255
255
  private getLatestSwapQuote;
256
256
  private validateSwapProcess;
257
257
  private handleSwapStep;
258
+ private subscribeLedgerGenericAllowChains;
258
259
  handle<TMessageType extends MessageTypes>(id: string, type: TMessageType, request: RequestTypes[TMessageType], port: chrome.runtime.Port): Promise<ResponseType<TMessageType>>;
259
260
  }
@@ -1647,18 +1647,23 @@ export default class KoniExtension {
1647
1647
  const transferNativeAmount = isTransferNativeToken ? transferAmount.value : '0';
1648
1648
  const additionalValidator = async inputTransaction => {
1649
1649
  let senderTransferTokenTransferable;
1650
+ let receiverNativeTransferable;
1650
1651
 
1651
1652
  // Check ed for sender
1652
1653
  if (!isTransferNativeToken) {
1653
- const {
1654
- value
1655
- } = await this.getAddressTransferableBalance({
1654
+ const [_senderTransferTokenTransferable, _receiverNativeTransferable] = await Promise.all([this.getAddressTransferableBalance({
1656
1655
  address: from,
1657
1656
  networkKey,
1658
1657
  token: tokenSlug,
1659
1658
  extrinsicType
1660
- });
1661
- senderTransferTokenTransferable = value;
1659
+ }), this.getAddressTransferableBalance({
1660
+ address: to,
1661
+ networkKey,
1662
+ token: nativeTokenSlug,
1663
+ extrinsicType: ExtrinsicType.TRANSFER_BALANCE
1664
+ })]);
1665
+ senderTransferTokenTransferable = _senderTransferTokenTransferable.value;
1666
+ receiverNativeTransferable = _receiverNativeTransferable.value;
1662
1667
  }
1663
1668
  const {
1664
1669
  value: receiverTransferTokenTransferable
@@ -1669,9 +1674,9 @@ export default class KoniExtension {
1669
1674
  extrinsicType
1670
1675
  }); // todo: shouldn't be just transferable, locked also counts
1671
1676
 
1672
- const [warning, error] = additionalValidateTransfer(transferTokenInfo, extrinsicType, receiverTransferTokenTransferable, transferAmount.value, senderTransferTokenTransferable);
1673
- warning && inputTransaction.warnings.push(warning);
1674
- error && inputTransaction.errors.push(error);
1677
+ const [warnings, errors] = additionalValidateTransfer(transferTokenInfo, nativeTokenInfo, extrinsicType, receiverTransferTokenTransferable, transferAmount.value, senderTransferTokenTransferable, receiverNativeTransferable);
1678
+ warnings.length && inputTransaction.warnings.push(...warnings);
1679
+ errors.length && inputTransaction.errors.push(...errors);
1675
1680
  };
1676
1681
  return this.#koniState.transactionService.handleTransaction({
1677
1682
  errors,
@@ -4143,6 +4148,21 @@ export default class KoniExtension {
4143
4148
  }
4144
4149
  /* Swap service */
4145
4150
 
4151
+ /* Ledger */
4152
+
4153
+ async subscribeLedgerGenericAllowChains(id, port) {
4154
+ const cb = createSubscription(id, port);
4155
+ await this.#koniState.eventService.waitLedgerReady;
4156
+ const subscription = this.#koniState.chainService.observable.ledgerGenericAllowChains.subscribe(cb);
4157
+ this.createUnsubscriptionHandle(id, subscription.unsubscribe);
4158
+ port.onDisconnect.addListener(() => {
4159
+ this.cancelSubscription(id);
4160
+ });
4161
+ return this.#koniState.chainService.value.ledgerGenericAllowChains;
4162
+ }
4163
+
4164
+ /* Ledger */
4165
+
4146
4166
  // --------------------------------------------------------------
4147
4167
  // eslint-disable-next-line @typescript-eslint/require-await
4148
4168
  async handle(id, type, request, port) {
@@ -4707,6 +4727,11 @@ export default class KoniExtension {
4707
4727
  case 'pri(swapService.handleSwapStep)':
4708
4728
  return this.handleSwapStep(request);
4709
4729
  /* Swap service */
4730
+
4731
+ /* Ledger */
4732
+ case 'pri(ledger.generic.allow)':
4733
+ return this.subscribeLedgerGenericAllowChains(id, port);
4734
+ /* Ledger */
4710
4735
  // Default
4711
4736
  default:
4712
4737
  throw new Error(`Unable to handle message of type ${type}`);
@@ -217,9 +217,9 @@ export default class KoniState {
217
217
  accountExportPrivateKey({ address, password }: RequestAccountExportPrivateKey): ResponseAccountExportPrivateKey;
218
218
  checkPublicAndSecretKey({ publicKey, secretKey }: RequestCheckPublicAndSecretKey): ResponseCheckPublicAndSecretKey;
219
219
  getEthKeyring(address: string, password: string): Promise<SimpleKeyring>;
220
- evmSign(id: string, url: string, method: string, params: any, allowedAccounts: string[]): Promise<string | undefined>;
220
+ evmSign(id: string, url: string, method: string, params: any, topic?: string): Promise<string | undefined>;
221
221
  calculateAllGasFeeOnChain(activeEvmChains: string[], timeout?: number): Promise<Record<string, EvmFeeInfo | null>>;
222
- evmSendTransaction(id: string, url: string, networkKey: string, allowedAccounts: string[], transactionParams: EvmSendTransactionParams): Promise<string | undefined>;
222
+ evmSendTransaction(id: string, url: string, transactionParams: EvmSendTransactionParams, networkKeyInit?: string, topic?: string): Promise<string | undefined>;
223
223
  getConfirmationsQueueSubject(): BehaviorSubject<ConfirmationsQueue>;
224
224
  completeConfirmation(request: RequestConfirmationComplete): Promise<boolean>;
225
225
  private onMV3Update;
@@ -6,6 +6,7 @@ import { withErrorLog } from '@subwallet/extension-base/background/handlers/help
6
6
  import { isSubscriptionRunning, unsubscribe } from '@subwallet/extension-base/background/handlers/subscriptions';
7
7
  import { APIItemState, BasicTxErrorType, ChainType, EvmProviderErrorType, ExternalRequestPromiseStatus, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
8
8
  import { ALL_ACCOUNT_KEY, ALL_GENESIS_HASH, MANTA_PAY_BALANCE_INTERVAL, REMIND_EXPORT_ACCOUNT } from '@subwallet/extension-base/constants';
9
+ import { generateValidationProcess, validationAuthMiddleware, validationAuthWCMiddleware, validationConnectMiddleware, validationEvmDataTransactionMiddleware, validationEvmSignMessageMiddleware } from '@subwallet/extension-base/core/logic-validation';
9
10
  import { BalanceService } from '@subwallet/extension-base/services/balance-service';
10
11
  import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
11
12
  import BuyService from '@subwallet/extension-base/services/buy-service';
@@ -34,12 +35,10 @@ import TransactionService from '@subwallet/extension-base/services/transaction-s
34
35
  import WalletConnectService from '@subwallet/extension-base/services/wallet-connect-service';
35
36
  import { SWStorage } from '@subwallet/extension-base/storage';
36
37
  import AccountRefStore from '@subwallet/extension-base/stores/AccountRef';
37
- import { isAccountAll, stripUrl, targetIsWeb, wait } from '@subwallet/extension-base/utils';
38
- import { isContractAddress, parseContractInput } from '@subwallet/extension-base/utils/eth/parseTransaction';
38
+ import { isAccountAll, stripUrl, targetIsWeb } from '@subwallet/extension-base/utils';
39
39
  import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
40
40
  import { decodePair } from '@subwallet/keyring/pair/decode';
41
41
  import { keyring } from '@subwallet/ui-keyring';
42
- import BigN from 'bignumber.js';
43
42
  import BN from 'bn.js';
44
43
  import SimpleKeyring from 'eth-simple-keyring';
45
44
  import { t } from 'i18next';
@@ -52,6 +51,7 @@ import { KoniSubscription } from "../subscription.js";
52
51
  // eslint-disable-next-line @typescript-eslint/no-var-requires,@typescript-eslint/no-unsafe-assignment
53
52
  const passworder = require('browser-passworder');
54
53
  const ETH_DERIVE_DEFAULT = '/m/44\'/60\'/0\'/0/0';
54
+ const ERROR_CONFIRMATION_TYPE = ['errorConnectNetwork'];
55
55
 
56
56
  // List of providers passed into constructor. This is the list of providers
57
57
  // exposed by the extension.
@@ -1078,7 +1078,7 @@ export default class KoniState {
1078
1078
  resolve(ethKeyring);
1079
1079
  });
1080
1080
  }
1081
- async evmSign(id, url, method, params, allowedAccounts) {
1081
+ async evmSign(id, url, method, params, topic) {
1082
1082
  let address = '';
1083
1083
  let payload;
1084
1084
  const [p1, p2] = params;
@@ -1089,60 +1089,21 @@ export default class KoniState {
1089
1089
  address = p2;
1090
1090
  payload = p1;
1091
1091
  }
1092
- if (address === '' || !payload) {
1093
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Not found address or payload to sign'));
1094
- }
1095
- if (['eth_sign', 'personal_sign', 'eth_signTypedData', 'eth_signTypedData_v1', 'eth_signTypedData_v3', 'eth_signTypedData_v4'].indexOf(method) < 0) {
1096
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Unsupported action'));
1097
- }
1098
- if (['eth_signTypedData_v3', 'eth_signTypedData_v4'].indexOf(method) > -1) {
1099
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-assignment
1100
- payload = JSON.parse(payload);
1101
- }
1102
-
1103
- // Check sign abiblity
1104
- if (!allowedAccounts.find(acc => acc.toLowerCase() === address.toLowerCase())) {
1105
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('You have rescinded allowance for this account in wallet'));
1106
- }
1107
- const pair = keyring.getPair(address);
1108
- if (!pair) {
1109
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Unable to find account'));
1110
- }
1111
- const account = {
1112
- address: pair.address,
1113
- ...pair.meta
1092
+ const payloadValidation = {
1093
+ address,
1094
+ payloadAfterValidated: payload,
1095
+ method,
1096
+ errors: [],
1097
+ networkKey: ''
1114
1098
  };
1115
- let hashPayload = '';
1116
- let canSign = false;
1117
- switch (method) {
1118
- case 'personal_sign':
1119
- canSign = true;
1120
- hashPayload = payload;
1121
- break;
1122
- case 'eth_sign':
1123
- case 'eth_signTypedData':
1124
- case 'eth_signTypedData_v1':
1125
- case 'eth_signTypedData_v3':
1126
- case 'eth_signTypedData_v4':
1127
- if (!account.isExternal) {
1128
- canSign = true;
1129
- }
1130
- break;
1131
- default:
1132
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Unsupported action'));
1133
- }
1134
- const signPayload = {
1135
- account: account,
1136
- type: method,
1137
- payload: payload,
1138
- hashPayload: hashPayload,
1139
- canSign: canSign,
1099
+ const validationSteps = [topic ? validationAuthWCMiddleware : validationAuthMiddleware, validationEvmSignMessageMiddleware];
1100
+ const result = await generateValidationProcess(this, url, payloadValidation, validationSteps, topic);
1101
+ const payloadAfterValidated = {
1102
+ ...result.payloadAfterValidated,
1103
+ errors: result.errors,
1140
1104
  id
1141
1105
  };
1142
- return this.requestService.addConfirmation(id, url, 'evmSignatureRequest', signPayload, {
1143
- requiredPassword: false,
1144
- address
1145
- }).then(({
1106
+ return this.requestService.addConfirmation(id, url, 'evmSignatureRequest', payloadAfterValidated, {}).then(({
1146
1107
  isApproved,
1147
1108
  payload
1148
1109
  }) => {
@@ -1186,117 +1147,36 @@ export default class KoniState {
1186
1147
  });
1187
1148
  return Object.fromEntries(await Promise.all(promiseList));
1188
1149
  }
1189
- async evmSendTransaction(id, url, networkKey, allowedAccounts, transactionParams) {
1190
- const evmApi = this.getEvmApi(networkKey);
1191
- const evmNetwork = this.getChainInfo(networkKey);
1192
- const web3 = evmApi.api;
1193
- const autoFormatNumber = val => {
1194
- if (typeof val === 'string' && val.startsWith('0x')) {
1195
- return new BN(val.replace('0x', ''), 16).toString();
1196
- } else if (typeof val === 'number') {
1197
- return val.toString();
1198
- }
1199
- return val;
1150
+ async evmSendTransaction(id, url, transactionParams, networkKeyInit, topic) {
1151
+ const payloadValidation = {
1152
+ errors: [],
1153
+ networkKey: networkKeyInit || '',
1154
+ payloadAfterValidated: transactionParams,
1155
+ address: transactionParams.from
1200
1156
  };
1201
- if (transactionParams.from === transactionParams.to) {
1202
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Receiving address must be different from sending address'));
1203
- }
1204
- const transaction = {
1205
- from: transactionParams.from,
1206
- to: transactionParams.to,
1207
- value: autoFormatNumber(transactionParams.value),
1208
- gas: autoFormatNumber(transactionParams.gas),
1209
- gasPrice: autoFormatNumber(transactionParams.gasPrice || transactionParams.gasLimit),
1210
- maxPriorityFeePerGas: autoFormatNumber(transactionParams.maxPriorityFeePerGas),
1211
- maxFeePerGas: autoFormatNumber(transactionParams.maxFeePerGas),
1212
- data: transactionParams.data
1213
- };
1214
- if (!transactionParams.gas) {
1215
- const getTransactionGas = async () => {
1216
- try {
1217
- transaction.gas = await web3.eth.estimateGas({
1218
- ...transaction
1219
- });
1220
- } catch (e) {
1221
- // @ts-ignore
1222
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
1223
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, e === null || e === void 0 ? void 0 : e.message);
1224
- }
1225
- };
1226
-
1227
- // Calculate transaction data
1228
- try {
1229
- await Promise.race([getTransactionGas(), wait(3000).then(async () => {
1230
- if (!transaction.gas) {
1231
- await this.chainService.initSingleApi(networkKey);
1232
- await getTransactionGas();
1233
- }
1234
- })]);
1235
- } catch (e) {
1236
- // @ts-ignore
1237
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
1238
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, e === null || e === void 0 ? void 0 : e.message);
1239
- }
1240
- }
1241
- if (!transaction.gas) {
1242
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS);
1243
- }
1244
- let estimateGas;
1245
-
1246
- // TODO: Review, If not override, transaction maybe fail because fee too low
1247
- if (transactionParams.maxPriorityFeePerGas && transactionParams.maxFeePerGas) {
1248
- const maxFee = new BigN(transactionParams.maxFeePerGas);
1249
- estimateGas = maxFee.multipliedBy(transaction.gas).toFixed(0);
1250
- } else if (transactionParams.gasPrice) {
1251
- estimateGas = new BigN(transactionParams.gasPrice).multipliedBy(transaction.gas).toFixed(0);
1252
- } else {
1253
- const priority = await calculateGasFeeParams(evmApi, networkKey);
1254
- if (priority.baseGasFee) {
1255
- transaction.maxPriorityFeePerGas = priority.maxPriorityFeePerGas.toString();
1256
- transaction.maxFeePerGas = priority.maxFeePerGas.toString();
1257
- const maxFee = priority.maxFeePerGas;
1258
- estimateGas = maxFee.multipliedBy(transaction.gas).toFixed(0);
1259
- } else {
1260
- transaction.gasPrice = priority.gasPrice;
1261
- estimateGas = new BigN(priority.gasPrice).multipliedBy(transaction.gas).toFixed(0);
1157
+ const validationSteps = [topic ? validationAuthWCMiddleware : validationAuthMiddleware, validationConnectMiddleware, validationEvmDataTransactionMiddleware];
1158
+ const result = await generateValidationProcess(this, url, payloadValidation, validationSteps, topic);
1159
+ const {
1160
+ confirmationType,
1161
+ errors,
1162
+ networkKey: networkKey_
1163
+ } = result;
1164
+ if (errors && errors.length > 0 && confirmationType) {
1165
+ if (ERROR_CONFIRMATION_TYPE.includes(confirmationType)) {
1166
+ return this.requestService.addConfirmation(id, url, confirmationType, result, {}).then(() => {
1167
+ throw new EvmProviderError(EvmProviderErrorType.USER_REJECTED_REQUEST);
1168
+ });
1262
1169
  }
1263
1170
  }
1264
-
1265
- // Address is validated in before step
1266
- const fromAddress = allowedAccounts.find(account => account.toLowerCase() === transaction.from.toLowerCase());
1267
- if (!fromAddress) {
1268
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('You have rescinded allowance for this account in wallet'));
1269
- }
1270
- const pair = keyring.getPair(fromAddress);
1271
- if (!pair) {
1272
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Unable to find account'));
1273
- }
1274
- const account = {
1275
- address: pair.address,
1276
- ...pair.meta
1277
- };
1278
-
1279
- // Validate balance
1280
- const balance = new BN((await web3.eth.getBalance(fromAddress)) || 0);
1281
- if (balance.lt(new BN(estimateGas).add(new BN(autoFormatNumber(transactionParams.value) || '0')))) {
1282
- throw new EvmProviderError(EvmProviderErrorType.INVALID_PARAMS, t('Insufficient balance'));
1283
- }
1284
- transaction.nonce = await web3.eth.getTransactionCount(fromAddress);
1285
- const hashPayload = this.transactionService.generateHashPayload(networkKey, transaction);
1286
- const isToContract = await isContractAddress(transaction.to || '', evmApi);
1287
- const parseData = isToContract ? transaction.data ? (await parseContractInput(transaction.data, transaction.to || '', evmNetwork)).result : '' : transaction.data || '';
1171
+ const transactionValidated = result.payloadAfterValidated;
1172
+ const networkKey = networkKey_ || '';
1288
1173
  const requestPayload = {
1289
- ...transaction,
1290
- estimateGas,
1291
- hashPayload,
1292
- isToContract,
1293
- parseData: parseData,
1294
- account: account,
1295
- canSign: true
1174
+ ...transactionValidated,
1175
+ errors: errors
1296
1176
  };
1297
- const eType = transaction.value ? ExtrinsicType.TRANSFER_BALANCE : ExtrinsicType.EVM_EXECUTE;
1177
+ const eType = transactionValidated.value ? ExtrinsicType.TRANSFER_BALANCE : ExtrinsicType.EVM_EXECUTE;
1298
1178
  const transactionData = {
1299
- ...transaction
1179
+ ...transactionValidated
1300
1180
  };
1301
1181
  const token = this.chainService.getNativeTokenInfo(networkKey);
1302
1182
  if (eType === ExtrinsicType.TRANSFER_BALANCE) {
@@ -1311,10 +1191,11 @@ export default class KoniState {
1311
1191
  chain: networkKey,
1312
1192
  url,
1313
1193
  data: transactionData,
1194
+ errors: errors,
1314
1195
  extrinsicType: eType,
1315
1196
  chainType: ChainType.EVM,
1316
1197
  estimateFee: {
1317
- value: estimateGas,
1198
+ value: transactionValidated.estimateGas,
1318
1199
  symbol: token.symbol,
1319
1200
  decimals: token.decimals || 18
1320
1201
  },
@@ -10,7 +10,6 @@ export default class KoniTabs {
10
10
  #private;
11
11
  private evmEventEmitterMap;
12
12
  constructor(koniState: KoniState);
13
- private getSigningPair;
14
13
  private bytesSign;
15
14
  private extrinsicSign;
16
15
  private metadataProvide;
@@ -9,16 +9,15 @@ import { EvmProviderErrorType } from '@subwallet/extension-base/background/KoniT
9
9
  import RequestBytesSign from '@subwallet/extension-base/background/RequestBytesSign';
10
10
  import RequestExtrinsicSign from '@subwallet/extension-base/background/RequestExtrinsicSign';
11
11
  import { ALL_ACCOUNT_KEY, CRON_GET_API_MAP_STATUS } from '@subwallet/extension-base/constants';
12
+ import { generateValidationProcess, validationAuthMiddleware } from '@subwallet/extension-base/core/logic-validation';
12
13
  import { PHISHING_PAGE_REDIRECT } from '@subwallet/extension-base/defaults';
13
14
  import { _CHAIN_VALIDATION_ERROR } from '@subwallet/extension-base/services/chain-service/handler/types';
14
15
  import { _generateCustomProviderKey } from '@subwallet/extension-base/services/chain-service/utils';
15
16
  import { DEFAULT_CHAIN_PATROL_ENABLE } from '@subwallet/extension-base/services/setting-service/constants';
16
17
  import { canDerive, getEVMChainInfo, stripUrl } from '@subwallet/extension-base/utils';
17
- import keyring from '@subwallet/ui-keyring';
18
- import { t } from 'i18next';
19
18
  import Web3 from 'web3';
20
19
  import { checkIfDenied } from '@polkadot/phishing';
21
- import { assert, isNumber } from '@polkadot/util';
20
+ import { isNumber } from '@polkadot/util';
22
21
  function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthType) {
23
22
  const accountSelected = authInfo ? authInfo.isAllowed ? Object.keys(authInfo.isAllowedMap).filter(address => authInfo.isAllowedMap[address]) : [] : [];
24
23
  let authTypeFilter = ({
@@ -102,33 +101,36 @@ export default class KoniTabs {
102
101
  }
103
102
 
104
103
  /// Clone from Polkadot.js
105
- getSigningPair(address) {
106
- const pair = keyring.getPair(address);
107
- assert(pair, t('Unable to find account'));
108
- return pair;
109
- }
110
104
  async bytesSign(url, request) {
111
105
  const address = request.address;
112
- const pair = this.getSigningPair(address);
113
- const authInfo = await this.getAuthInfo(url);
114
- if (!authInfo || !authInfo.isAllowed || !authInfo.isAllowedMap[pair.address]) {
115
- throw new Error('Account {{address}} not in allowed list'.replace('{{address}}', address));
116
- }
106
+ const payloadValidate = {
107
+ address,
108
+ networkKey: '',
109
+ errors: [],
110
+ payloadAfterValidated: request
111
+ };
112
+ const {
113
+ pair
114
+ } = await generateValidationProcess(this.#koniState, url, payloadValidate, [validationAuthMiddleware]);
117
115
  return this.#koniState.sign(url, new RequestBytesSign(request), {
118
116
  address,
119
- ...pair.meta
117
+ ...(pair === null || pair === void 0 ? void 0 : pair.meta)
120
118
  });
121
119
  }
122
120
  async extrinsicSign(url, request) {
123
121
  const address = request.address;
124
- const pair = this.getSigningPair(address);
125
- const authInfo = await this.getAuthInfo(url);
126
- if (!authInfo || !authInfo.isAllowed || !authInfo.isAllowedMap[pair.address]) {
127
- throw new Error('Account {{address}} not in allowed list'.replace('{{address}}', address));
128
- }
122
+ const payloadValidate = {
123
+ address,
124
+ networkKey: '',
125
+ errors: [],
126
+ payloadAfterValidated: request
127
+ };
128
+ const {
129
+ pair
130
+ } = await generateValidationProcess(this.#koniState, url, payloadValidate, [validationAuthMiddleware]);
129
131
  return this.#koniState.sign(url, new RequestExtrinsicSign(request), {
130
132
  address,
131
- ...pair.meta
133
+ ...(pair === null || pair === void 0 ? void 0 : pair.meta)
132
134
  });
133
135
  }
134
136
  metadataProvide(url, request) {
@@ -747,8 +749,19 @@ export default class KoniTabs {
747
749
  params: params,
748
750
  id
749
751
  }, (error, result) => {
750
- const err = (result === null || result === void 0 ? void 0 : result.error) || error;
752
+ let err = (result === null || result === void 0 ? void 0 : result.error) || error;
751
753
  if (err) {
754
+ let message = err.message.toLowerCase();
755
+ if (message.includes('method not found') || message.includes('not supported') || message.includes('is not available')) {
756
+ message = 'This method is not supported by SubWallet. Try again or contact support at agent@subwallet.app';
757
+ }
758
+ if (message.includes('network is disconnected')) {
759
+ message = 'Re-enable the network or change RPC on the extension and try again';
760
+ }
761
+ err = {
762
+ ...err,
763
+ message
764
+ };
752
765
  reject(err);
753
766
  } else {
754
767
  const rs = result === null || result === void 0 ? void 0 : result.result;
@@ -766,8 +779,7 @@ export default class KoniTabs {
766
779
  method,
767
780
  params
768
781
  }) {
769
- const allowedAccounts = await this.getEvmCurrentAccount(url);
770
- const signResult = await this.#koniState.evmSign(id, url, method, params, allowedAccounts);
782
+ const signResult = await this.#koniState.evmSign(id, url, method, params);
771
783
  if (signResult) {
772
784
  return signResult;
773
785
  } else {
@@ -778,17 +790,7 @@ export default class KoniTabs {
778
790
  params
779
791
  }) {
780
792
  const transactionParams = params[0];
781
- const canUseAccount = transactionParams.from && this.canUseAccount(transactionParams.from, url);
782
- const evmState = await this.getEvmState(url);
783
- const networkKey = evmState.networkKey;
784
- if (!canUseAccount) {
785
- throw new Error(t('You have rescinded allowance for this account in wallet'));
786
- }
787
- if (!networkKey) {
788
- throw new Error('Network unavailable. Please switch network or manually add network to wallet');
789
- }
790
- const allowedAccounts = await this.getEvmCurrentAccount(url);
791
- const transactionHash = await this.#koniState.evmSendTransaction(id, url, networkKey, allowedAccounts, transactionParams);
793
+ const transactionHash = await this.#koniState.evmSendTransaction(id, url, transactionParams);
792
794
  if (!transactionHash) {
793
795
  throw new EvmProviderError(EvmProviderErrorType.USER_REJECTED_REQUEST);
794
796
  }
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.2.24-2",
20
+ "version": "1.2.25-1",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -129,11 +129,21 @@
129
129
  "require": "./cjs/constants/storage.js",
130
130
  "default": "./constants/storage.js"
131
131
  },
132
+ "./core/logic-validation": {
133
+ "types": "./core/logic-validation/index.d.ts",
134
+ "require": "./cjs/core/logic-validation/index.js",
135
+ "default": "./core/logic-validation/index.js"
136
+ },
132
137
  "./core/logic-validation/earning": {
133
138
  "types": "./core/logic-validation/earning.d.ts",
134
139
  "require": "./cjs/core/logic-validation/earning.js",
135
140
  "default": "./core/logic-validation/earning.js"
136
141
  },
142
+ "./core/logic-validation/request": {
143
+ "types": "./core/logic-validation/request.d.ts",
144
+ "require": "./cjs/core/logic-validation/request.js",
145
+ "default": "./core/logic-validation/request.js"
146
+ },
137
147
  "./core/logic-validation/swap": {
138
148
  "types": "./core/logic-validation/swap.d.ts",
139
149
  "require": "./cjs/core/logic-validation/swap.js",
@@ -2059,11 +2069,11 @@
2059
2069
  "@reduxjs/toolkit": "^1.9.1",
2060
2070
  "@sora-substrate/type-definitions": "^1.17.7",
2061
2071
  "@substrate/connect": "^0.8.9",
2062
- "@subwallet/chain-list": "0.2.81",
2063
- "@subwallet/extension-base": "^1.2.24-2",
2064
- "@subwallet/extension-chains": "^1.2.24-2",
2065
- "@subwallet/extension-dapp": "^1.2.24-2",
2066
- "@subwallet/extension-inject": "^1.2.24-2",
2072
+ "@subwallet/chain-list": "0.2.82",
2073
+ "@subwallet/extension-base": "^1.2.25-1",
2074
+ "@subwallet/extension-chains": "^1.2.25-1",
2075
+ "@subwallet/extension-dapp": "^1.2.25-1",
2076
+ "@subwallet/extension-inject": "^1.2.25-1",
2067
2077
  "@subwallet/keyring": "^0.1.5",
2068
2078
  "@subwallet/ui-keyring": "^0.1.5",
2069
2079
  "@walletconnect/keyvaluestorage": "^1.1.1",
package/packageInfo.js CHANGED
@@ -7,5 +7,5 @@ export const packageInfo = {
7
7
  name: '@subwallet/extension-base',
8
8
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
9
9
  type: 'esm',
10
- version: '1.2.24-2'
10
+ version: '1.2.25-1'
11
11
  };