@subwallet/extension-base 1.3.72-0 → 1.3.74-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 (113) hide show
  1. package/background/KoniTypes.d.ts +42 -5
  2. package/background/KoniTypes.js +14 -1
  3. package/cjs/background/KoniTypes.js +16 -2
  4. package/cjs/core/logic-validation/transfer.js +35 -57
  5. package/cjs/koni/background/handlers/Extension.js +599 -146
  6. package/cjs/koni/background/handlers/State.js +5 -6
  7. package/cjs/koni/background/handlers/Tabs.js +3 -2
  8. package/cjs/koni/background/subscription.js +2 -22
  9. package/cjs/packageInfo.js +1 -1
  10. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +0 -2
  11. package/cjs/services/chain-service/handler/SubstrateApi.js +6 -1
  12. package/cjs/services/chain-service/index.js +1 -0
  13. package/cjs/services/chain-service/utils/index.js +4 -0
  14. package/cjs/services/earning-service/handlers/native-staking/para-chain.js +17 -2
  15. package/cjs/services/event-service/index.js +1 -0
  16. package/cjs/services/fee-service/utils/index.js +4 -4
  17. package/cjs/services/inapp-notification-service/consts.js +4 -2
  18. package/cjs/services/inapp-notification-service/index.js +51 -6
  19. package/cjs/services/inapp-notification-service/interfaces.js +2 -0
  20. package/cjs/services/inapp-notification-service/utils/common.js +4 -0
  21. package/cjs/services/keyring-service/context/account-context.js +44 -0
  22. package/cjs/services/keyring-service/context/handlers/Multisig.js +186 -0
  23. package/cjs/services/keyring-service/context/state.js +12 -0
  24. package/cjs/services/multisig-service/index.js +627 -0
  25. package/cjs/services/multisig-service/utils.js +242 -0
  26. package/cjs/services/request-service/handler/SubstrateRequestHandler.js +25 -0
  27. package/cjs/services/request-service/index.js +5 -1
  28. package/cjs/services/storage-service/DatabaseService.js +5 -2
  29. package/cjs/services/storage-service/db-stores/InappNotification.js +20 -2
  30. package/cjs/services/substrate-proxy-service/index.js +22 -7
  31. package/cjs/services/transaction-service/helpers/index.js +8 -0
  32. package/cjs/services/transaction-service/index.js +348 -147
  33. package/cjs/services/transaction-service/types.js +18 -1
  34. package/cjs/types/account/info/keyring.js +5 -0
  35. package/cjs/types/account/info/proxy.js +1 -0
  36. package/cjs/types/multisig/index.js +14 -0
  37. package/cjs/types/transaction/error.js +9 -2
  38. package/cjs/utils/account/transform.js +28 -4
  39. package/cjs/utils/logger/Logger.js +294 -0
  40. package/cjs/utils/logger/index.js +42 -0
  41. package/cjs/utils/logger/types.js +1 -0
  42. package/core/logic-validation/transfer.d.ts +2 -2
  43. package/core/logic-validation/transfer.js +10 -32
  44. package/koni/background/handlers/Extension.d.ts +7 -0
  45. package/koni/background/handlers/Extension.js +498 -45
  46. package/koni/background/handlers/State.d.ts +2 -1
  47. package/koni/background/handlers/State.js +5 -6
  48. package/koni/background/handlers/Tabs.js +3 -2
  49. package/koni/background/subscription.js +2 -22
  50. package/package.json +43 -7
  51. package/packageInfo.js +1 -1
  52. package/services/balance-service/helpers/subscribe/substrate/index.js +0 -2
  53. package/services/chain-service/handler/SubstrateApi.js +7 -2
  54. package/services/chain-service/index.js +1 -0
  55. package/services/chain-service/types.d.ts +1 -1
  56. package/services/chain-service/utils/index.js +4 -0
  57. package/services/earning-service/handlers/native-staking/para-chain.js +17 -2
  58. package/services/event-service/index.d.ts +1 -0
  59. package/services/event-service/index.js +1 -0
  60. package/services/event-service/types.d.ts +1 -0
  61. package/services/fee-service/utils/index.js +4 -4
  62. package/services/inapp-notification-service/consts.d.ts +3 -1
  63. package/services/inapp-notification-service/consts.js +5 -3
  64. package/services/inapp-notification-service/index.d.ts +3 -2
  65. package/services/inapp-notification-service/index.js +51 -6
  66. package/services/inapp-notification-service/interfaces.d.ts +18 -2
  67. package/services/inapp-notification-service/interfaces.js +2 -0
  68. package/services/inapp-notification-service/utils/common.d.ts +1 -0
  69. package/services/inapp-notification-service/utils/common.js +3 -0
  70. package/services/keyring-service/context/account-context.d.ts +9 -1
  71. package/services/keyring-service/context/account-context.js +44 -0
  72. package/services/keyring-service/context/handlers/Multisig.d.ts +18 -0
  73. package/services/keyring-service/context/handlers/Multisig.js +180 -0
  74. package/services/keyring-service/context/state.d.ts +2 -0
  75. package/services/keyring-service/context/state.js +12 -0
  76. package/services/multisig-service/index.d.ts +245 -0
  77. package/services/multisig-service/index.js +620 -0
  78. package/services/multisig-service/utils.d.ts +95 -0
  79. package/services/multisig-service/utils.js +227 -0
  80. package/services/request-service/handler/SubstrateRequestHandler.d.ts +1 -0
  81. package/services/request-service/handler/SubstrateRequestHandler.js +25 -0
  82. package/services/request-service/index.d.ts +2 -1
  83. package/services/request-service/index.js +5 -1
  84. package/services/storage-service/DatabaseService.d.ts +3 -2
  85. package/services/storage-service/DatabaseService.js +5 -2
  86. package/services/storage-service/db-stores/InappNotification.d.ts +3 -2
  87. package/services/storage-service/db-stores/InappNotification.js +20 -2
  88. package/services/substrate-proxy-service/index.d.ts +4 -1
  89. package/services/substrate-proxy-service/index.js +22 -8
  90. package/services/transaction-service/helpers/index.js +8 -0
  91. package/services/transaction-service/index.d.ts +31 -0
  92. package/services/transaction-service/index.js +270 -69
  93. package/services/transaction-service/types.d.ts +28 -3
  94. package/services/transaction-service/types.js +12 -1
  95. package/types/account/info/keyring.d.ts +14 -1
  96. package/types/account/info/keyring.js +6 -0
  97. package/types/account/info/proxy.d.ts +1 -0
  98. package/types/account/info/proxy.js +1 -0
  99. package/types/multisig/index.d.ts +76 -0
  100. package/types/multisig/index.js +8 -0
  101. package/types/notification/index.d.ts +8 -0
  102. package/types/substrateProxyAccount/index.d.ts +26 -1
  103. package/types/transaction/error.d.ts +6 -1
  104. package/types/transaction/error.js +7 -1
  105. package/types/transaction/request.d.ts +0 -1
  106. package/types/yield/info/pallet.d.ts +1 -1
  107. package/utils/account/transform.js +28 -4
  108. package/utils/logger/Logger.d.ts +31 -0
  109. package/utils/logger/Logger.js +267 -0
  110. package/utils/logger/index.d.ts +15 -0
  111. package/utils/logger/index.js +29 -0
  112. package/utils/logger/types.d.ts +23 -0
  113. package/utils/logger/types.js +1 -0
@@ -42,13 +42,16 @@ import { _ChainConnectionStatus } from '@subwallet/extension-base/services/chain
42
42
  import { _getAssetDecimals, _getAssetSymbol, _getChainNativeTokenBasicInfo, _getContractAddressOfToken, _getEvmChainId, _isAssetSmartContractNft, _isChainBitcoinCompatible, _isChainCompatibleLedgerEvm, _isChainEnabled, _isChainEvmCompatible, _isChainSubstrateCompatible, _isCustomAsset, _isLocalToken, _isMantaZkAsset, _isNativeToken, _isNativeTokenBySlug, _isPureEvmChain, _isTokenEvmSmartContract, _isTokenTransferredByBitcoin, _isTokenTransferredByCardano, _isTokenTransferredByEvm, _isTokenTransferredByTon } from '@subwallet/extension-base/services/chain-service/utils';
43
43
  import { calculateToAmountByReservePool } from '@subwallet/extension-base/services/fee-service/utils';
44
44
  import { batchExtrinsicSetFeeHydration, getAssetHubTokensCanPayFee, getHydrationTokensCanPayFee } from '@subwallet/extension-base/services/fee-service/utils/tokenPayFee';
45
+ import { calcDepositAmount, createInitMultisigExtrinsic, decodeCallData, DEFAULT_MAX_WEIGHT } from '@subwallet/extension-base/services/multisig-service/utils';
45
46
  import { EXTENSION_REQUEST_URL } from '@subwallet/extension-base/services/request-service/constants';
46
47
  import { DEFAULT_AUTO_LOCK_TIME } from '@subwallet/extension-base/services/setting-service/constants';
48
+ import { createInitSubstrateProxyExtrinsic } from '@subwallet/extension-base/services/substrate-proxy-service';
49
+ import { SubstrateTransactionWrappingStatus } from '@subwallet/extension-base/services/transaction-service/types';
47
50
  import { isProposalExpired, isSupportWalletConnectChain, isSupportWalletConnectNamespace } from '@subwallet/extension-base/services/wallet-connect-service/helpers';
48
51
  import { SWStorage } from '@subwallet/extension-base/storage';
49
52
  import { AccountsStore } from '@subwallet/extension-base/stores';
50
- import { AccountChainType, AccountSignMode, BalanceType, BasicTxErrorType, BasicTxWarningCode, CommonStepType, EarningProcessType, ProcessType, StakingTxErrorType, StepStatus, SwapFeeType, YieldPoolType, YieldStepType } from '@subwallet/extension-base/types';
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';
53
+ import { AccountChainType, AccountSignMode, BalanceType, BasicTxErrorType, BasicTxWarningCode, CommonStepType, EarningProcessType, MultisigTxErrorType, ProcessType, StakingTxErrorType, StepStatus, SwapFeeType, YieldPoolType, YieldStepType } from '@subwallet/extension-base/types';
54
+ import { _analyzeAddress, calculateMaxTransferable, combineAllAccountProxy, combineBitcoinFee, createPromiseHandler, createTransactionFromRLP, detectTransferTxType, filterUneconomicalUtxos, getAccountJsonByAddress, getAccountSignMode, getSizeInfo, getTransferableBitcoinUtxos, isSameAddress, isSubstrateEcdsaLedgerAssetSupported, MODULE_SUPPORT, reformatAddress, signatureToHex, transformAccounts, transformAddresses, uniqueStringArray } from '@subwallet/extension-base/utils';
52
55
  import { parseContractInput, parseEvmRlp } from '@subwallet/extension-base/utils/eth/parseTransaction';
53
56
  import { getId } from '@subwallet/extension-base/utils/getId';
54
57
  import { getKeypairTypeByAddress, isAddress, isCardanoAddress, isSubstrateAddress, isTonAddress } from '@subwallet/keyring';
@@ -63,7 +66,7 @@ import { t } from 'i18next';
63
66
  import { combineLatest, Subject } from 'rxjs';
64
67
  import { TypeRegistry } from '@polkadot/types';
65
68
  import { assert, hexStripPrefix, hexToU8a, isAscii, isHex, noop, u8aToHex } from '@polkadot/util';
66
- import { decodeAddress, isEthereumAddress } from '@polkadot/util-crypto';
69
+ import { decodeAddress, isEthereumAddress, sortAddresses } from '@polkadot/util-crypto';
67
70
  import { getSuitableRegistry, setupApiRegistry, setupDappRegistry, setupDatabaseRegistry } from "../utils.js";
68
71
  export function isJsonPayload(value) {
69
72
  return value.genesisHash !== undefined;
@@ -1255,7 +1258,6 @@ export default class KoniExtension {
1255
1258
  feeCustom,
1256
1259
  feeOption,
1257
1260
  from,
1258
- signerSubstrateProxyAddress,
1259
1261
  to,
1260
1262
  tokenPayFeeSlug,
1261
1263
  tokenSlug,
@@ -1489,7 +1491,6 @@ export default class KoniExtension {
1489
1491
  isTransferAll: isTransferNativeToken ? transferAll : false,
1490
1492
  isTransferLocalTokenAndPayThatTokenAsFee,
1491
1493
  edAsWarning: isTransferNativeToken,
1492
- signerSubstrateProxyAddress,
1493
1494
  additionalValidator: additionalValidator
1494
1495
  });
1495
1496
  }
@@ -1501,7 +1502,6 @@ export default class KoniExtension {
1501
1502
  from,
1502
1503
  isPassConfirmation,
1503
1504
  originNetworkKey,
1504
- signerSubstrateProxyAddress,
1505
1505
  to,
1506
1506
  tokenPayFeeSlug,
1507
1507
  tokenSlug,
@@ -1697,8 +1697,7 @@ export default class KoniExtension {
1697
1697
  xcmFeeDryRun,
1698
1698
  errors,
1699
1699
  additionalValidator: additionalValidator,
1700
- eventsHandler: eventsHandler,
1701
- signerSubstrateProxyAddress
1700
+ eventsHandler: eventsHandler
1702
1701
  });
1703
1702
  }
1704
1703
  async makeBitcoinDappTransferConfirmation(inputData) {
@@ -2423,8 +2422,7 @@ export default class KoniExtension {
2423
2422
  const {
2424
2423
  params,
2425
2424
  recipientAddress,
2426
- senderAddress,
2427
- signerSubstrateProxyAddress
2425
+ senderAddress
2428
2426
  } = inputData;
2429
2427
  const isSendingSelf = isRecipientSelf(senderAddress, recipientAddress);
2430
2428
 
@@ -2445,8 +2443,7 @@ export default class KoniExtension {
2445
2443
  isSendingSelf
2446
2444
  },
2447
2445
  extrinsicType: ExtrinsicType.SEND_NFT,
2448
- chainType: ChainType.SUBSTRATE,
2449
- signerSubstrateProxyAddress
2446
+ chainType: ChainType.SUBSTRATE
2450
2447
  });
2451
2448
  return {
2452
2449
  ...rs,
@@ -2483,6 +2480,9 @@ export default class KoniExtension {
2483
2480
  }
2484
2481
  return result;
2485
2482
  }
2483
+ async accountsCreateMultisig(request) {
2484
+ return this.#koniState.keyringService.context.accountsCreateMultisig(request);
2485
+ }
2486
2486
 
2487
2487
  /// External account
2488
2488
 
@@ -2918,6 +2918,439 @@ export default class KoniExtension {
2918
2918
  });
2919
2919
  }
2920
2920
 
2921
+ // Multisig handlers
2922
+ async approvePendingTx(inputData) {
2923
+ const {
2924
+ address,
2925
+ callHash,
2926
+ chain,
2927
+ multisigMetadata,
2928
+ timepoint
2929
+ } = inputData;
2930
+ if (!address || !chain || !multisigMetadata || !callHash || !timepoint) {
2931
+ return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(MultisigTxErrorType.INVALID_PARAMS)]);
2932
+ }
2933
+ const api = this.#koniState.getSubstrateApi(chain).api;
2934
+ if (!api || !api.tx || !api.tx.multisig) {
2935
+ return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(MultisigTxErrorType.LACK_MULTISIG_PALLET)]);
2936
+ }
2937
+ const otherSignatories = multisigMetadata.signers.filter(s => !isSameAddress(s, address));
2938
+ const extrinsic = api.tx.multisig.approveAsMulti(multisigMetadata.threshold, sortAddresses(otherSignatories), timepoint, callHash, DEFAULT_MAX_WEIGHT);
2939
+ return await this.#koniState.transactionService.handleTransaction({
2940
+ address,
2941
+ chain,
2942
+ chainType: ChainType.SUBSTRATE,
2943
+ data: inputData,
2944
+ extrinsicType: ExtrinsicType.MULTISIG_APPROVE_TX,
2945
+ transaction: extrinsic,
2946
+ url: EXTENSION_REQUEST_URL
2947
+ });
2948
+ }
2949
+ async executePendingTx(inputData) {
2950
+ const {
2951
+ address,
2952
+ call,
2953
+ chain,
2954
+ decodedCallData,
2955
+ multisigMetadata,
2956
+ timepoint
2957
+ } = inputData;
2958
+ if (!address || !chain || !multisigMetadata || !timepoint || !call || !decodedCallData) {
2959
+ return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(MultisigTxErrorType.INVALID_PARAMS)]);
2960
+ }
2961
+ try {
2962
+ const api = this.#koniState.getSubstrateApi(chain).api;
2963
+ if (!api || !api.tx || !api.tx.multisig) {
2964
+ return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(MultisigTxErrorType.LACK_MULTISIG_PALLET)]);
2965
+ }
2966
+ const otherSignatories = multisigMetadata.signers.filter(s => !isSameAddress(s, address));
2967
+ const originalCall = api.createType('Call', call);
2968
+ const originalExtrinsic = api.tx(originalCall);
2969
+ const {
2970
+ weight
2971
+ } = await originalExtrinsic.paymentInfo(otherSignatories[0]); // estimate max weight for execute multisig tx
2972
+
2973
+ const extrinsic = api.tx.multisig.asMulti(multisigMetadata.threshold, sortAddresses(otherSignatories), timepoint, call, weight);
2974
+ return await this.#koniState.transactionService.handleTransaction({
2975
+ address,
2976
+ chain,
2977
+ chainType: ChainType.SUBSTRATE,
2978
+ data: inputData,
2979
+ extrinsicType: ExtrinsicType.MULTISIG_EXECUTE_TX,
2980
+ transaction: extrinsic,
2981
+ url: EXTENSION_REQUEST_URL
2982
+ });
2983
+ } catch (e) {
2984
+ const errMsg = e.message;
2985
+ return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(MultisigTxErrorType.UNABLE_TO_CONSTRUCT_TX, errMsg)]);
2986
+ }
2987
+ }
2988
+ async cancelPendingTx(inputData) {
2989
+ const {
2990
+ address,
2991
+ callHash,
2992
+ chain,
2993
+ multisigMetadata,
2994
+ timepoint
2995
+ } = inputData;
2996
+ if (!address || !chain || !multisigMetadata || !callHash) {
2997
+ return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(MultisigTxErrorType.INVALID_PARAMS)]);
2998
+ }
2999
+ const api = this.#koniState.getSubstrateApi(chain).api;
3000
+ if (!api || !api.tx || !api.tx.multisig) {
3001
+ return this.#koniState.transactionService.generateBeforeHandleResponseErrors([new TransactionError(MultisigTxErrorType.LACK_MULTISIG_PALLET)]);
3002
+ }
3003
+ const otherSignatories = multisigMetadata.signers.filter(s => !isSameAddress(s, address));
3004
+ const extrinsic = api.tx.multisig.cancelAsMulti(multisigMetadata.threshold, sortAddresses(otherSignatories), timepoint, callHash);
3005
+ return await this.#koniState.transactionService.handleTransaction({
3006
+ address,
3007
+ chain,
3008
+ chainType: ChainType.SUBSTRATE,
3009
+ data: inputData,
3010
+ extrinsicType: ExtrinsicType.MULTISIG_CANCEL_TX,
3011
+ transaction: extrinsic,
3012
+ url: EXTENSION_REQUEST_URL
3013
+ });
3014
+ }
3015
+
3016
+ // Multisig Account
3017
+ async initMultisigTx(request) {
3018
+ const {
3019
+ chain,
3020
+ multisigMetadata: {
3021
+ signers,
3022
+ threshold
3023
+ },
3024
+ signer,
3025
+ transactionId
3026
+ } = request;
3027
+
3028
+ /**
3029
+ * ─────────────────────────────
3030
+ * Prepare original transaction
3031
+ * ─────────────────────────────
3032
+ */
3033
+ const substrateApi = await this.#koniState.chainService.getSubstrateApi(chain).isReady;
3034
+ const originTransaction = this.#koniState.transactionService.getTransaction(transactionId);
3035
+ if (!(originTransaction !== null && originTransaction !== void 0 && originTransaction.transaction)) {
3036
+ throw new Error(`[initMultisigTx] Origin transaction not found: ${transactionId}`);
3037
+ }
3038
+ const extrinsicOriginTransaction = originTransaction.transaction;
3039
+ const callData = extrinsicOriginTransaction.method.toHex();
3040
+
3041
+ /**
3042
+ * ─────────────────────────────
3043
+ * Create multisig wrapped extrinsic
3044
+ * ─────────────────────────────
3045
+ */
3046
+ const multisigExtrinsic = createInitMultisigExtrinsic(substrateApi.api, threshold, signers, signer, extrinsicOriginTransaction);
3047
+ const decodedCallData = decodeCallData({
3048
+ api: substrateApi.api,
3049
+ callData
3050
+ });
3051
+
3052
+ /**
3053
+ * ─────────────────────────────
3054
+ * Fee & deposit calculation
3055
+ * ─────────────────────────────
3056
+ */
3057
+ const networkFee = (await multisigExtrinsic.paymentInfo(signer)).partialFee.toString();
3058
+ const depositBase = substrateApi.api.consts.multisig.depositBase.toString();
3059
+ const depositFactor = substrateApi.api.consts.multisig.depositFactor.toString();
3060
+ const depositAmount = calcDepositAmount(depositBase, threshold, depositFactor);
3061
+
3062
+ /**
3063
+ * ─────────────────────────────
3064
+ * Additional validation
3065
+ * ─────────────────────────────
3066
+ * Validate signer balance:
3067
+ * - multisig deposit
3068
+ * - network fee
3069
+ */
3070
+ const additionalValidator = async inputTransaction => {
3071
+ const signerBalance = await this.getAddressTransferableBalance({
3072
+ address: signer,
3073
+ networkKey: chain,
3074
+ token: this.#koniState.chainService.getNativeTokenInfo(chain).slug,
3075
+ extrinsicType: ExtrinsicType.TRANSFER_TOKEN
3076
+ });
3077
+
3078
+ // Hydration: token fee setting is not supported
3079
+ // todo: check and return better error for the case set token fee on hydration
3080
+ if (_SUPPORT_TOKEN_PAY_FEE_GROUP.hydration.includes(chain)) {
3081
+ var _substrateApi$api$que3;
3082
+ const setTokenPayFee = await ((_substrateApi$api$que3 = substrateApi.api.query.multiTransactionPayment) === null || _substrateApi$api$que3 === void 0 ? void 0 : _substrateApi$api$que3.accountCurrencyMap(signer));
3083
+ if (setTokenPayFee.toPrimitive()) {
3084
+ inputTransaction.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, t('bg.koni.handler.Extension.notEnoughBalanceForMultisigDepositAndFee')));
3085
+ }
3086
+ }
3087
+ const requiredBalance = BigInt(depositAmount) + BigInt(networkFee);
3088
+ if (BigInt(signerBalance.value) < requiredBalance) {
3089
+ inputTransaction.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, t('bg.koni.handler.Extension.notEnoughBalanceForMultisigDepositAndFee')));
3090
+ }
3091
+ };
3092
+
3093
+ /**
3094
+ * ─────────────────────────────
3095
+ * Event forwarding
3096
+ * ─────────────────────────────
3097
+ * Multisig INIT transaction:
3098
+ * - `signed` is forwarded to notify that the multisig initialization
3099
+ * has been successfully submitted.
3100
+ * - `error` / `timeout` are forwarded to propagate failures.
3101
+ *
3102
+ * Note:
3103
+ * Multisig execution requires collecting enough approvals,
3104
+ * so the transaction is not finalized at this stage.
3105
+ * These forwarded events are only used to resolve
3106
+ * the original wrapped transaction promise.
3107
+ */
3108
+ const eventsHandler = eventEmitter => {
3109
+ const originEmitter = originTransaction === null || originTransaction === void 0 ? void 0 : originTransaction.emitterTransaction;
3110
+ if (!originEmitter) {
3111
+ return;
3112
+ }
3113
+ eventEmitter.on('signed', data => {
3114
+ originEmitter.emit('signed', data);
3115
+ });
3116
+ eventEmitter.on('error', data => {
3117
+ if (data.errors.length > 0) {
3118
+ originEmitter.emit('error', data);
3119
+ }
3120
+ });
3121
+ eventEmitter.on('timeout', data => {
3122
+ if (data.errors.length > 0 && data.errors.some(e => e.errorType === BasicTxErrorType.TIMEOUT)) {
3123
+ originEmitter.emit('timeout', data);
3124
+ }
3125
+ });
3126
+ };
3127
+
3128
+ /**
3129
+ * ─────────────────────────────
3130
+ * Submit wrapped transaction
3131
+ * ─────────────────────────────
3132
+ */
3133
+ return this.#koniState.transactionService.handleWrappedTransaction({
3134
+ address: signer,
3135
+ chain,
3136
+ chainType: ChainType.SUBSTRATE,
3137
+ extrinsicType: ExtrinsicType.MULTISIG_INIT_TX,
3138
+ transaction: multisigExtrinsic,
3139
+ skipFeeValidation: true,
3140
+ wrappingStatus: SubstrateTransactionWrappingStatus.WRAP_RESULT,
3141
+ data: {
3142
+ // input
3143
+ ...request,
3144
+ // output
3145
+ submittedCallData: multisigExtrinsic.toHex(),
3146
+ callData,
3147
+ decodedCallData,
3148
+ depositAmount,
3149
+ networkFee
3150
+ },
3151
+ additionalValidator,
3152
+ eventsHandler
3153
+ });
3154
+ }
3155
+
3156
+ // Substrate Proxy Account
3157
+ async handleSubstrateProxyWrappedTx(request) {
3158
+ const {
3159
+ chain,
3160
+ proxyMetadata,
3161
+ signer,
3162
+ transactionId
3163
+ } = request;
3164
+ const {
3165
+ proxiedAddress
3166
+ } = proxyMetadata;
3167
+
3168
+ /**
3169
+ * ─────────────────────────────
3170
+ * Prepare original transaction
3171
+ * ─────────────────────────────
3172
+ */
3173
+ const substrateApi = await this.#koniState.chainService.getSubstrateApi(chain).isReady;
3174
+ const originTransaction = this.#koniState.transactionService.getTransaction(transactionId);
3175
+ const extrinsicOriginTransaction = originTransaction === null || originTransaction === void 0 ? void 0 : originTransaction.transaction;
3176
+ const callData = extrinsicOriginTransaction.method.toHex();
3177
+ const decodedCallData = decodeCallData({
3178
+ api: substrateApi.api,
3179
+ callData
3180
+ });
3181
+
3182
+ /**
3183
+ * ─────────────────────────────
3184
+ * Determine proxy execution
3185
+ * ─────────────────────────────
3186
+ * If signer is the proxied address itself,
3187
+ * a substrate proxy transaction is NOT required.
3188
+ */
3189
+ const isSignerProxiedAccount = isSameAddress(signer, proxiedAddress);
3190
+
3191
+ /**
3192
+ * ─────────────────────────────
3193
+ * Fee calculation
3194
+ * ─────────────────────────────
3195
+ */
3196
+
3197
+ const substrateProxyExtrinsic = isSignerProxiedAccount ? extrinsicOriginTransaction : createInitSubstrateProxyExtrinsic(substrateApi.api, proxiedAddress, extrinsicOriginTransaction);
3198
+ const networkFee = (await substrateProxyExtrinsic.paymentInfo(signer)).partialFee.toString();
3199
+
3200
+ /**
3201
+ * ─────────────────────────────
3202
+ * Additional validation
3203
+ * ─────────────────────────────
3204
+ * Validate signer balance for proxy execution fee.
3205
+ */
3206
+ const additionalValidator = async inputTransaction => {
3207
+ const signerBalance = await this.getAddressTransferableBalance({
3208
+ address: signer,
3209
+ networkKey: chain,
3210
+ token: this.#koniState.chainService.getNativeTokenInfo(chain).slug,
3211
+ extrinsicType: ExtrinsicType.TRANSFER_TOKEN
3212
+ });
3213
+
3214
+ // todo: check and return better error for the case set token fee on hydration
3215
+ if (_SUPPORT_TOKEN_PAY_FEE_GROUP.hydration.includes(chain)) {
3216
+ var _substrateApi$api$que4;
3217
+ const setTokenPayFee = await ((_substrateApi$api$que4 = substrateApi.api.query.multiTransactionPayment) === null || _substrateApi$api$que4 === void 0 ? void 0 : _substrateApi$api$que4.accountCurrencyMap(signer));
3218
+ if (setTokenPayFee.toPrimitive()) {
3219
+ const account = getAccountJsonByAddress(signer);
3220
+ inputTransaction.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, t('bg.koni.handler.Extension.proxyAccountNotEnoughBalance', {
3221
+ replace: {
3222
+ accountName: account === null || account === void 0 ? void 0 : account.name
3223
+ }
3224
+ })));
3225
+ }
3226
+ }
3227
+ if (BigInt(signerBalance.value) < BigInt(networkFee)) {
3228
+ const account = getAccountJsonByAddress(signer);
3229
+ inputTransaction.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, t('bg.koni.handler.Extension.proxyAccountNotEnoughBalance', {
3230
+ replace: {
3231
+ accountName: account === null || account === void 0 ? void 0 : account.name
3232
+ }
3233
+ })));
3234
+ }
3235
+ };
3236
+
3237
+ /**
3238
+ * ─────────────────────────────
3239
+ * Event forwarding
3240
+ * ─────────────────────────────
3241
+ * The substrate proxy transaction acts as a wrapper.
3242
+ * Its lifecycle events are forwarded to the original
3243
+ * transaction to resolve the wrapped transaction promise.
3244
+ * update history transaction accordingly.
3245
+ */
3246
+ const eventsHandler = eventEmitter => {
3247
+ if (!(originTransaction !== null && originTransaction !== void 0 && originTransaction.emitterTransaction)) {
3248
+ return;
3249
+ }
3250
+ const originEmitter = originTransaction.emitterTransaction;
3251
+ eventEmitter.on('send', data => {
3252
+ originEmitter.emit('send', {
3253
+ ...data,
3254
+ id: originTransaction.id
3255
+ });
3256
+ });
3257
+ eventEmitter.on('signed', data => {
3258
+ originEmitter.emit('signed', {
3259
+ ...data,
3260
+ id: originTransaction.id
3261
+ });
3262
+ });
3263
+ eventEmitter.on('extrinsicHash', data => {
3264
+ originEmitter.emit('extrinsicHash', {
3265
+ ...data,
3266
+ id: originTransaction.id
3267
+ });
3268
+ });
3269
+ eventEmitter.on('success', data => {
3270
+ originEmitter.emit('success', {
3271
+ ...data,
3272
+ id: originTransaction.id
3273
+ });
3274
+ });
3275
+ eventEmitter.on('error', data => {
3276
+ if (data.errors.length > 0) {
3277
+ originEmitter.emit('error', {
3278
+ ...data,
3279
+ id: originTransaction.id
3280
+ });
3281
+ }
3282
+ });
3283
+ eventEmitter.on('timeout', data => {
3284
+ if (data.errors.some(error => error.errorType === BasicTxErrorType.TIMEOUT)) {
3285
+ originEmitter.emit('timeout', {
3286
+ ...data,
3287
+ id: originTransaction.id
3288
+ });
3289
+ }
3290
+ });
3291
+ };
3292
+
3293
+ /**
3294
+ * ─────────────────────────────
3295
+ * Execute wrapped transaction
3296
+ * ─────────────────────────────
3297
+ */
3298
+
3299
+ // Case 1: signer === proxied address → handle original transaction
3300
+ if (isSignerProxiedAccount) {
3301
+ let callDataFinal = callData;
3302
+ let decodedCallDataFinal = decodedCallData;
3303
+ const pendingMultisigTxRequest = originTransaction.data;
3304
+ if (pendingMultisigTxRequest.call && pendingMultisigTxRequest.decodedCallData) {
3305
+ callDataFinal = pendingMultisigTxRequest.call;
3306
+ decodedCallDataFinal = pendingMultisigTxRequest.decodedCallData;
3307
+ }
3308
+ const response = await this.#koniState.transactionService.handleWrappedTransaction({
3309
+ ...originTransaction,
3310
+ skipFeeValidation: false,
3311
+ data: {
3312
+ ...originTransaction.data,
3313
+ // output
3314
+ decodedCallData: decodedCallDataFinal,
3315
+ submittedCallData: substrateProxyExtrinsic.toHex(),
3316
+ callData: callDataFinal,
3317
+ networkFee
3318
+ },
3319
+ errors: [],
3320
+ // Clear previous errors
3321
+ wrappingStatus: SubstrateTransactionWrappingStatus.WRAP_RESULT,
3322
+ eventsHandler
3323
+ });
3324
+
3325
+ // Clear wrappingStatus since no wrapping is needed
3326
+ delete response.wrappingStatus;
3327
+ return response;
3328
+ }
3329
+
3330
+ // Case 2: create and handle substrate proxy transaction
3331
+ return await this.#koniState.transactionService.handleWrappedTransaction({
3332
+ address: signer,
3333
+ chain,
3334
+ chainType: ChainType.SUBSTRATE,
3335
+ extrinsicType: ExtrinsicType.SUBSTRATE_PROXY_INIT_TX,
3336
+ transaction: substrateProxyExtrinsic,
3337
+ skipFeeValidation: true,
3338
+ transferNativeAmount: originTransaction.transferNativeAmount,
3339
+ data: {
3340
+ // input
3341
+ ...request,
3342
+ // output
3343
+ decodedCallData,
3344
+ submittedCallData: substrateProxyExtrinsic.toHex(),
3345
+ callData,
3346
+ networkFee
3347
+ },
3348
+ wrappingStatus: SubstrateTransactionWrappingStatus.WRAP_RESULT,
3349
+ additionalValidator,
3350
+ eventsHandler
3351
+ });
3352
+ }
3353
+
2921
3354
  // EVM Transaction
2922
3355
  async parseContractInput({
2923
3356
  chainId,
@@ -3320,8 +3753,6 @@ export default class KoniExtension {
3320
3753
  return await this.#koniState.reloadStaking();
3321
3754
  } else if (data === 'balance') {
3322
3755
  return await this.#koniState.reloadBalance();
3323
- } else if (data === 'crowdloan') {
3324
- return await this.#koniState.reloadCrowdloan();
3325
3756
  }
3326
3757
  return Promise.resolve(false);
3327
3758
  }
@@ -3749,8 +4180,7 @@ export default class KoniExtension {
3749
4180
  isPassConfirmation,
3750
4181
  onSend,
3751
4182
  path,
3752
- processId,
3753
- signerSubstrateProxyAddress
4183
+ processId
3754
4184
  } = inputData;
3755
4185
  const {
3756
4186
  address
@@ -3881,7 +4311,6 @@ export default class KoniExtension {
3881
4311
  // change this depends on step
3882
4312
  chainType,
3883
4313
  resolveOnDone: !isLastStep,
3884
- signerSubstrateProxyAddress,
3885
4314
  transferNativeAmount,
3886
4315
  balanceType: balanceTypeForPool,
3887
4316
  skipFeeValidation: isMintingStep && isPoolSupportAlternativeFee,
@@ -3894,7 +4323,6 @@ export default class KoniExtension {
3894
4323
  async handleYieldLeave(params) {
3895
4324
  const {
3896
4325
  address,
3897
- signerSubstrateProxyAddress,
3898
4326
  slug
3899
4327
  } = params;
3900
4328
  const leaveValidation = await this.#koniState.earningService.validateYieldLeave(params);
@@ -3910,7 +4338,6 @@ export default class KoniExtension {
3910
4338
  data: params,
3911
4339
  // TODO
3912
4340
  extrinsicType,
3913
- signerSubstrateProxyAddress,
3914
4341
  chainType: (handler === null || handler === void 0 ? void 0 : handler.transactionChainType) || ChainType.SUBSTRATE
3915
4342
  });
3916
4343
  }
@@ -3987,7 +4414,6 @@ export default class KoniExtension {
3987
4414
  async yieldSubmitWithdrawal(params) {
3988
4415
  const {
3989
4416
  address,
3990
- signerSubstrateProxyAddress,
3991
4417
  slug
3992
4418
  } = params;
3993
4419
  const poolHandler = this.#koniState.earningService.getPoolHandler(slug);
@@ -4001,7 +4427,6 @@ export default class KoniExtension {
4001
4427
  transaction: extrinsic,
4002
4428
  data: params,
4003
4429
  extrinsicType: ExtrinsicType.STAKING_WITHDRAW,
4004
- signerSubstrateProxyAddress,
4005
4430
  chainType: (poolHandler === null || poolHandler === void 0 ? void 0 : poolHandler.transactionChainType) || ChainType.SUBSTRATE
4006
4431
  });
4007
4432
  }
@@ -4009,7 +4434,6 @@ export default class KoniExtension {
4009
4434
  const {
4010
4435
  address,
4011
4436
  selectedUnstaking,
4012
- signerSubstrateProxyAddress,
4013
4437
  slug
4014
4438
  } = params;
4015
4439
  const poolHandler = this.#koniState.earningService.getPoolHandler(slug);
@@ -4024,14 +4448,12 @@ export default class KoniExtension {
4024
4448
  transaction: extrinsic,
4025
4449
  data: params,
4026
4450
  extrinsicType: ExtrinsicType.STAKING_CANCEL_UNSTAKE,
4027
- signerSubstrateProxyAddress,
4028
4451
  chainType: (poolHandler === null || poolHandler === void 0 ? void 0 : poolHandler.transactionChainType) || ChainType.SUBSTRATE
4029
4452
  });
4030
4453
  }
4031
4454
  async yieldSubmitClaimReward(params) {
4032
4455
  const {
4033
4456
  address,
4034
- signerSubstrateProxyAddress,
4035
4457
  slug
4036
4458
  } = params;
4037
4459
  const poolHandler = this.#koniState.earningService.getPoolHandler(slug);
@@ -4044,7 +4466,6 @@ export default class KoniExtension {
4044
4466
  chain: poolHandler.chain,
4045
4467
  transaction: extrinsic,
4046
4468
  data: params,
4047
- signerSubstrateProxyAddress,
4048
4469
  extrinsicType: ExtrinsicType.STAKING_CLAIM_REWARD,
4049
4470
  chainType: (poolHandler === null || poolHandler === void 0 ? void 0 : poolHandler.transactionChainType) || ChainType.SUBSTRATE
4050
4471
  });
@@ -4063,7 +4484,6 @@ export default class KoniExtension {
4063
4484
  async handleYieldChangeValidator(params) {
4064
4485
  const {
4065
4486
  address,
4066
- signerSubstrateProxyAddress,
4067
4487
  slug
4068
4488
  } = params;
4069
4489
  const poolHandler = this.#koniState.earningService.getPoolHandler(slug);
@@ -4076,7 +4496,6 @@ export default class KoniExtension {
4076
4496
  chain: poolHandler.chain,
4077
4497
  transaction: extrinsic,
4078
4498
  data: params,
4079
- signerSubstrateProxyAddress,
4080
4499
  extrinsicType: ExtrinsicType.CHANGE_EARNING_VALIDATOR,
4081
4500
  chainType: ChainType.SUBSTRATE
4082
4501
  });
@@ -4446,8 +4865,8 @@ export default class KoniExtension {
4446
4865
  });
4447
4866
  return await this.#koniState.inappNotificationService.getUnreadNotificationsCountMap();
4448
4867
  }
4449
- markAllReadNotification(proxyId) {
4450
- return this.#koniState.inappNotificationService.markAllRead(proxyId);
4868
+ markAllReadNotification(params) {
4869
+ return this.#koniState.inappNotificationService.markAllRead(params);
4451
4870
  }
4452
4871
  switchReadNotificationStatus(params) {
4453
4872
  return this.#koniState.inappNotificationService.switchReadStatus(params);
@@ -4764,10 +5183,9 @@ export default class KoniExtension {
4764
5183
  async handleAddSubstrateProxyAccount(params) {
4765
5184
  const {
4766
5185
  address,
4767
- chain,
4768
- signerSubstrateProxyAddress
5186
+ chain
4769
5187
  } = params;
4770
- const validationErrors = await this.#koniState.substrateProxyAccountService.validateAddSubstrateProxyAccount(params, signerSubstrateProxyAddress);
5188
+ const validationErrors = await this.#koniState.substrateProxyAccountService.validateAddSubstrateProxyAccount(params);
4771
5189
  if (validationErrors.length > 0) {
4772
5190
  return this.#koniState.transactionService.generateBeforeHandleResponseErrors(validationErrors);
4773
5191
  }
@@ -4778,15 +5196,13 @@ export default class KoniExtension {
4778
5196
  transaction: extrinsic,
4779
5197
  data: params,
4780
5198
  extrinsicType: ExtrinsicType.ADD_SUBSTRATE_PROXY_ACCOUNT,
4781
- chainType: ChainType.SUBSTRATE,
4782
- signerSubstrateProxyAddress
5199
+ chainType: ChainType.SUBSTRATE
4783
5200
  });
4784
5201
  }
4785
5202
  async handleRemoveSubstrateProxyAccount(params) {
4786
5203
  const {
4787
5204
  address,
4788
- chain,
4789
- signerSubstrateProxyAddress
5205
+ chain
4790
5206
  } = params;
4791
5207
  const extrinsic = await this.#koniState.substrateProxyAccountService.removeSubstrateProxyAccounts(params);
4792
5208
  return await this.#koniState.transactionService.handleTransaction({
@@ -4795,8 +5211,7 @@ export default class KoniExtension {
4795
5211
  transaction: extrinsic,
4796
5212
  data: params,
4797
5213
  extrinsicType: ExtrinsicType.REMOVE_SUBSTRATE_PROXY_ACCOUNT,
4798
- chainType: ChainType.SUBSTRATE,
4799
- signerSubstrateProxyAddress
5214
+ chainType: ChainType.SUBSTRATE
4800
5215
  });
4801
5216
  }
4802
5217
 
@@ -4812,8 +5227,7 @@ export default class KoniExtension {
4812
5227
  transaction: extrinsic,
4813
5228
  data: request,
4814
5229
  extrinsicType: ExtrinsicType.GOV_VOTE,
4815
- chainType: ChainType.SUBSTRATE,
4816
- signerSubstrateProxyAddress: request.signerSubstrateProxyAddress
5230
+ chainType: ChainType.SUBSTRATE
4817
5231
  });
4818
5232
  }
4819
5233
  async handleRemoveVote(request) {
@@ -4824,8 +5238,7 @@ export default class KoniExtension {
4824
5238
  transaction: extrinsic,
4825
5239
  data: request,
4826
5240
  extrinsicType: ExtrinsicType.GOV_UNVOTE,
4827
- chainType: ChainType.SUBSTRATE,
4828
- signerSubstrateProxyAddress: request.signerSubstrateProxyAddress
5241
+ chainType: ChainType.SUBSTRATE
4829
5242
  });
4830
5243
  }
4831
5244
  async handleUnlockVote(request) {
@@ -4836,8 +5249,7 @@ export default class KoniExtension {
4836
5249
  transaction: extrinsic,
4837
5250
  data: request,
4838
5251
  extrinsicType: ExtrinsicType.GOV_UNLOCK_VOTE,
4839
- chainType: ChainType.SUBSTRATE,
4840
- signerSubstrateProxyAddress: request.signerSubstrateProxyAddress
5252
+ chainType: ChainType.SUBSTRATE
4841
5253
  });
4842
5254
  }
4843
5255
  async subscribeGovLockedInfo(id, port) {
@@ -4857,6 +5269,25 @@ export default class KoniExtension {
4857
5269
 
4858
5270
  /* Open Gov */
4859
5271
 
5272
+ /* Multisig Acocunt */
5273
+
5274
+ async subscribePendingMultisigTx(id, port) {
5275
+ const cb = createSubscription(id, port);
5276
+ await this.#koniState.multisigService.waitForStarted();
5277
+ const pendingTxSubscription = this.#koniState.multisigService.subscribePendingMultisigTxMap().subscribe({
5278
+ next: rs => {
5279
+ cb(rs);
5280
+ }
5281
+ });
5282
+ this.createUnsubscriptionHandle(id, pendingTxSubscription.unsubscribe);
5283
+ port.onDisconnect.addListener(() => {
5284
+ this.cancelSubscription(id);
5285
+ });
5286
+ return this.#koniState.multisigService.getPendingMultisigTxMap();
5287
+ }
5288
+
5289
+ /* Multisig Acocunt */
5290
+
4860
5291
  // --------------------------------------------------------------
4861
5292
  // eslint-disable-next-line @typescript-eslint/require-await
4862
5293
  async handle(id, type, request, port) {
@@ -5063,6 +5494,8 @@ export default class KoniExtension {
5063
5494
  return this.accountsCreateSuriV2(request);
5064
5495
  case 'pri(accounts.create.externalV2)':
5065
5496
  return await this.accountsCreateExternalV2(request);
5497
+ case 'pri(accounts.create.multisig)':
5498
+ return await this.accountsCreateMultisig(request);
5066
5499
  case 'pri(accounts.create.hardwareV2)':
5067
5500
  return await this.accountsCreateHardwareV2(request);
5068
5501
  case 'pri(accounts.create.hardwareMultiple)':
@@ -5515,6 +5948,7 @@ export default class KoniExtension {
5515
5948
  return this.migrateSoloAccount(request);
5516
5949
  case 'pri(migrate.pingSession)':
5517
5950
  return this.pingSession(request);
5951
+ /* Migrate Unified Account */
5518
5952
 
5519
5953
  /* Gov */
5520
5954
  case 'pri(openGov.vote)':
@@ -5525,6 +5959,24 @@ export default class KoniExtension {
5525
5959
  return this.handleUnlockVote(request);
5526
5960
  case 'pri(openGov.subscribeGovLockedInfo)':
5527
5961
  return this.subscribeGovLockedInfo(id, port);
5962
+ /* Gov */
5963
+
5964
+ /* Multisig Account */
5965
+ case 'pri(multisig.subscribePendingMultisigTxs)':
5966
+ return await this.subscribePendingMultisigTx(id, port);
5967
+ case 'pri(multisig.getPendingMultisigTxs)':
5968
+ return this.#koniState.multisigService.getPendingTxsForMultisigAddress(request);
5969
+ case 'pri(multisig.approvePendingTx)':
5970
+ return await this.approvePendingTx(request);
5971
+ case 'pri(multisig.executePendingTx)':
5972
+ return await this.executePendingTx(request);
5973
+ case 'pri(multisig.cancelPendingTx)':
5974
+ return await this.cancelPendingTx(request);
5975
+ case 'pri(multisig.initMultisigTx)':
5976
+ return await this.initMultisigTx(request);
5977
+ case 'pri(multisig.getSignableAccountInfos)':
5978
+ return this.#koniState.keyringService.context.getSignableAccountInfos(request);
5979
+ /* Multisig Account */
5528
5980
 
5529
5981
  // Proxy
5530
5982
  case 'pri(substrateProxyAccount.getGroupInfo)':
@@ -5533,7 +5985,8 @@ export default class KoniExtension {
5533
5985
  return this.handleAddSubstrateProxyAccount(request);
5534
5986
  case 'pri(substrateProxyAccount.remove)':
5535
5987
  return this.handleRemoveSubstrateProxyAccount(request);
5536
-
5988
+ case 'pri(substrateProxyAccount.handleProxyWrappedTx)':
5989
+ return this.handleSubstrateProxyWrappedTx(request);
5537
5990
  // Default
5538
5991
  default:
5539
5992
  throw new Error(`Unable to handle message of type ${type}`);