@subwallet/extension-base 1.3.76-0 → 1.3.77-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 (42) hide show
  1. package/background/KoniTypes.d.ts +2 -1
  2. package/cjs/core/substrate/xcm-parser.js +8 -11
  3. package/cjs/koni/background/handlers/Extension.js +258 -63
  4. package/cjs/koni/background/handlers/Tabs.js +2 -3
  5. package/cjs/packageInfo.js +1 -1
  6. package/cjs/services/chain-service/utils/patch.js +1 -1
  7. package/cjs/services/earning-service/constants/chains.js +4 -1
  8. package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +8 -5
  9. package/cjs/services/earning-service/service.js +18 -2
  10. package/cjs/services/multisig-service/index.js +1 -1
  11. package/cjs/services/request-service/handler/SubstrateRequestHandler.js +12 -0
  12. package/cjs/services/request-service/index.js +3 -0
  13. package/cjs/services/setting-service/constants.js +2 -1
  14. package/cjs/services/storage-service/db-stores/InappNotification.js +1 -1
  15. package/cjs/services/transaction-service/index.js +9 -0
  16. package/core/substrate/xcm-parser.d.ts +1 -0
  17. package/core/substrate/xcm-parser.js +7 -11
  18. package/koni/background/handlers/Extension.d.ts +19 -0
  19. package/koni/background/handlers/Extension.js +197 -5
  20. package/koni/background/handlers/Tabs.js +2 -3
  21. package/package.json +6 -6
  22. package/packageInfo.js +1 -1
  23. package/services/chain-service/utils/patch.d.ts +1 -1
  24. package/services/chain-service/utils/patch.js +1 -1
  25. package/services/earning-service/constants/chains.d.ts +1 -0
  26. package/services/earning-service/constants/chains.js +2 -0
  27. package/services/earning-service/handlers/liquid-staking/stella-swap.d.ts +1 -0
  28. package/services/earning-service/handlers/liquid-staking/stella-swap.js +6 -4
  29. package/services/earning-service/service.js +20 -4
  30. package/services/inapp-notification-service/interfaces.d.ts +1 -0
  31. package/services/multisig-service/index.js +1 -1
  32. package/services/request-service/handler/SubstrateRequestHandler.d.ts +1 -0
  33. package/services/request-service/handler/SubstrateRequestHandler.js +12 -0
  34. package/services/request-service/index.d.ts +1 -0
  35. package/services/request-service/index.js +3 -0
  36. package/services/request-service/types.d.ts +1 -0
  37. package/services/setting-service/constants.js +2 -1
  38. package/services/storage-service/db-stores/InappNotification.js +1 -1
  39. package/services/transaction-service/index.d.ts +1 -1
  40. package/services/transaction-service/index.js +9 -0
  41. package/types/balance/transfer.d.ts +2 -0
  42. package/types/multisig/index.d.ts +12 -0
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.getStellaswapLiquidStakingContract = exports.default = void 0;
7
+ exports.getStellaswapLiquidStakingContract = exports.default = exports.STELLA_SWAP_LIQUID_STAKING_SLUG = void 0;
8
8
  var _TransactionError = require("@subwallet/extension-base/background/errors/TransactionError");
9
9
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
10
10
  var _web = require("@subwallet/extension-base/koni/api/contract-handler/evm/web3");
@@ -28,6 +28,8 @@ exports.getStellaswapLiquidStakingContract = getStellaswapLiquidStakingContract;
28
28
  const APR_STATS_URL = 'https://stdot-apr.stellaswap.com/';
29
29
  const SUBWALLET_REFERRAL = '0x7e6815f45E624768548d085231f2d453f16FD7DD';
30
30
  const TOP_HOLDER = '0x4300e09284e3bB4d9044DdAB31EfAF5f3301DABa';
31
+ const STELLA_SWAP_LIQUID_STAKING_SLUG = 'xcDOT___liquid_staking___stellaswap';
32
+ exports.STELLA_SWAP_LIQUID_STAKING_SLUG = STELLA_SWAP_LIQUID_STAKING_SLUG;
31
33
  class StellaSwapLiquidStakingPoolHandler extends _base.default {
32
34
  inputAsset = 'moonbeam-LOCAL-xcDOT';
33
35
  altInputAsset = '';
@@ -37,8 +39,8 @@ class StellaSwapLiquidStakingPoolHandler extends _base.default {
37
39
  transactionChainType = _KoniTypes.ChainType.EVM;
38
40
  rateDecimals = 10; // Derivative asset decimals
39
41
  availableMethod = {
40
- join: true,
41
- defaultUnstake: true,
42
+ join: false,
43
+ defaultUnstake: false,
42
44
  fastUnstake: false,
43
45
  cancelUnstake: false,
44
46
  withdraw: true,
@@ -47,7 +49,7 @@ class StellaSwapLiquidStakingPoolHandler extends _base.default {
47
49
  };
48
50
  constructor(state, chain) {
49
51
  super(state, chain);
50
- this.slug = 'xcDOT___liquid_staking___stellaswap';
52
+ this.slug = STELLA_SWAP_LIQUID_STAKING_SLUG;
51
53
  this.name = 'StellaSwap Liquid Staking';
52
54
  this._logo = 'stellaswap';
53
55
  this.shortName = 'StellaSwap';
@@ -170,7 +172,8 @@ class StellaSwapLiquidStakingPoolHandler extends _base.default {
170
172
  unstakeBalance: unlockBalance.toString(),
171
173
  isBondedBefore: totalBalance.gt(_util.BN_ZERO),
172
174
  derivativeToken: derivativeTokenSlug,
173
- status: activeBalance.gt(_util.BN_ZERO) ? _types.EarningStatus.EARNING_REWARD : _types.EarningStatus.NOT_EARNING,
175
+ // StellaSwap announced all stDOT positions are auto-unstaking, so rewards are no longer earned.
176
+ status: _types.EarningStatus.NOT_EARNING,
174
177
  nominations: [],
175
178
  unstakings
176
179
  };
@@ -441,6 +441,14 @@ class EarningService {
441
441
  }
442
442
  const updatedItem = structuredClone(item);
443
443
  updatedItem.metadata.availableMethod = handler.availableMethod;
444
+
445
+ // Disable staking for sunsetted pools
446
+ if (_constants2.SUNSETTED_YIELD_POOL_SLUGS.includes(item.slug)) {
447
+ updatedItem.metadata.availableMethod = {
448
+ ...updatedItem.metadata.availableMethod,
449
+ join: false
450
+ };
451
+ }
444
452
  this.updateYieldPoolInfo(updatedItem);
445
453
  });
446
454
  return onlineData;
@@ -535,7 +543,11 @@ class EarningService {
535
543
  const yieldPositionInfo = this.yieldPositionSubject.getValue();
536
544
  existedYieldPosition.forEach(item => {
537
545
  if (!this.inactivePoolSlug.has(item.slug)) {
538
- yieldPositionInfo[this._getYieldPositionKey(item.slug, item.address)] = item;
546
+ const normalizedItem = _constants2.SUNSETTED_YIELD_POOL_SLUGS.includes(item.slug) ? {
547
+ ...item,
548
+ status: _types2.EarningStatus.NOT_EARNING
549
+ } : item;
550
+ yieldPositionInfo[this._getYieldPositionKey(item.slug, item.address)] = normalizedItem;
539
551
  }
540
552
  });
541
553
  this.yieldPositionSubject.next(yieldPositionInfo);
@@ -558,7 +570,11 @@ class EarningService {
558
570
  return `${slug}---${address}`;
559
571
  }
560
572
  updateYieldPosition(data) {
561
- this.yieldPositionPersistQueue.push(data);
573
+ const normalizedData = _constants2.SUNSETTED_YIELD_POOL_SLUGS.includes(data.slug) ? {
574
+ ...data,
575
+ status: _types2.EarningStatus.NOT_EARNING
576
+ } : data;
577
+ this.yieldPositionPersistQueue.push(normalizedData);
562
578
  (0, _utils2.addLazy)('persistYieldPositionInfo', () => {
563
579
  const yieldPositionInfo = this.yieldPositionSubject.getValue();
564
580
  const queue = [...this.yieldPositionPersistQueue];
@@ -212,7 +212,7 @@ class MultisigService {
212
212
  */
213
213
  handleEvents(events, eventTypes) {
214
214
  let needReload = false;
215
- if (eventTypes.includes('account.add') || eventTypes.includes('account.remove')) {
215
+ if (eventTypes.includes('account.add') || eventTypes.includes('account.remove') || eventTypes.includes('account.updateCurrent')) {
216
216
  needReload = true;
217
217
  }
218
218
  if (eventTypes.includes('chain.updateState') || eventTypes.includes('transaction.done')) {
@@ -44,6 +44,18 @@ class SubstrateRequestHandler {
44
44
  };
45
45
  });
46
46
  }
47
+ updateSignRequest(id, request, signerAddress) {
48
+ const current = this.getSignRequest(id);
49
+ if (!current) {
50
+ throw new _TransactionError.TransactionError(_types.BasicTxErrorType.INVALID_PARAMS, 'Sign request not found');
51
+ }
52
+ this.#substrateRequests[id] = {
53
+ ...current,
54
+ request,
55
+ signerAddress: signerAddress || current.signerAddress
56
+ };
57
+ this.updateIconSign();
58
+ }
47
59
  updateIconSign(shouldClose) {
48
60
  this.signSubject.next(this.allSubstrateRequests);
49
61
  this.#requestService.updateIconV2(shouldClose);
@@ -175,6 +175,9 @@ class RequestService {
175
175
  getSignRequest(id) {
176
176
  return this.#substrateRequestHandler.getSignRequest(id);
177
177
  }
178
+ updateSignRequest(id, request, signerAddress) {
179
+ this.#substrateRequestHandler.updateSignRequest(id, request, signerAddress);
180
+ }
178
181
  async signInternalTransaction(id, address, url, payload, onSign, isWrappedTx) {
179
182
  if (isWrappedTx === _types.SubstrateTransactionWrappingStatus.WRAP_RESULT) {
180
183
  return this.#substrateRequestHandler.signWrappedTransaction(id, address, url, payload, onSign);
@@ -41,7 +41,8 @@ const DEFAULT_NOTIFICATION_SETUP = {
41
41
  earningClaim: true,
42
42
  earningWithdraw: true,
43
43
  availBridgeClaim: true,
44
- polygonBridgeClaim: true
44
+ polygonBridgeClaim: true,
45
+ pendingMultisigApprovals: true
45
46
  // isHideWithdraw: false, // todo: just for test, remove later
46
47
  // isHideMarketing: false,
47
48
  // isHideAnnouncement: false
@@ -89,7 +89,7 @@ class InappNotificationStore extends _BaseStore.default {
89
89
  isRead: true
90
90
  });
91
91
  }
92
- return this.table.where('proxyId').equalsIgnoreCase(proxyId).modify({
92
+ return this.table.where('proxyId').equalsIgnoreCase(proxyId).filter(notification => !excludeNotificationIds.includes(notification.id)).modify({
93
93
  isRead: true
94
94
  });
95
95
  }
@@ -1378,6 +1378,15 @@ class TransactionService {
1378
1378
  case _KoniTypes.ExtrinsicType.UNKNOWN:
1379
1379
  break;
1380
1380
  }
1381
+ const txData = transaction.data;
1382
+ const signer = txData === null || txData === void 0 ? void 0 : txData.signer;
1383
+ if (signer) {
1384
+ const currentAdditionalInfo = historyItem.additionalInfo ? historyItem.additionalInfo : {};
1385
+ historyItem.additionalInfo = {
1386
+ ...currentAdditionalInfo,
1387
+ signer
1388
+ };
1389
+ }
1381
1390
  try {
1382
1391
  // Return one more history record if transaction send to account in the wallets
1383
1392
  const toAccount = (historyItem === null || historyItem === void 0 ? void 0 : historyItem.to) && _uiKeyring.default.getPair(historyItem.to);
@@ -8,4 +8,5 @@ export declare function _isMythosFromHydrationToMythos(originChainInfo: _ChainIn
8
8
  export declare function _isPolygonBridgeXcm(originChainInfo: _ChainInfo, destChainInfo: _ChainInfo): boolean;
9
9
  export declare function _isPosBridgeXcm(originChainInfo: _ChainInfo, destChainInfo: _ChainInfo): boolean;
10
10
  export declare function _isAcrossBridgeXcm(originChainInfo: _ChainInfo, destChainInfo: _ChainInfo): boolean;
11
+ export declare function _isAssetHubBridgeXcm(originChainInfo: _ChainInfo, destChainInfo: _ChainInfo): boolean;
11
12
  export declare function _adaptX1Interior(_assetIdentifier: Record<string, any>, version: number): Record<string, any>;
@@ -8,17 +8,10 @@ import { _isPolygonChainBridge } from '@subwallet/extension-base/services/balanc
8
8
  import { _isPosChainBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/posBridge';
9
9
  import { _getSubstrateRelayParent, _isPureEvmChain } from '@subwallet/extension-base/services/chain-service/utils';
10
10
  export function _isXcmTransferUnstable(originChainInfo, destChainInfo, assetSlug) {
11
- return !_isXcmWithinSameConsensus(originChainInfo, destChainInfo) || _isMythosFromHydrationToMythos(originChainInfo, destChainInfo, assetSlug) || _isPolygonBridgeXcm(originChainInfo, destChainInfo) || _isPosBridgeXcm(originChainInfo, destChainInfo);
11
+ return !_isXcmWithinSameConsensus(originChainInfo, destChainInfo) && !_isAssetHubBridgeXcm || _isMythosFromHydrationToMythos(originChainInfo, destChainInfo, assetSlug) || _isPolygonBridgeXcm(originChainInfo, destChainInfo) || _isPosBridgeXcm(originChainInfo, destChainInfo);
12
12
  }
13
- function getAssetHubBridgeUnstableWarning(originChainInfo) {
14
- switch (originChainInfo.slug) {
15
- case COMMON_CHAIN_SLUGS.POLKADOT_ASSET_HUB:
16
- return 'Cross-chain transfer of this token is not recommended as it is in beta and incurs a transaction fee of 2 DOT. Continue at your own risk';
17
- case COMMON_CHAIN_SLUGS.KUSAMA_ASSET_HUB:
18
- return 'Cross-chain transfer of this token is not recommended as it is in beta and incurs a transaction fee of 0.4 KSM. Continue at your own risk';
19
- default:
20
- return 'Cross-chain transfer of this token is not recommended as it is in beta and incurs a large transaction fee. Continue at your own risk';
21
- }
13
+ function getDefaultUnstableWarning() {
14
+ return 'Cross-chain transfer of this token is not recommended as it is in beta and incurs a large transaction fee. Continue at your own risk';
22
15
  }
23
16
  function getSnowBridgeUnstableWarning(originChainInfo) {
24
17
  switch (originChainInfo.slug) {
@@ -62,7 +55,7 @@ export function _getXcmUnstableWarning(originChainInfo, destChainInfo, assetSlug
62
55
  } else if (_isMythosFromHydrationToMythos(originChainInfo, destChainInfo, assetSlug)) {
63
56
  return getMythosFromHydrationToMythosWarning();
64
57
  } else {
65
- return getAssetHubBridgeUnstableWarning(originChainInfo);
58
+ return getDefaultUnstableWarning();
66
59
  }
67
60
  }
68
61
  export function _isXcmWithinSameConsensus(originChainInfo, destChainInfo) {
@@ -88,6 +81,9 @@ export function _isPosBridgeXcm(originChainInfo, destChainInfo) {
88
81
  export function _isAcrossBridgeXcm(originChainInfo, destChainInfo) {
89
82
  return _isAcrossChainBridge(originChainInfo.slug, destChainInfo.slug);
90
83
  }
84
+ export function _isAssetHubBridgeXcm(originChainInfo, destChainInfo) {
85
+ return originChainInfo.slug === 'statemint' && destChainInfo.slug === 'statemine' || originChainInfo.slug === 'statemine' && destChainInfo.slug === 'statemint';
86
+ }
91
87
  // ---------------------------------------------------------------------------------------------------------------------
92
88
 
93
89
  export function _adaptX1Interior(_assetIdentifier, version) {
@@ -188,6 +188,25 @@ export default class KoniExtension {
188
188
  private executePendingTx;
189
189
  private cancelPendingTx;
190
190
  private initMultisigTx;
191
+ private buildExtrinsicFromPayload;
192
+ /**
193
+ * ─────────────────────────────────────────────────────────────
194
+ * prepareMultisigSignRequest
195
+ * ─────────────────────────────────────────────────────────────
196
+ * Called when a dApp sends a signing request to a multisig account.
197
+ * This method wraps the original extrinsic into a multisig.asMulti call so that it can be submitted by one of the signers on behalf of the multisig account.
198
+ *
199
+ * Important:
200
+ * - The original sign request is MUTATED in-place via updateSignRequest.
201
+ * After this method returns, the UI will prompt the signer to sign
202
+ * the wrapped multisig extrinsic, not the original one.
203
+ * - Errors are collected (not thrown) and returned in the response
204
+ * so the UI can display them without crashing.
205
+ * - This method does NOT submit the transaction; it only prepares
206
+ * the payload for signing.
207
+ * ─────────────────────────────────────────────────────────────
208
+ */
209
+ private prepareMultisigSignRequest;
191
210
  private handleSubstrateProxyWrappedTx;
192
211
  private parseContractInput;
193
212
  private submitTuringStakeCompounding;
@@ -8,6 +8,7 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
8
8
  import { withErrorLog } from '@subwallet/extension-base/background/handlers/helpers';
9
9
  import { createSubscription } from '@subwallet/extension-base/background/handlers/subscriptions';
10
10
  import { CampaignDataType, ChainType, ExternalRequestPromiseStatus, ExtrinsicType, MantaPayEnableMessage, StakingType } from '@subwallet/extension-base/background/KoniTypes';
11
+ import RequestExtrinsicSign from '@subwallet/extension-base/background/RequestExtrinsicSign';
11
12
  import { _SUPPORT_TOKEN_PAY_FEE_GROUP, ALL_ACCOUNT_KEY, BTC_DUST_AMOUNT, LATEST_SESSION } from '@subwallet/extension-base/constants';
12
13
  import { additionalValidateTransferForRecipient, validateTransferRequest, validateXcmMinAmountToMythos, validateXcmTransferRequest } from '@subwallet/extension-base/core/logic-validation/transfer';
13
14
  import { _isSnowBridgeXcm } from '@subwallet/extension-base/core/substrate/xcm-parser';
@@ -3153,8 +3154,134 @@ export default class KoniExtension {
3153
3154
  });
3154
3155
  }
3155
3156
 
3157
+ // Helper for prepareMultisigSignRequest: reconstruct the original extrinsic from the payload's method & args
3158
+ async buildExtrinsicFromPayload(chain, payload) {
3159
+ const substrateApi = await this.#koniState.chainService.getSubstrateApi(chain).isReady;
3160
+ const call = substrateApi.api.createType('Call', payload.method);
3161
+ const {
3162
+ method,
3163
+ section
3164
+ } = substrateApi.api.registry.findMetaCall(call.callIndex);
3165
+ const extrinsic = substrateApi.api.tx[section][method](...call.args);
3166
+ return {
3167
+ substrateApi,
3168
+ extrinsic,
3169
+ call
3170
+ };
3171
+ }
3172
+
3173
+ /**
3174
+ * ─────────────────────────────────────────────────────────────
3175
+ * prepareMultisigSignRequest
3176
+ * ─────────────────────────────────────────────────────────────
3177
+ * Called when a dApp sends a signing request to a multisig account.
3178
+ * This method wraps the original extrinsic into a multisig.asMulti call so that it can be submitted by one of the signers on behalf of the multisig account.
3179
+ *
3180
+ * Important:
3181
+ * - The original sign request is MUTATED in-place via updateSignRequest.
3182
+ * After this method returns, the UI will prompt the signer to sign
3183
+ * the wrapped multisig extrinsic, not the original one.
3184
+ * - Errors are collected (not thrown) and returned in the response
3185
+ * so the UI can display them without crashing.
3186
+ * - This method does NOT submit the transaction; it only prepares
3187
+ * the payload for signing.
3188
+ * ─────────────────────────────────────────────────────────────
3189
+ */
3190
+ async prepareMultisigSignRequest(request) {
3191
+ const {
3192
+ id,
3193
+ signer
3194
+ } = request;
3195
+
3196
+ // ── Step 1: Retrieve the pending sign request from the queue ──
3197
+ const queued = this.#koniState.getSignRequest(id);
3198
+ assert(queued, t('bg.koni.handler.Extension.unableToProceed'));
3199
+ const errors = [];
3200
+ let submittedCallData = '';
3201
+ let callData = '';
3202
+ let depositAmount = '';
3203
+ let networkFee = '';
3204
+ const payload = queued.request.payload;
3205
+
3206
+ // ── Step 2: Validate payload format ──
3207
+ // Only JSON payloads (SignerPayloadJSON) contain the structured fields
3208
+ // (genesisHash, method, etc.) needed to reconstruct the extrinsic.
3209
+ // Raw (bytes) payloads cannot be wrapped into a multisig call.
3210
+ if (!isJsonPayload(payload)) {
3211
+ errors.push(new TransactionError(BasicTxErrorType.INVALID_PARAMS, t('bg.koni.handler.Extension.unableToProceed')));
3212
+ } else {
3213
+ var _chainInfo$substrateI;
3214
+ // ── Step 3: Resolve chain from genesisHash & check multisig support ──
3215
+ callData = payload.method;
3216
+ const [chain, chainInfo] = this.#koniState.findNetworkKeyByGenesisHash(payload.genesisHash);
3217
+ if (!chain || !(chainInfo !== null && chainInfo !== void 0 && (_chainInfo$substrateI = chainInfo.substrateInfo) !== null && _chainInfo$substrateI !== void 0 && _chainInfo$substrateI.supportMultisig)) {
3218
+ errors.push(new TransactionError(BasicTxErrorType.UNSUPPORTED, t('bg.koni.handler.Extension.unableToProceed')));
3219
+ } else {
3220
+ // ── Step 4: Look up multisig account configuration ──
3221
+ // queued.address is the multisig account address (the "from" in the original request).
3222
+ // We need its threshold and signers list to construct the asMulti call.
3223
+ const accountProxy = this.#koniState.keyringService.context.getMultisigAccountByAddress(queued.address);
3224
+ if (!accountProxy) {
3225
+ errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, t('bg.koni.handler.Extension.unableToProceed')));
3226
+ } else {
3227
+ const threshold = accountProxy.accounts[0].threshold;
3228
+ const signers = accountProxy.accounts[0].signers;
3229
+
3230
+ // ── Step 5: Rebuild the original extrinsic from payload call data ──
3231
+ const {
3232
+ extrinsic: originExtrinsic,
3233
+ substrateApi
3234
+ } = await this.buildExtrinsicFromPayload(chain, payload);
3235
+
3236
+ // ── Step 6: Wrap into multisig initiation extrinsic ──
3237
+ const multisigExtrinsic = createInitMultisigExtrinsic(substrateApi.api, threshold, signers, signer, originExtrinsic);
3238
+
3239
+ // ── Step 7: Estimate fee & calculate multisig deposit ──
3240
+ submittedCallData = multisigExtrinsic.method.toHex();
3241
+ networkFee = (await multisigExtrinsic.paymentInfo(signer)).partialFee.toString();
3242
+ const depositBase = substrateApi.api.consts.multisig.depositBase.toString();
3243
+ const depositFactor = substrateApi.api.consts.multisig.depositFactor.toString();
3244
+ depositAmount = calcDepositAmount(depositBase, threshold, depositFactor);
3245
+
3246
+ // ── Step 8: Validate signer has sufficient balance ──
3247
+ const signerBalance = await this.getAddressTransferableBalance({
3248
+ address: signer,
3249
+ networkKey: chain,
3250
+ token: this.#koniState.chainService.getNativeTokenInfo(chain).slug,
3251
+ extrinsicType: ExtrinsicType.TRANSFER_TOKEN
3252
+ });
3253
+ const requiredBalance = new BigN(depositAmount).plus(networkFee);
3254
+ if (new BigN(signerBalance.value).lt(requiredBalance)) {
3255
+ errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, t('bg.koni.handler.Extension.notEnoughBalanceForMultisigDepositAndFee')));
3256
+ }
3257
+
3258
+ // ── Step 9: Replace the original sign request with the wrapped payload ──
3259
+ // After this, the signing UI will show the multisig extrinsic instead of
3260
+ // the original one. The signer's address and fresh nonce are used so
3261
+ // the transaction is submitted from the signer (not the multisig account).
3262
+ const nonce = await substrateApi.api.rpc.system.accountNextIndex(signer);
3263
+ const wrappedPayload = {
3264
+ ...payload,
3265
+ address: signer,
3266
+ nonce: nonce.toHex(),
3267
+ method: multisigExtrinsic.method.toHex()
3268
+ };
3269
+ this.#koniState.requestService.updateSignRequest(id, new RequestExtrinsicSign(wrappedPayload), signer);
3270
+ }
3271
+ }
3272
+ }
3273
+ return {
3274
+ submittedCallData: submittedCallData,
3275
+ callData: callData,
3276
+ depositAmount,
3277
+ networkFee,
3278
+ errors
3279
+ };
3280
+ }
3281
+
3156
3282
  // Substrate Proxy Account
3157
3283
  async handleSubstrateProxyWrappedTx(request) {
3284
+ var _originTransaction;
3158
3285
  const {
3159
3286
  chain,
3160
3287
  proxyMetadata,
@@ -3171,8 +3298,8 @@ export default class KoniExtension {
3171
3298
  * ─────────────────────────────
3172
3299
  */
3173
3300
  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;
3301
+ let originTransaction = this.#koniState.transactionService.getTransaction(transactionId);
3302
+ const extrinsicOriginTransaction = (_originTransaction = originTransaction) === null || _originTransaction === void 0 ? void 0 : _originTransaction.transaction;
3176
3303
  const callData = extrinsicOriginTransaction.method.toHex();
3177
3304
  const decodedCallData = decodeCallData({
3178
3305
  api: substrateApi.api,
@@ -3244,7 +3371,8 @@ export default class KoniExtension {
3244
3371
  * update history transaction accordingly.
3245
3372
  */
3246
3373
  const eventsHandler = eventEmitter => {
3247
- if (!(originTransaction !== null && originTransaction !== void 0 && originTransaction.emitterTransaction)) {
3374
+ var _originTransaction2;
3375
+ if (!((_originTransaction2 = originTransaction) !== null && _originTransaction2 !== void 0 && _originTransaction2.emitterTransaction)) {
3248
3376
  return;
3249
3377
  }
3250
3378
  const originEmitter = originTransaction.emitterTransaction;
@@ -3296,6 +3424,49 @@ export default class KoniExtension {
3296
3424
  * ─────────────────────────────
3297
3425
  */
3298
3426
 
3427
+ const originTransferData = originTransaction.data;
3428
+ const isTransferAllBalance = originTransaction.extrinsicType === ExtrinsicType.TRANSFER_BALANCE && !!(originTransferData !== null && originTransferData !== void 0 && originTransferData.transferAll);
3429
+ const maxTransferableWithoutFee = originTransferData === null || originTransferData === void 0 ? void 0 : originTransferData.maxTransferableWithoutFee;
3430
+ const maxTransferable = originTransferData === null || originTransferData === void 0 ? void 0 : originTransferData.maxTransferable;
3431
+ if (isTransferAllBalance && !!maxTransferableWithoutFee && !!maxTransferable) {
3432
+ if (isSignerProxiedAccount) {
3433
+ this.#koniState.transactionService.updateTransaction(transactionId, {
3434
+ data: {
3435
+ ...originTransferData,
3436
+ value: maxTransferable,
3437
+ transferNativeAmount: maxTransferable
3438
+ }
3439
+ });
3440
+ } else {
3441
+ this.#koniState.transactionService.updateTransaction(transactionId, {
3442
+ data: {
3443
+ ...originTransferData,
3444
+ value: maxTransferableWithoutFee,
3445
+ transferNativeAmount: maxTransferableWithoutFee
3446
+ }
3447
+ });
3448
+ }
3449
+
3450
+ // Refresh originTransaction after update
3451
+ originTransaction = this.#koniState.transactionService.getTransaction(transactionId);
3452
+ }
3453
+
3454
+ // If signer is the proxied account itself, the original transaction will be signed and sent directly without proxy execution.
3455
+ if (isSignerProxiedAccount) {
3456
+ const restData = Object.fromEntries(Object.entries(originTransaction.data || {}).filter(([key]) => key !== 'signer'));
3457
+ this.#koniState.transactionService.updateTransaction(transactionId, {
3458
+ data: restData
3459
+ });
3460
+ } else {
3461
+ this.#koniState.transactionService.updateTransaction(transactionId, {
3462
+ data: {
3463
+ ...originTransaction.data,
3464
+ signer
3465
+ }
3466
+ });
3467
+ }
3468
+ originTransaction = this.#koniState.transactionService.getTransaction(transactionId);
3469
+
3299
3470
  // Case 1: signer === proxied address → handle original transaction
3300
3471
  if (isSignerProxiedAccount) {
3301
3472
  let callDataFinal = callData;
@@ -3343,6 +3514,8 @@ export default class KoniExtension {
3343
3514
  decodedCallData,
3344
3515
  submittedCallData: substrateProxyExtrinsic.toHex(),
3345
3516
  callData,
3517
+ signer,
3518
+ signerAddress: signer,
3346
3519
  networkFee
3347
3520
  },
3348
3521
  wrappingStatus: SubstrateTransactionWrappingStatus.WRAP_RESULT,
@@ -3530,7 +3703,8 @@ export default class KoniExtension {
3530
3703
  request,
3531
3704
  resolve
3532
3705
  } = queued;
3533
- const pair = keyring.getPair(queued.address);
3706
+ const signingAddress = queued.signerAddress || queued.address;
3707
+ const pair = keyring.getPair(signingAddress);
3534
3708
 
3535
3709
  // unlike queued.account.address the following
3536
3710
  // address is encoded with the default prefix
@@ -3560,10 +3734,26 @@ export default class KoniExtension {
3560
3734
  }
3561
3735
  }
3562
3736
  const result = request.sign(registry, pair);
3737
+ let signedTransaction;
3738
+ if (queued.signerAddress && isJsonPayload(payload)) {
3739
+ try {
3740
+ const [chain] = this.#koniState.findNetworkKeyByGenesisHash(payload.genesisHash);
3741
+ if (chain) {
3742
+ const {
3743
+ extrinsic
3744
+ } = await this.buildExtrinsicFromPayload(chain, payload);
3745
+ extrinsic.addSignature(payload.address, result.signature, payload);
3746
+ signedTransaction = extrinsic.toHex();
3747
+ }
3748
+ } catch (e) {
3749
+ console.error('Failed to build signed transaction for wrapped multisig signing', e);
3750
+ }
3751
+ }
3563
3752
  resolve({
3564
3753
  id,
3565
3754
  // In case evm chain, must be cut 2 character after 0x
3566
- signature: result.signature
3755
+ signature: result.signature,
3756
+ signedTransaction
3567
3757
  });
3568
3758
  if (this.#alwaysLock) {
3569
3759
  this.keyringLock();
@@ -6006,6 +6196,8 @@ export default class KoniExtension {
6006
6196
  return await this.cancelPendingTx(request);
6007
6197
  case 'pri(multisig.initMultisigTx)':
6008
6198
  return await this.initMultisigTx(request);
6199
+ case 'pri(multisig.prepareSignRequest)':
6200
+ return await this.prepareMultisigSignRequest(request);
6009
6201
  case 'pri(multisig.getSignableAccountInfos)':
6010
6202
  return this.#koniState.keyringService.context.getSignableAccountInfos(request);
6011
6203
  /* Multisig Account */
@@ -69,11 +69,10 @@ function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthTyp
69
69
  const injectedAccounts = Object.values(accounts).filter(({
70
70
  json: {
71
71
  meta: {
72
- isHidden,
73
- isMultisig
72
+ isHidden
74
73
  }
75
74
  }
76
- }) => !isHidden && !isMultisig).filter(authTypeFilter).filter(({
75
+ }) => !isHidden).filter(authTypeFilter).filter(({
77
76
  json: {
78
77
  address
79
78
  }
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.3.76-0",
20
+ "version": "1.3.77-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -3008,11 +3008,11 @@
3008
3008
  "@sora-substrate/type-definitions": "^1.17.7",
3009
3009
  "@substrate/connect": "^0.8.9",
3010
3010
  "@subwallet-monorepos/subwallet-services-sdk": "0.1.16",
3011
- "@subwallet/chain-list": "0.2.125",
3012
- "@subwallet/extension-base": "^1.3.76-0",
3013
- "@subwallet/extension-chains": "^1.3.76-0",
3014
- "@subwallet/extension-dapp": "^1.3.76-0",
3015
- "@subwallet/extension-inject": "^1.3.76-0",
3011
+ "@subwallet/chain-list": "0.2.126",
3012
+ "@subwallet/extension-base": "^1.3.77-0",
3013
+ "@subwallet/extension-chains": "^1.3.77-0",
3014
+ "@subwallet/extension-dapp": "^1.3.77-0",
3015
+ "@subwallet/extension-inject": "^1.3.77-0",
3016
3016
  "@subwallet/keyring": "^0.1.14",
3017
3017
  "@subwallet/ui-keyring": "^0.1.14",
3018
3018
  "@ton/core": "^0.56.3",
package/packageInfo.js CHANGED
@@ -7,5 +7,5 @@ export const packageInfo = {
7
7
  name: '@subwallet/extension-base',
8
8
  path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
9
9
  type: 'esm',
10
- version: '1.3.76-0'
10
+ version: '1.3.77-0'
11
11
  };
@@ -1,5 +1,5 @@
1
1
  import { _ChainAsset, _ChainInfo, _MultiChainAsset } from '@subwallet/chain-list/types';
2
- export declare const ChainListVersion = "0.2.123";
2
+ export declare const ChainListVersion = "0.2.126";
3
3
  export interface PatchInfo {
4
4
  patchVersion: string;
5
5
  appliedVersion: string;
@@ -5,7 +5,7 @@ const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
5
5
  const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
6
6
  const fetchDomain = process.env.PATCH_CHAIN_LIST_URL || (PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev');
7
7
  const fetchFile = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'list.json' : 'preview.json';
8
- export const ChainListVersion = '0.2.123'; // update this when build chain-list
8
+ export const ChainListVersion = '0.2.126'; // update this when build chain-list
9
9
 
10
10
  // todo: move this interface to chainlist
11
11
 
@@ -17,6 +17,7 @@ export declare const _STAKING_CHAIN_GROUP: {
17
17
  mythos: string[];
18
18
  tanssi: string[];
19
19
  };
20
+ export declare const SUNSETTED_YIELD_POOL_SLUGS: string[];
20
21
  export declare const RELAY_HANDLER_DIRECT_STAKING_CHAINS: string[];
21
22
  export declare const TON_CHAINS: string[];
22
23
  export declare const MaxEraRewardPointsEras = 14;
@@ -1,6 +1,7 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import { STELLA_SWAP_LIQUID_STAKING_SLUG } from "../handlers/liquid-staking/stella-swap.js";
4
5
  export const _STAKING_CHAIN_GROUP = {
5
6
  relay: ['polkadot', 'kusama', 'aleph', 'polkadex', 'ternoa', 'alephTest', 'polkadexTest', 'westend', 'kate', 'edgeware', 'creditcoin', 'vara_network', 'goldberg_testnet', 'availTuringTest', 'avail_mainnet', 'vara_testnet', 'dentnet', 'cere', 'zkverify', 'zkverify_testnet', 'paseoTest'],
6
7
  assetHub: ['statemine', 'statemint', 'westend_assethub', 'paseo_assethub'],
@@ -22,6 +23,7 @@ export const _STAKING_CHAIN_GROUP = {
22
23
  mythos: ['mythos', 'muse_testnet'],
23
24
  tanssi: ['tanssi', 'dancelight']
24
25
  };
26
+ export const SUNSETTED_YIELD_POOL_SLUGS = [STELLA_SWAP_LIQUID_STAKING_SLUG, 'MANTA___native_staking___manta_network'];
25
27
  export const RELAY_HANDLER_DIRECT_STAKING_CHAINS = [..._STAKING_CHAIN_GROUP.relay, ..._STAKING_CHAIN_GROUP.assetHub];
26
28
  export const TON_CHAINS = ['ton', 'ton_testnet'];
27
29
  export const MaxEraRewardPointsEras = 14;
@@ -6,6 +6,7 @@ import { BaseYieldStepDetail, HandleYieldStepData, LiquidYieldPoolInfo, OptimalY
6
6
  import { Contract } from 'web3-eth-contract';
7
7
  import BaseLiquidStakingPoolHandler from './base';
8
8
  export declare const getStellaswapLiquidStakingContract: (networkKey: string, assetAddress: string, evmApi: _EvmApi, options?: {}) => Contract;
9
+ export declare const STELLA_SWAP_LIQUID_STAKING_SLUG = "xcDOT___liquid_staking___stellaswap";
9
10
  export default class StellaSwapLiquidStakingPoolHandler extends BaseLiquidStakingPoolHandler {
10
11
  slug: string;
11
12
  protected readonly name: string;