@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.
- package/background/KoniTypes.d.ts +2 -1
- package/cjs/core/substrate/xcm-parser.js +8 -11
- package/cjs/koni/background/handlers/Extension.js +258 -63
- package/cjs/koni/background/handlers/Tabs.js +2 -3
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/chain-service/utils/patch.js +1 -1
- package/cjs/services/earning-service/constants/chains.js +4 -1
- package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +8 -5
- package/cjs/services/earning-service/service.js +18 -2
- package/cjs/services/multisig-service/index.js +1 -1
- package/cjs/services/request-service/handler/SubstrateRequestHandler.js +12 -0
- package/cjs/services/request-service/index.js +3 -0
- package/cjs/services/setting-service/constants.js +2 -1
- package/cjs/services/storage-service/db-stores/InappNotification.js +1 -1
- package/cjs/services/transaction-service/index.js +9 -0
- package/core/substrate/xcm-parser.d.ts +1 -0
- package/core/substrate/xcm-parser.js +7 -11
- package/koni/background/handlers/Extension.d.ts +19 -0
- package/koni/background/handlers/Extension.js +197 -5
- package/koni/background/handlers/Tabs.js +2 -3
- package/package.json +6 -6
- package/packageInfo.js +1 -1
- package/services/chain-service/utils/patch.d.ts +1 -1
- package/services/chain-service/utils/patch.js +1 -1
- package/services/earning-service/constants/chains.d.ts +1 -0
- package/services/earning-service/constants/chains.js +2 -0
- package/services/earning-service/handlers/liquid-staking/stella-swap.d.ts +1 -0
- package/services/earning-service/handlers/liquid-staking/stella-swap.js +6 -4
- package/services/earning-service/service.js +20 -4
- package/services/inapp-notification-service/interfaces.d.ts +1 -0
- package/services/multisig-service/index.js +1 -1
- package/services/request-service/handler/SubstrateRequestHandler.d.ts +1 -0
- package/services/request-service/handler/SubstrateRequestHandler.js +12 -0
- package/services/request-service/index.d.ts +1 -0
- package/services/request-service/index.js +3 -0
- package/services/request-service/types.d.ts +1 -0
- package/services/setting-service/constants.js +2 -1
- package/services/storage-service/db-stores/InappNotification.js +1 -1
- package/services/transaction-service/index.d.ts +1 -1
- package/services/transaction-service/index.js +9 -0
- package/types/balance/transfer.d.ts +2 -0
- 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:
|
|
41
|
-
defaultUnstake:
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
14
|
-
|
|
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
|
|
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
|
-
|
|
3175
|
-
const extrinsicOriginTransaction = originTransaction === null ||
|
|
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
|
-
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
3012
|
-
"@subwallet/extension-base": "^1.3.
|
|
3013
|
-
"@subwallet/extension-chains": "^1.3.
|
|
3014
|
-
"@subwallet/extension-dapp": "^1.3.
|
|
3015
|
-
"@subwallet/extension-inject": "^1.3.
|
|
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.
|
|
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.
|
|
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.
|
|
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;
|