@subwallet/extension-base 1.3.73-0 → 1.3.74-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) 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 -144
  6. package/cjs/koni/background/handlers/State.js +5 -2
  7. package/cjs/koni/background/handlers/Tabs.js +3 -2
  8. package/cjs/packageInfo.js +1 -1
  9. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +0 -2
  10. package/cjs/services/chain-service/handler/SubstrateApi.js +6 -1
  11. package/cjs/services/chain-service/index.js +1 -0
  12. package/cjs/services/chain-service/utils/index.js +4 -0
  13. package/cjs/services/event-service/index.js +1 -0
  14. package/cjs/services/fee-service/utils/index.js +4 -4
  15. package/cjs/services/inapp-notification-service/consts.js +4 -2
  16. package/cjs/services/inapp-notification-service/index.js +51 -6
  17. package/cjs/services/inapp-notification-service/interfaces.js +2 -0
  18. package/cjs/services/inapp-notification-service/utils/common.js +4 -0
  19. package/cjs/services/keyring-service/context/account-context.js +44 -0
  20. package/cjs/services/keyring-service/context/handlers/Multisig.js +186 -0
  21. package/cjs/services/keyring-service/context/state.js +12 -0
  22. package/cjs/services/multisig-service/index.js +627 -0
  23. package/cjs/services/multisig-service/utils.js +242 -0
  24. package/cjs/services/request-service/handler/SubstrateRequestHandler.js +25 -0
  25. package/cjs/services/request-service/index.js +5 -1
  26. package/cjs/services/storage-service/DatabaseService.js +5 -2
  27. package/cjs/services/storage-service/db-stores/InappNotification.js +20 -2
  28. package/cjs/services/substrate-proxy-service/index.js +22 -7
  29. package/cjs/services/transaction-service/helpers/index.js +8 -0
  30. package/cjs/services/transaction-service/index.js +348 -147
  31. package/cjs/services/transaction-service/types.js +18 -1
  32. package/cjs/types/account/info/keyring.js +5 -0
  33. package/cjs/types/account/info/proxy.js +1 -0
  34. package/cjs/types/multisig/index.js +14 -0
  35. package/cjs/types/transaction/error.js +9 -2
  36. package/cjs/utils/account/transform.js +28 -4
  37. package/cjs/utils/logger/Logger.js +294 -0
  38. package/cjs/utils/logger/index.js +42 -0
  39. package/cjs/utils/logger/types.js +1 -0
  40. package/core/logic-validation/transfer.d.ts +2 -2
  41. package/core/logic-validation/transfer.js +10 -32
  42. package/koni/background/handlers/Extension.d.ts +7 -0
  43. package/koni/background/handlers/Extension.js +498 -43
  44. package/koni/background/handlers/State.d.ts +2 -0
  45. package/koni/background/handlers/State.js +5 -2
  46. package/koni/background/handlers/Tabs.js +3 -2
  47. package/package.json +42 -6
  48. package/packageInfo.js +1 -1
  49. package/services/balance-service/helpers/subscribe/substrate/index.js +0 -2
  50. package/services/chain-service/handler/SubstrateApi.js +7 -2
  51. package/services/chain-service/index.js +1 -0
  52. package/services/chain-service/types.d.ts +1 -1
  53. package/services/chain-service/utils/index.js +4 -0
  54. package/services/event-service/index.d.ts +1 -0
  55. package/services/event-service/index.js +1 -0
  56. package/services/event-service/types.d.ts +1 -0
  57. package/services/fee-service/utils/index.js +4 -4
  58. package/services/inapp-notification-service/consts.d.ts +3 -1
  59. package/services/inapp-notification-service/consts.js +5 -3
  60. package/services/inapp-notification-service/index.d.ts +3 -2
  61. package/services/inapp-notification-service/index.js +51 -6
  62. package/services/inapp-notification-service/interfaces.d.ts +18 -2
  63. package/services/inapp-notification-service/interfaces.js +2 -0
  64. package/services/inapp-notification-service/utils/common.d.ts +1 -0
  65. package/services/inapp-notification-service/utils/common.js +3 -0
  66. package/services/keyring-service/context/account-context.d.ts +9 -1
  67. package/services/keyring-service/context/account-context.js +44 -0
  68. package/services/keyring-service/context/handlers/Multisig.d.ts +18 -0
  69. package/services/keyring-service/context/handlers/Multisig.js +180 -0
  70. package/services/keyring-service/context/state.d.ts +2 -0
  71. package/services/keyring-service/context/state.js +12 -0
  72. package/services/multisig-service/index.d.ts +245 -0
  73. package/services/multisig-service/index.js +620 -0
  74. package/services/multisig-service/utils.d.ts +95 -0
  75. package/services/multisig-service/utils.js +227 -0
  76. package/services/request-service/handler/SubstrateRequestHandler.d.ts +1 -0
  77. package/services/request-service/handler/SubstrateRequestHandler.js +25 -0
  78. package/services/request-service/index.d.ts +2 -1
  79. package/services/request-service/index.js +5 -1
  80. package/services/storage-service/DatabaseService.d.ts +3 -2
  81. package/services/storage-service/DatabaseService.js +5 -2
  82. package/services/storage-service/db-stores/InappNotification.d.ts +3 -2
  83. package/services/storage-service/db-stores/InappNotification.js +20 -2
  84. package/services/substrate-proxy-service/index.d.ts +4 -1
  85. package/services/substrate-proxy-service/index.js +22 -8
  86. package/services/transaction-service/helpers/index.js +8 -0
  87. package/services/transaction-service/index.d.ts +31 -0
  88. package/services/transaction-service/index.js +270 -69
  89. package/services/transaction-service/types.d.ts +28 -3
  90. package/services/transaction-service/types.js +12 -1
  91. package/types/account/info/keyring.d.ts +14 -1
  92. package/types/account/info/keyring.js +6 -0
  93. package/types/account/info/proxy.d.ts +1 -0
  94. package/types/account/info/proxy.js +1 -0
  95. package/types/multisig/index.d.ts +76 -0
  96. package/types/multisig/index.js +8 -0
  97. package/types/notification/index.d.ts +8 -0
  98. package/types/substrateProxyAccount/index.d.ts +26 -1
  99. package/types/transaction/error.d.ts +6 -1
  100. package/types/transaction/error.js +7 -1
  101. package/types/transaction/request.d.ts +0 -1
  102. package/utils/account/transform.js +28 -4
  103. package/utils/logger/Logger.d.ts +31 -0
  104. package/utils/logger/Logger.js +267 -0
  105. package/utils/logger/index.d.ts +15 -0
  106. package/utils/logger/index.js +29 -0
  107. package/utils/logger/types.d.ts +23 -0
  108. package/utils/logger/types.js +1 -0
@@ -0,0 +1,95 @@
1
+ import { MultisigTxType } from '@subwallet/extension-base/services/multisig-service/index';
2
+ import { ApiPromise } from '@polkadot/api';
3
+ import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
4
+ import { Block } from '@polkadot/types/interfaces';
5
+ import { AnyJson } from '@polkadot/types/types';
6
+ import { HexString } from '@polkadot/util/types';
7
+ export declare const DEFAULT_BLOCK_HASH = "0x0000000000000000000000000000000000000000000000000000000000000000";
8
+ export declare const DEFAULT_MAX_WEIGHT: {
9
+ refTime: string;
10
+ proofSize: string;
11
+ };
12
+ /**
13
+ * Request interface for getting call data from a block
14
+ */
15
+ interface GetCallDataRequest {
16
+ /** Hash of the call data */
17
+ callHash: HexString;
18
+ /** Index of the extrinsic in the block */
19
+ extrinsicIndex: number;
20
+ /** Block containing the extrinsic */
21
+ block: Block;
22
+ }
23
+ /**
24
+ * Request interface for decoding call data
25
+ */
26
+ interface DecodeCallDataRequest {
27
+ /** Sub API instance */
28
+ api: ApiPromise;
29
+ /** Optional encoded call data to decode */
30
+ callData?: HexString;
31
+ }
32
+ /**
33
+ * Response interface for decoded call data
34
+ */
35
+ export interface DecodeCallDataResponse {
36
+ /** Method name of the call */
37
+ method: string;
38
+ /** Section/pallet name of the call */
39
+ section: string;
40
+ /** Decoded arguments of the call */
41
+ args: AnyJson;
42
+ }
43
+ /**
44
+ * Extracts call data from a block's extrinsic
45
+ * Finds the inner call within multisig extrinsic and verifies it matches the call hash
46
+ * @param block - Block containing the extrinsic
47
+ * @param callHash - Expected hash of the call data
48
+ * @param extrinsicIndex - Index of the extrinsic in the block
49
+ * @returns Hex-encoded call data if found and verified, undefined otherwise
50
+ */
51
+ export declare function getCallData({ block, callHash, extrinsicIndex }: GetCallDataRequest): HexString | undefined;
52
+ /**
53
+ * Decodes call data into a human-readable format
54
+ * @param api - Polkadot API instance
55
+ * @param callData - Hex-encoded call data to decode
56
+ * @returns Decoded call data with method, section, and args, or undefined if callData is not provided
57
+ */
58
+ export declare function decodeCallData({ api, callData }: DecodeCallDataRequest): DecodeCallDataResponse | undefined;
59
+ /**
60
+ * Determines the type of multisig extrinsic based on decoded call data
61
+ * Maps pallet methods to extrinsic types (Transfer, Staking, Lending, etc.)
62
+ * @param decodedCallData - Decoded call data containing section and method
63
+ * @returns The type of multisig extrinsic, or UNKNOWN if not recognized
64
+ */
65
+ export declare function getMultisigTxType(decodedCallData: DecodeCallDataResponse | undefined): MultisigTxType;
66
+ /**
67
+ * Generates a unique key for a pending multisig extrinsic
68
+ * Used as the key in the PendingMultisigTxMap
69
+ * @param chain - Chain identifier
70
+ * @param multisigAddress - Multisig address
71
+ * @param signerAddress - Address of the signer
72
+ * @param extrinsicHash - Hash of the extrinsic
73
+ * @returns Unique key string for the extrinsic
74
+ */
75
+ export declare function genPendingMultisigTxKey(chain: string, multisigAddress: string, signerAddress: string, extrinsicHash: string): string;
76
+ /**
77
+ * Calculate deposit amount: depositAmount = depositBase + threshold * depositFactor
78
+ * In case threshold equal to 1, return undefined
79
+ * @param depositBase - Base deposit amount as a string
80
+ * @param threshold - Multisig threshold
81
+ * @param depositFactor - Deposit factor per additional signer as a string
82
+ * @returns Calculated deposit amount as a string
83
+ */
84
+ export declare function calcDepositAmount(depositBase: string, threshold: number, depositFactor: string): string;
85
+ /**
86
+ * Creates an init multisig extrinsic using the asMulti method
87
+ * @param api - Polkadot API instance
88
+ * @param threshold - Multisig threshold
89
+ * @param signers - Array of signer addresses
90
+ * @param signer - Address of the current signer
91
+ * @param extrinsic - Original extrinsic to be wrapped in multisig
92
+ * @returns SubmittableExtrinsic representing the multisig transaction
93
+ */
94
+ export declare function createInitMultisigExtrinsic(api: ApiPromise, threshold: number, signers: string[], signer: string, extrinsic: SubmittableExtrinsic): SubmittableExtrinsic;
95
+ export {};
@@ -0,0 +1,227 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { MULTISIG_TX_TYPE_MAP, MultisigTxType } from '@subwallet/extension-base/services/multisig-service/index';
5
+ import { isSameAddress } from '@subwallet/extension-base/utils';
6
+ import { blake2AsHex, sortAddresses } from '@polkadot/util-crypto';
7
+ export const DEFAULT_BLOCK_HASH = '0x0000000000000000000000000000000000000000000000000000000000000000';
8
+ export const DEFAULT_MAX_WEIGHT = {
9
+ refTime: '0',
10
+ proofSize: '0'
11
+ };
12
+
13
+ /**
14
+ * Request interface for getting call data from a block
15
+ */
16
+
17
+ /**
18
+ * Request interface for decoding call data
19
+ */
20
+
21
+ /**
22
+ * Response interface for decoded call data
23
+ */
24
+
25
+ /**
26
+ * Extracts call data from a block's extrinsic
27
+ * Finds the inner call within multisig extrinsic and verifies it matches the call hash
28
+ * @param block - Block containing the extrinsic
29
+ * @param callHash - Expected hash of the call data
30
+ * @param extrinsicIndex - Index of the extrinsic in the block
31
+ * @returns Hex-encoded call data if found and verified, undefined otherwise
32
+ */
33
+ export function getCallData({
34
+ block,
35
+ callHash,
36
+ extrinsicIndex
37
+ }) {
38
+ const extrinsic = block.extrinsics[extrinsicIndex];
39
+ if (!extrinsic) {
40
+ return undefined;
41
+ }
42
+ const innerCall = findInnerExtrinsicCall(extrinsic);
43
+ if (!innerCall) {
44
+ return undefined;
45
+ }
46
+ const callData = innerCall === null || innerCall === void 0 ? void 0 : innerCall.toHex();
47
+ if (!callData || !(blake2AsHex(callData) === callHash)) {
48
+ return undefined;
49
+ }
50
+ return callData;
51
+ }
52
+
53
+ /**
54
+ * Type guard to check if a codec is a Call type
55
+ * @param codec - Codec object to check
56
+ * @returns True if the codec is a Call, false otherwise
57
+ */
58
+ function isCall(codec) {
59
+ return 'args' in codec && 'method' in codec && 'section' in codec;
60
+ }
61
+
62
+ /**
63
+ * Finds the inner call within a multisig extrinsic
64
+ * Handles nested calls in multisig.asMulti and batchAll operations
65
+ * @param extrinsic - Extrinsic to search for inner call
66
+ * @returns The inner Call if found, null otherwise
67
+ */
68
+ function findInnerExtrinsicCall(extrinsic) {
69
+ const findAsMulti = method => {
70
+ const MULTISIG_EXTRINSIC_CALL_INDEX = 3;
71
+ const WRAP_EXTRINSIC_CALL_INDEX = 2;
72
+ if (!method) {
73
+ return null;
74
+ }
75
+ const {
76
+ method: callMethod,
77
+ section
78
+ } = method.toHuman();
79
+ if (callMethod === 'asMulti' && section === 'multisig') {
80
+ const arg = method.args[MULTISIG_EXTRINSIC_CALL_INDEX];
81
+ return isCall(arg) ? arg : null;
82
+ }
83
+ if (callMethod === 'batchAll' && method.args.length > 0) {
84
+ const firstArg = method.args[0];
85
+ for (const item of firstArg) {
86
+ if (isCall(item)) {
87
+ const result = findAsMulti(item);
88
+ if (result) {
89
+ return result;
90
+ }
91
+ }
92
+ }
93
+ }
94
+ if (method.args && method.args.length > WRAP_EXTRINSIC_CALL_INDEX) {
95
+ const wrappedArg = method.args[WRAP_EXTRINSIC_CALL_INDEX];
96
+ if (isCall(wrappedArg)) {
97
+ return findAsMulti(wrappedArg);
98
+ }
99
+ }
100
+ return null;
101
+ };
102
+ return findAsMulti(extrinsic.method);
103
+ }
104
+
105
+ /**
106
+ * Decodes call data into a human-readable format
107
+ * @param api - Polkadot API instance
108
+ * @param callData - Hex-encoded call data to decode
109
+ * @returns Decoded call data with method, section, and args, or undefined if callData is not provided
110
+ */
111
+ export function decodeCallData({
112
+ api,
113
+ callData
114
+ }) {
115
+ if (callData) {
116
+ return api.createType('Call', callData).toHuman();
117
+ }
118
+ return undefined;
119
+ }
120
+
121
+ /**
122
+ * Determines the type of multisig extrinsic based on decoded call data
123
+ * Maps pallet methods to extrinsic types (Transfer, Staking, Lending, etc.)
124
+ * @param decodedCallData - Decoded call data containing section and method
125
+ * @returns The type of multisig extrinsic, or UNKNOWN if not recognized
126
+ */
127
+ export function getMultisigTxType(decodedCallData) {
128
+ if (!decodedCallData) {
129
+ return MultisigTxType.UNKNOWN;
130
+ }
131
+ const sectionMethod = `${decodedCallData.section}.${decodedCallData.method}`;
132
+ if (MULTISIG_TX_TYPE_MAP.transfer.includes(sectionMethod)) {
133
+ return MultisigTxType.TRANSFER;
134
+ }
135
+ if (MULTISIG_TX_TYPE_MAP.transfer_nft.includes(sectionMethod)) {
136
+ return MultisigTxType.TRANSFER_NFT;
137
+ }
138
+ if (MULTISIG_TX_TYPE_MAP.staking.includes(sectionMethod)) {
139
+ return MultisigTxType.STAKING;
140
+ }
141
+ if (MULTISIG_TX_TYPE_MAP.redeem.includes(sectionMethod)) {
142
+ return MultisigTxType.REDEEM;
143
+ }
144
+ if (MULTISIG_TX_TYPE_MAP.unstake.includes(sectionMethod)) {
145
+ return MultisigTxType.UNSTAKE;
146
+ }
147
+ if (MULTISIG_TX_TYPE_MAP.withdraw.includes(sectionMethod)) {
148
+ return MultisigTxType.WITHDRAW;
149
+ }
150
+ if (MULTISIG_TX_TYPE_MAP.cancelUnstake.includes(sectionMethod)) {
151
+ return MultisigTxType.CANCEL_UNSTAKE;
152
+ }
153
+ if (MULTISIG_TX_TYPE_MAP.claim.includes(sectionMethod)) {
154
+ return MultisigTxType.CLAIM_REWARD;
155
+ }
156
+ if (MULTISIG_TX_TYPE_MAP.nominate.includes(sectionMethod)) {
157
+ return MultisigTxType.NOMINATE;
158
+ }
159
+ if (MULTISIG_TX_TYPE_MAP.lending.includes(sectionMethod)) {
160
+ return MultisigTxType.LENDING;
161
+ }
162
+ if (MULTISIG_TX_TYPE_MAP.govVote.includes(sectionMethod)) {
163
+ return MultisigTxType.GOV_VOTE;
164
+ }
165
+ if (MULTISIG_TX_TYPE_MAP.govUnlockVote.includes(sectionMethod)) {
166
+ return MultisigTxType.GOV_UNLOCK_VOTE;
167
+ }
168
+ if (MULTISIG_TX_TYPE_MAP.govRemoveVote.includes(sectionMethod)) {
169
+ return MultisigTxType.GOV_REMOVE_VOTE;
170
+ }
171
+ if (MULTISIG_TX_TYPE_MAP.swap.includes(sectionMethod)) {
172
+ return MultisigTxType.SWAP;
173
+ }
174
+ if (MULTISIG_TX_TYPE_MAP.setTokenPayFee.includes(sectionMethod)) {
175
+ return MultisigTxType.SET_TOKEN_PAY_FEE;
176
+ }
177
+ if (MULTISIG_TX_TYPE_MAP.addProxy.includes(sectionMethod)) {
178
+ return MultisigTxType.ADD_PROXY;
179
+ }
180
+ if (MULTISIG_TX_TYPE_MAP.removeProxy.includes(sectionMethod)) {
181
+ return MultisigTxType.REMOVE_PROXY;
182
+ }
183
+ return MultisigTxType.UNKNOWN;
184
+ }
185
+
186
+ /**
187
+ * Generates a unique key for a pending multisig extrinsic
188
+ * Used as the key in the PendingMultisigTxMap
189
+ * @param chain - Chain identifier
190
+ * @param multisigAddress - Multisig address
191
+ * @param signerAddress - Address of the signer
192
+ * @param extrinsicHash - Hash of the extrinsic
193
+ * @returns Unique key string for the extrinsic
194
+ */
195
+ export function genPendingMultisigTxKey(chain, multisigAddress, signerAddress, extrinsicHash) {
196
+ return `${chain}___${multisigAddress}___${signerAddress}______${extrinsicHash}`;
197
+ }
198
+
199
+ /**
200
+ * Calculate deposit amount: depositAmount = depositBase + threshold * depositFactor
201
+ * In case threshold equal to 1, return undefined
202
+ * @param depositBase - Base deposit amount as a string
203
+ * @param threshold - Multisig threshold
204
+ * @param depositFactor - Deposit factor per additional signer as a string
205
+ * @returns Calculated deposit amount as a string
206
+ */
207
+ export function calcDepositAmount(depositBase, threshold, depositFactor) {
208
+ if (threshold === 1) {
209
+ return '0';
210
+ }
211
+ return (BigInt(depositBase) + BigInt(threshold) * BigInt(depositFactor)).toString();
212
+ }
213
+
214
+ /**
215
+ * Creates an init multisig extrinsic using the asMulti method
216
+ * @param api - Polkadot API instance
217
+ * @param threshold - Multisig threshold
218
+ * @param signers - Array of signer addresses
219
+ * @param signer - Address of the current signer
220
+ * @param extrinsic - Original extrinsic to be wrapped in multisig
221
+ * @returns SubmittableExtrinsic representing the multisig transaction
222
+ */
223
+ export function createInitMultisigExtrinsic(api, threshold, signers, signer, extrinsic) {
224
+ const otherSignatories = signers.filter(s => !isSameAddress(s, signer));
225
+ return api.tx.multisig.asMulti(threshold, sortAddresses(otherSignatories), null, extrinsic, DEFAULT_MAX_WEIGHT // default max weight for init multisig tx
226
+ );
227
+ }
@@ -14,5 +14,6 @@ export default class SubstrateRequestHandler {
14
14
  get numSubstrateRequests(): number;
15
15
  sign(url: string, request: RequestSign, _id?: string): Promise<ResponseSigning>;
16
16
  signTransaction(id: string, address: string, url: string, payload: SignerPayloadJSON, onSign?: (id: string) => void): Promise<ResponseSigning>;
17
+ signWrappedTransaction(id: string, address: string, url: string, payload: SignerPayloadJSON, onSign?: (id: string) => void): Promise<ResponseSigning>;
17
18
  resetWallet(): void;
18
19
  }
@@ -1,7 +1,9 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
4
5
  import RequestExtrinsicSign from '@subwallet/extension-base/background/RequestExtrinsicSign';
6
+ import { BasicTxErrorType } from '@subwallet/extension-base/types';
5
7
  import { getId } from '@subwallet/extension-base/utils/getId';
6
8
  import { isInternalRequest } from '@subwallet/extension-base/utils/request';
7
9
  import { BehaviorSubject } from 'rxjs';
@@ -94,6 +96,29 @@ export default class SubstrateRequestHandler {
94
96
  onSign === null || onSign === void 0 ? void 0 : onSign(id);
95
97
  });
96
98
  }
99
+
100
+ // used for wrapped tx where we don't want to show popup for internal requests
101
+ // transaction is multisig or proxy transaction
102
+ async signWrappedTransaction(id, address, url, payload, onSign) {
103
+ const isAlwaysRequired = await this.#requestService.settingService.isAlwaysRequired;
104
+ if (isAlwaysRequired && !onSign) {
105
+ this.#requestService.keyringService.lock();
106
+ }
107
+ if (!this.#substrateRequests[id]) {
108
+ return Promise.reject(new TransactionError(BasicTxErrorType.USER_REJECT_REQUEST));
109
+ }
110
+ return new Promise((resolve, reject) => {
111
+ this.#substrateRequests[id] = {
112
+ ...this.signComplete(id, resolve, reject),
113
+ address,
114
+ id,
115
+ request: new RequestExtrinsicSign(payload),
116
+ url: url
117
+ };
118
+ this.signSubject.next(this.allSubstrateRequests);
119
+ onSign === null || onSign === void 0 ? void 0 : onSign(id);
120
+ });
121
+ }
97
122
  resetWallet() {
98
123
  for (const request of Object.values(this.#substrateRequests)) {
99
124
  request.reject(new Error('Reset wallet'));
@@ -4,6 +4,7 @@ import { ChainService } from '@subwallet/extension-base/services/chain-service';
4
4
  import { KeyringService } from '@subwallet/extension-base/services/keyring-service';
5
5
  import SettingService from '@subwallet/extension-base/services/setting-service/SettingService';
6
6
  import TransactionService from '@subwallet/extension-base/services/transaction-service';
7
+ import { SubstrateTransactionWrappingStatus } from '@subwallet/extension-base/services/transaction-service/types';
7
8
  import { WalletConnectNotSupportRequest, WalletConnectSessionRequest } from '@subwallet/extension-base/services/wallet-connect-service/types';
8
9
  import { MetadataDef } from '@subwallet/extension-inject/types';
9
10
  import { BehaviorSubject } from 'rxjs';
@@ -54,7 +55,7 @@ export default class RequestService {
54
55
  get confirmationsQueueSubjectTon(): BehaviorSubject<ConfirmationsQueueTon>;
55
56
  get confirmationsQueueSubjectCardano(): BehaviorSubject<ConfirmationsQueueCardano>;
56
57
  getSignRequest(id: string): import("./types").SignRequest | undefined;
57
- signInternalTransaction(id: string, address: string, url: string, payload: SignerPayloadJSON, onSign?: (id: string) => void): Promise<ResponseSigning>;
58
+ signInternalTransaction(id: string, address: string, url: string, payload: SignerPayloadJSON, onSign?: (id: string) => void, isWrappedTx?: SubstrateTransactionWrappingStatus): Promise<ResponseSigning>;
58
59
  addConfirmation<CT extends ConfirmationType>(id: string, url: string, type: CT, payload: ConfirmationDefinitions[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitions[CT][1]) => Error | undefined): Promise<ConfirmationDefinitions[CT][1]>;
59
60
  addConfirmationTon<CT extends ConfirmationTypeTon>(id: string, url: string, type: CT, payload: ConfirmationDefinitionsTon[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitionsTon[CT][1]) => Error | undefined): Promise<ConfirmationDefinitionsTon[CT][1]>;
60
61
  addConfirmationCardano<CT extends ConfirmationTypeCardano>(id: string, url: string, type: CT, payload: ConfirmationDefinitionsCardano[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitionsCardano[CT][1]) => Error | undefined): Promise<ConfirmationDefinitionsCardano[CT][1]>;
@@ -3,6 +3,7 @@
3
3
 
4
4
  import BitcoinRequestHandler from '@subwallet/extension-base/services/request-service/handler/BitcoinRequestHandler';
5
5
  import CardanoRequestHandler from '@subwallet/extension-base/services/request-service/handler/CardanoRequestHandler';
6
+ import { SubstrateTransactionWrappingStatus } from '@subwallet/extension-base/services/transaction-service/types';
6
7
  import TonRequestHandler from "./handler/TonRequestHandler.js";
7
8
  import { AuthRequestHandler, ConnectWCRequestHandler, EvmRequestHandler, MetadataRequestHandler, NotSupportWCRequestHandler, PopupHandler, SubstrateRequestHandler } from "./handler/index.js";
8
9
  export default class RequestService {
@@ -166,7 +167,10 @@ export default class RequestService {
166
167
  getSignRequest(id) {
167
168
  return this.#substrateRequestHandler.getSignRequest(id);
168
169
  }
169
- async signInternalTransaction(id, address, url, payload, onSign) {
170
+ async signInternalTransaction(id, address, url, payload, onSign, isWrappedTx) {
171
+ if (isWrappedTx === SubstrateTransactionWrappingStatus.WRAP_RESULT) {
172
+ return this.#substrateRequestHandler.signWrappedTransaction(id, address, url, payload, onSign);
173
+ }
170
174
  return this.#substrateRequestHandler.signTransaction(id, address, url, payload, onSign);
171
175
  }
172
176
  addConfirmation(id, url, type, payload, options = {}, validator) {
@@ -13,7 +13,7 @@ import { HistoryQuery } from '@subwallet/extension-base/services/storage-service
13
13
  import YieldPoolStore from '@subwallet/extension-base/services/storage-service/db-stores/YieldPoolStore';
14
14
  import YieldPositionStore from '@subwallet/extension-base/services/storage-service/db-stores/YieldPositionStore';
15
15
  import { BalanceItem, ProcessTransactionData, YieldPoolInfo, YieldPoolType, YieldPositionInfo } from '@subwallet/extension-base/types';
16
- import { GetNotificationParams, RequestSwitchStatusParams } from '@subwallet/extension-base/types/notification';
16
+ import { GetNotificationParams, MarkAllReadParams, RequestSwitchStatusParams } from '@subwallet/extension-base/types/notification';
17
17
  import { Subscription } from 'dexie';
18
18
  import { DexieExportJsonStructure } from 'dexie-export-import';
19
19
  import { GovVotingInfo } from '../open-gov/interface';
@@ -131,10 +131,11 @@ export default class DatabaseService {
131
131
  updateNotification(notification: _NotificationInfo): Promise<unknown>;
132
132
  getNotificationsByParams(params: GetNotificationParams): Promise<_NotificationInfo[]>;
133
133
  cleanUpOldNotifications(overdueTime: number): Promise<number>;
134
+ cleanUpNotificationByIds(ids: string[]): Promise<number>;
134
135
  subscribeUnreadNotificationsCountMap(): import("dexie").Observable<Record<string, number>>;
135
136
  getUnreadNotificationsCountMap(): Promise<Record<string, number>>;
136
137
  upsertNotifications(notifications: _NotificationInfo[]): Promise<unknown>;
137
- markAllRead(proxyId: string): import("dexie").PromiseExtended<number>;
138
+ markAllRead(params: MarkAllReadParams): import("dexie").PromiseExtended<number>;
138
139
  switchReadStatus(params: RequestSwitchStatusParams): import("dexie").PromiseExtended<number>;
139
140
  removeAccountNotifications(proxyId: string): import("dexie").PromiseExtended<number>;
140
141
  updateNotificationProxyId(proxyIds: string[], newProxyId: string, newName: string): void;
@@ -578,6 +578,9 @@ export default class DatabaseService {
578
578
  cleanUpOldNotifications(overdueTime) {
579
579
  return this.stores.inappNotification.cleanUpOldNotifications(overdueTime);
580
580
  }
581
+ cleanUpNotificationByIds(ids) {
582
+ return this.stores.inappNotification.cleanUpNotificationsByIds(ids);
583
+ }
581
584
  subscribeUnreadNotificationsCountMap() {
582
585
  return this.stores.inappNotification.subscribeUnreadNotificationsCount();
583
586
  }
@@ -587,8 +590,8 @@ export default class DatabaseService {
587
590
  upsertNotifications(notifications) {
588
591
  return this.stores.inappNotification.bulkUpsert(notifications);
589
592
  }
590
- markAllRead(proxyId) {
591
- return this.stores.inappNotification.markAllRead(proxyId);
593
+ markAllRead(params) {
594
+ return this.stores.inappNotification.markAllRead(params);
592
595
  }
593
596
  switchReadStatus(params) {
594
597
  return this.stores.inappNotification.switchReadStatus(params);
@@ -1,15 +1,16 @@
1
1
  import { _NotificationInfo } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
2
2
  import BaseStore from '@subwallet/extension-base/services/storage-service/db-stores/BaseStore';
3
- import { GetNotificationParams, RequestSwitchStatusParams } from '@subwallet/extension-base/types/notification';
3
+ import { GetNotificationParams, MarkAllReadParams, RequestSwitchStatusParams } from '@subwallet/extension-base/types/notification';
4
4
  export default class InappNotificationStore extends BaseStore<_NotificationInfo> {
5
5
  getNotificationInfo(id: string): Promise<_NotificationInfo | undefined>;
6
6
  getAll(): Promise<_NotificationInfo[]>;
7
7
  getNotificationsByParams(params: GetNotificationParams): Promise<_NotificationInfo[]>;
8
8
  updateNotificationProxyId(proxyIds: string[], newProxyId: string, newName: string): void;
9
9
  cleanUpOldNotifications(overdueTime: number): Promise<number>;
10
+ cleanUpNotificationsByIds(ids: string[]): Promise<number>;
10
11
  subscribeUnreadNotificationsCount(): import("dexie").Observable<Record<string, number>>;
11
12
  getUnreadNotificationsCountMap(): Promise<Record<string, number>>;
12
- markAllRead(proxyId: string): import("dexie").PromiseExtended<number>;
13
+ markAllRead(params: MarkAllReadParams): import("dexie").PromiseExtended<number>;
13
14
  switchReadStatus(params: RequestSwitchStatusParams): import("dexie").PromiseExtended<number>;
14
15
  removeAccountNotifications(proxyId: string): import("dexie").PromiseExtended<number>;
15
16
  }
@@ -5,6 +5,7 @@ import { ALL_ACCOUNT_KEY } from '@subwallet/extension-base/constants';
5
5
  import { NotificationTab } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
6
6
  import { getIsTabRead } from '@subwallet/extension-base/services/inapp-notification-service/utils';
7
7
  import BaseStore from '@subwallet/extension-base/services/storage-service/db-stores/BaseStore';
8
+ import { isSameAddress } from '@subwallet/extension-base/utils';
8
9
  import { liveQuery } from 'dexie';
9
10
  export default class InappNotificationStore extends BaseStore {
10
11
  async getNotificationInfo(id) {
@@ -15,6 +16,7 @@ export default class InappNotificationStore extends BaseStore {
15
16
  }
16
17
  async getNotificationsByParams(params) {
17
18
  const {
19
+ metadata,
18
20
  notificationTab,
19
21
  proxyId
20
22
  } = params;
@@ -26,6 +28,15 @@ export default class InappNotificationStore extends BaseStore {
26
28
  const filteredTable = this.table.filter(item => {
27
29
  const matchesProxyId = item.proxyId === proxyId;
28
30
  const matchesReadStatus = item.isRead === getIsTabRead(notificationTab);
31
+ if (metadata !== null && metadata !== void 0 && metadata.multisigAddress && metadata !== null && metadata !== void 0 && metadata.chain && notificationTab === NotificationTab.MULTISIG) {
32
+ // @Todo This condition is service only for multisig subscribe service to get all filter by multisig address
33
+ // then clear it when tx is completed
34
+ // So, if use this condition to service other feature, need to re-check carefully
35
+ const multisigMetadata = item.metadata;
36
+ const multisigAddressOfNotification = multisigMetadata === null || multisigMetadata === void 0 ? void 0 : multisigMetadata.multisigAddress;
37
+ const chain = multisigMetadata === null || multisigMetadata === void 0 ? void 0 : multisigMetadata.chain;
38
+ return !!multisigAddressOfNotification && isSameAddress(multisigAddressOfNotification, metadata.multisigAddress) && chain === metadata.chain;
39
+ }
29
40
  if (isTabAll) {
30
41
  return matchesProxyId;
31
42
  }
@@ -46,6 +57,9 @@ export default class InappNotificationStore extends BaseStore {
46
57
  const currentTimestamp = Date.now();
47
58
  return this.table.filter(item => item.time <= currentTimestamp - overdueTime).delete();
48
59
  }
60
+ async cleanUpNotificationsByIds(ids) {
61
+ return this.table.where('id').anyOf(ids).delete();
62
+ }
49
63
  subscribeUnreadNotificationsCount() {
50
64
  return liveQuery(async () => {
51
65
  return await this.getUnreadNotificationsCountMap();
@@ -58,9 +72,13 @@ export default class InappNotificationStore extends BaseStore {
58
72
  return countMap;
59
73
  }, {});
60
74
  }
61
- markAllRead(proxyId) {
75
+ markAllRead(params) {
76
+ const {
77
+ proxyId,
78
+ excludeNotificationIds = []
79
+ } = params;
62
80
  if (proxyId === ALL_ACCOUNT_KEY) {
63
- return this.table.toCollection().modify({
81
+ return this.table.toCollection().filter(notification => !excludeNotificationIds.includes(notification.id)).modify({
64
82
  isRead: true
65
83
  });
66
84
  }
@@ -2,12 +2,15 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
2
2
  import KoniState from '@subwallet/extension-base/koni/background/handlers/State';
3
3
  import { TransactionData } from '@subwallet/extension-base/types';
4
4
  import { AddSubstrateProxyAccountParams, RemoveSubstrateProxyAccountParams, RequestGetSubstrateProxyAccountGroup, SubstrateProxyAccountGroup } from '@subwallet/extension-base/types/substrateProxyAccount';
5
+ import { ApiPromise } from '@polkadot/api';
6
+ import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
7
+ export declare function createInitSubstrateProxyExtrinsic(api: ApiPromise, proxiedAddress: string, extrinsic: SubmittableExtrinsic): SubmittableExtrinsic;
5
8
  export default class SubstrateProxyAccountService {
6
9
  protected readonly state: KoniState;
7
10
  constructor(state: KoniState);
8
11
  private getSubstrateApi;
9
12
  getSubstrateProxyAccountGroup(request: RequestGetSubstrateProxyAccountGroup): Promise<SubstrateProxyAccountGroup>;
10
13
  addSubstrateProxyAccounts(data: AddSubstrateProxyAccountParams): Promise<TransactionData>;
11
- validateAddSubstrateProxyAccount(params: AddSubstrateProxyAccountParams, signerSubstrateProxyAddress?: string): Promise<TransactionError[]>;
14
+ validateAddSubstrateProxyAccount(params: AddSubstrateProxyAccountParams): Promise<TransactionError[]>;
12
15
  removeSubstrateProxyAccounts(data: RemoveSubstrateProxyAccountParams): Promise<TransactionData>;
13
16
  }
@@ -2,10 +2,13 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
5
- import { BasicTxErrorType } from '@subwallet/extension-base/types';
5
+ import { AccountChainType, BasicTxErrorType } from '@subwallet/extension-base/types';
6
6
  import { reformatAddress } from '@subwallet/extension-base/utils';
7
7
  import BigN from 'bignumber.js';
8
8
  import { txTypeToSubstrateProxyMap } from "./constant.js";
9
+ export function createInitSubstrateProxyExtrinsic(api, proxiedAddress, extrinsic) {
10
+ return api.tx.proxy.proxy(proxiedAddress, null, extrinsic);
11
+ }
9
12
  export default class SubstrateProxyAccountService {
10
13
  constructor(state) {
11
14
  this.state = state;
@@ -32,6 +35,7 @@ export default class SubstrateProxyAccountService {
32
35
  const baseDeposit = ((_substrateApi$api$con = substrateApi.api.consts.proxy.proxyDepositBase) === null || _substrateApi$api$con === void 0 ? void 0 : _substrateApi$api$con.toString()) || '0';
33
36
  const factorDeposit = ((_substrateApi$api$con2 = substrateApi.api.consts.proxy.proxyDepositFactor) === null || _substrateApi$api$con2 === void 0 ? void 0 : _substrateApi$api$con2.toString()) || '0';
34
37
  const deposit = new BigN(baseDeposit).plus(factorDeposit);
38
+ const allAccounts = this.state.keyringService.context.accounts;
35
39
  const [_substrateProxyAccounts, currentSubstrateProxyDeposit] = result.toPrimitive();
36
40
 
37
41
  // Mapping on-chain data to our defined type
@@ -46,11 +50,21 @@ export default class SubstrateProxyAccountService {
46
50
  });
47
51
  if (type) {
48
52
  const allowedSet = new Set([...(txTypeToSubstrateProxyMap[type] || []), 'Any']);
49
- substrateProxyAccounts = substrateProxyAccounts.filter(p => allowedSet.has(p.substrateProxyType));
53
+ substrateProxyAccounts = substrateProxyAccounts.filter(p => {
54
+ if (!p.proxyId) {
55
+ return false;
56
+ }
57
+ const accountProxy = allAccounts[p.proxyId];
58
+ const substrateAccount = accountProxy === null || accountProxy === void 0 ? void 0 : accountProxy.accounts.find(acc => acc.chainType === AccountChainType.SUBSTRATE);
59
+ if (!substrateAccount || !substrateAccount.transactionActions.includes(type)) {
60
+ return false;
61
+ }
62
+ return allowedSet.has(p.substrateProxyType);
63
+ });
50
64
  }
51
65
  if (excludedSubstrateProxyAccounts && excludedSubstrateProxyAccounts.length > 0) {
52
66
  substrateProxyAccounts = substrateProxyAccounts.filter(p => {
53
- return !excludedSubstrateProxyAccounts.some(excluded => excluded.address === p.substrateProxyAddress && excluded.substrateProxyType === p.substrateProxyType);
67
+ return !excludedSubstrateProxyAccounts.some(excluded => excluded.substrateProxyAddress === p.substrateProxyAddress && excluded.substrateProxyType === p.substrateProxyType);
54
68
  });
55
69
  }
56
70
  const estimateSubstrateProxyDeposit = new BigN(currentSubstrateProxyDeposit).plus(factorDeposit);
@@ -79,7 +93,7 @@ export default class SubstrateProxyAccountService {
79
93
  }
80
94
 
81
95
  // Validate adding proxy account
82
- async validateAddSubstrateProxyAccount(params, signerSubstrateProxyAddress) {
96
+ async validateAddSubstrateProxyAccount(params) {
83
97
  var _substrateApi$api$con3, _substrateApi$api$con4, _substrateApi$api$con5, _substrateApi$api$con6;
84
98
  const {
85
99
  address,
@@ -88,6 +102,9 @@ export default class SubstrateProxyAccountService {
88
102
  } = params;
89
103
  const substrateApi = this.getSubstrateApi(chain);
90
104
  await substrateApi.isReady;
105
+ if (!substrateApi.api.tx.proxy || !substrateApi.api.tx.proxy.addProxy) {
106
+ return [new TransactionError(BasicTxErrorType.UNSUPPORTED)];
107
+ }
91
108
  const addProxyTx = substrateApi.api.tx.proxy.addProxy;
92
109
  const proxyTypeArg = addProxyTx.meta.args.find(arg => arg.name.toString() === 'proxyType');
93
110
  if (proxyTypeArg) {
@@ -98,9 +115,6 @@ export default class SubstrateProxyAccountService {
98
115
  return [new TransactionError(BasicTxErrorType.UNSUPPORTED, 'This proxy type is not supported on the chosen network. Select another one and try again')];
99
116
  }
100
117
  }
101
- if (!substrateApi.api.tx.proxy || !substrateApi.api.tx.proxy.addProxy) {
102
- return [new TransactionError(BasicTxErrorType.UNSUPPORTED)];
103
- }
104
118
 
105
119
  // Validate max proxies accounts limit
106
120
  const maxSubstrateProxies = ((_substrateApi$api$con3 = substrateApi.api.consts.proxy.maxProxies) === null || _substrateApi$api$con3 === void 0 ? void 0 : (_substrateApi$api$con4 = _substrateApi$api$con3.toNumber) === null || _substrateApi$api$con4 === void 0 ? void 0 : _substrateApi$api$con4.call(_substrateApi$api$con3)) || 0;
@@ -118,7 +132,7 @@ export default class SubstrateProxyAccountService {
118
132
  const baseDeposit = ((_substrateApi$api$con5 = substrateApi.api.consts.proxy.proxyDepositBase) === null || _substrateApi$api$con5 === void 0 ? void 0 : _substrateApi$api$con5.toString()) || '0';
119
133
  const factorDeposit = ((_substrateApi$api$con6 = substrateApi.api.consts.proxy.proxyDepositFactor) === null || _substrateApi$api$con6 === void 0 ? void 0 : _substrateApi$api$con6.toString()) || '0';
120
134
  const requiredDeposit = proxyList.length === 0 ? new BigN(baseDeposit).plus(factorDeposit) : new BigN(factorDeposit);
121
- const totalRequired = new BigN(requiredDeposit).plus(!signerSubstrateProxyAddress ? estimatedFee : 0);
135
+ const totalRequired = new BigN(requiredDeposit).plus(estimatedFee);
122
136
  if (bnTransferableBalance.lt(totalRequired)) {
123
137
  return [new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE)];
124
138
  }
@@ -69,6 +69,14 @@ const typeName = type => {
69
69
  return 'Unlock votes';
70
70
  case ExtrinsicType.CHANGE_EARNING_VALIDATOR:
71
71
  return 'Change validator';
72
+ case ExtrinsicType.MULTISIG_APPROVE_TX:
73
+ return 'Approve multisig extrinsic';
74
+ case ExtrinsicType.MULTISIG_EXECUTE_TX:
75
+ return 'Execute multisig extrinsic';
76
+ case ExtrinsicType.MULTISIG_CANCEL_TX:
77
+ return 'Cancel multisig extrinsic';
78
+ case ExtrinsicType.MULTISIG_INIT_TX:
79
+ return 'Initiate multisig extrinsic';
72
80
  case ExtrinsicType.UNKNOWN:
73
81
  default:
74
82
  return 'unknown';