@subwallet/extension-base 1.3.37-0 → 1.3.39-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 (32) hide show
  1. package/background/KoniTypes.d.ts +2 -0
  2. package/cjs/core/logic-validation/request.js +49 -12
  3. package/cjs/koni/background/handlers/State.js +4 -8
  4. package/cjs/koni/background/handlers/Tabs.js +38 -5
  5. package/cjs/packageInfo.js +1 -1
  6. package/cjs/page/cardano/cips/cip30.js +21 -1
  7. package/cjs/page/cardano/index.js +5 -5
  8. package/cjs/services/request-service/handler/AuthRequestHandler.js +2 -0
  9. package/cjs/services/request-service/handler/CardanoRequestHandler.js +4 -3
  10. package/cjs/services/request-service/helper/index.js +19 -17
  11. package/cjs/services/swap-service/handler/base-handler.js +4 -2
  12. package/cjs/services/swap-service/handler/uniswap-handler.js +122 -57
  13. package/cjs/services/swap-service/index.js +1 -1
  14. package/core/logic-validation/request.d.ts +1 -0
  15. package/core/logic-validation/request.js +50 -14
  16. package/koni/background/handlers/State.js +5 -9
  17. package/koni/background/handlers/Tabs.d.ts +1 -0
  18. package/koni/background/handlers/Tabs.js +38 -5
  19. package/package.json +8 -8
  20. package/packageInfo.js +1 -1
  21. package/page/cardano/cips/cip30.d.ts +31 -17
  22. package/page/cardano/cips/cip30.js +17 -1
  23. package/page/cardano/index.d.ts +20 -4
  24. package/page/cardano/index.js +5 -5
  25. package/services/request-service/handler/AuthRequestHandler.js +2 -0
  26. package/services/request-service/handler/CardanoRequestHandler.js +4 -3
  27. package/services/request-service/helper/index.js +19 -17
  28. package/services/swap-service/handler/base-handler.js +4 -2
  29. package/services/swap-service/handler/uniswap-handler.d.ts +1 -1
  30. package/services/swap-service/handler/uniswap-handler.js +99 -34
  31. package/services/swap-service/index.js +1 -1
  32. package/types/service-base.d.ts +1 -0
@@ -11,12 +11,13 @@ var _logicValidation = require("@subwallet/extension-base/core/logic-validation"
11
11
  var _web = require("@subwallet/extension-base/koni/api/contract-handler/evm/web3");
12
12
  var _xcm = require("@subwallet/extension-base/services/balance-service/transfer/xcm");
13
13
  var _acrossBridge = require("@subwallet/extension-base/services/balance-service/transfer/xcm/acrossBridge");
14
+ var _utils = require("@subwallet/extension-base/services/swap-service/utils");
14
15
  var _types = require("@subwallet/extension-base/types");
15
- var _utils = require("@subwallet/extension-base/utils");
16
+ var _utils2 = require("@subwallet/extension-base/utils");
16
17
  var _getId = require("@subwallet/extension-base/utils/getId");
17
18
  var _bignumber = _interopRequireDefault(require("bignumber.js"));
18
- var _utils2 = require("../../chain-service/utils");
19
- var _utils3 = require("../../fee-service/utils");
19
+ var _utils3 = require("../../chain-service/utils");
20
+ var _utils4 = require("../../fee-service/utils");
20
21
  var _baseHandler = require("./base-handler");
21
22
  // Copyright 2019-2022 @subwallet/extension-base
22
23
  // SPDX-License-Identifier: Apache-2.0
@@ -101,7 +102,8 @@ class UniswapHandler {
101
102
  const stepFuncList = [];
102
103
  /**
103
104
  * approve - permit - swap or
104
- * approve - permit - swap - approve - bridge
105
+ * approve - permit - swap - approve - bridge or
106
+ * approve - bridge - approve - permit - swap
105
107
  */
106
108
 
107
109
  params.path.forEach(step => {
@@ -118,11 +120,26 @@ class UniswapHandler {
118
120
  return this.swapBaseHandler.generateOptimalProcessV2(params, stepFuncList);
119
121
  }
120
122
  async getApprovalStep(params, stepIndex) {
121
- if (stepIndex === 0) {
123
+ /**
124
+ * Explain: All processes will go through one of below processes. If a step do not have, it returns undefined and
125
+ * the stepIndex is still counted up
126
+ *
127
+ * Processes:
128
+ * approve - permit - swap or
129
+ * approve - permit - swap - approve - bridge or
130
+ * approve - bridge - approve - permit - swap
131
+ */
132
+ const actionList = JSON.stringify(params.path.map(step => step.action));
133
+ const swap = actionList === JSON.stringify([_types.DynamicSwapType.SWAP]);
134
+ const swapBridge = actionList === JSON.stringify([_types.DynamicSwapType.SWAP, _types.DynamicSwapType.BRIDGE]);
135
+ const bridgeSwap = actionList === JSON.stringify([_types.DynamicSwapType.BRIDGE, _types.DynamicSwapType.SWAP]);
136
+ const isApproveBridge = stepIndex === 3 && swapBridge || stepIndex === 0 && bridgeSwap;
137
+ const isApproveSwap = stepIndex === 0 && swap || stepIndex === 0 && swapBridge || stepIndex === 2 && bridgeSwap;
138
+ if (isApproveSwap) {
122
139
  return this.getApproveSwap(params);
123
140
  }
124
- if (stepIndex === 3) {
125
- return this.getApproveBridge(params);
141
+ if (isApproveBridge) {
142
+ return this.getApproveBridge(params, bridgeSwap);
126
143
  }
127
144
  return Promise.resolve(undefined);
128
145
  }
@@ -160,9 +177,9 @@ class UniswapHandler {
160
177
  return undefined;
161
178
  }
162
179
  const fromTokenInfo = this.chainService.getAssetBySlug(selectedQuote.pair.from);
163
- const fromChainInfo = this.chainService.getChainInfoByKey((0, _utils2._getAssetOriginChain)(fromTokenInfo));
180
+ const fromChainInfo = this.chainService.getChainInfoByKey((0, _utils3._getAssetOriginChain)(fromTokenInfo));
164
181
  const evmApi = this.chainService.getEvmApi(fromChainInfo.slug);
165
- const tokenContract = (0, _utils2._getContractAddressOfToken)(fromTokenInfo);
182
+ const tokenContract = (0, _utils3._getContractAddressOfToken)(fromTokenInfo);
166
183
  const approval = checkApprovalResponse.approval;
167
184
  if (!approval) {
168
185
  return Promise.resolve(undefined);
@@ -177,7 +194,7 @@ class UniswapHandler {
177
194
  const tx = await (0, _web.getERC20SpendingApprovalTx)(spender, sender, tokenContract, evmApi);
178
195
  const evmFeeInfo = await this.feeService.subscribeChainFee((0, _getId.getId)(), fromTokenInfo.originChain, 'evm');
179
196
  const estimatedFee = await (0, _web.estimateTxFee)(tx, evmApi, evmFeeInfo);
180
- const nativeTokenSlug = (0, _utils2._getChainNativeTokenSlug)(fromChainInfo);
197
+ const nativeTokenSlug = (0, _utils3._getChainNativeTokenSlug)(fromChainInfo);
181
198
  const feeInfo = {
182
199
  feeComponent: [{
183
200
  feeType: _types.SwapFeeType.NETWORK_FEE,
@@ -193,7 +210,7 @@ class UniswapHandler {
193
210
  // @ts-ignore
194
211
  metadata: {
195
212
  tokenApprove: fromTokenInfo.slug,
196
- contractAddress: (0, _utils2._getContractAddressOfToken)(fromTokenInfo) || approval.to,
213
+ contractAddress: (0, _utils3._getContractAddressOfToken)(fromTokenInfo) || approval.to,
197
214
  spenderAddress: spender,
198
215
  owner: sender,
199
216
  // todo: use approval.from?
@@ -203,22 +220,30 @@ class UniswapHandler {
203
220
  };
204
221
  return Promise.resolve([submitStep, feeInfo]);
205
222
  }
206
- async getApproveBridge(params) {
207
- const quote = params.selectedQuote;
208
- if (!quote) {
223
+ async getApproveBridge(params, isBridgeFirst) {
224
+ const {
225
+ path,
226
+ request,
227
+ selectedQuote
228
+ } = params;
229
+ if (!selectedQuote) {
209
230
  return Promise.resolve(undefined);
210
231
  }
211
- console.log('params', params);
212
- const sendingAmount = quote.toAmount;
213
- const senderAddress = params.request.address;
214
- const fromTokenInfo = this.chainService.getAssetBySlug(quote.pair.to);
215
- const fromChainInfo = this.chainService.getChainInfoByKey((0, _utils2._getAssetOriginChain)(fromTokenInfo));
216
- const fromChainId = (0, _utils2._getEvmChainId)(fromChainInfo);
232
+ const bridgePairInfo = path.find(action => action.action === _types.DynamicSwapType.BRIDGE);
233
+ if (!bridgePairInfo || !bridgePairInfo.pair) {
234
+ return Promise.resolve(undefined);
235
+ }
236
+ const _sendingAmount = isBridgeFirst ? request.fromAmount : selectedQuote.toAmount;
237
+ const sendingAmount = (0, _bignumber.default)(_sendingAmount).multipliedBy(2).toFixed(0, 1); // ensure approve enough amount
238
+ const senderAddress = request.address;
239
+ const fromTokenInfo = this.chainService.getAssetBySlug(bridgePairInfo.pair.from);
240
+ const fromChainInfo = this.chainService.getChainInfoByKey((0, _utils3._getAssetOriginChain)(fromTokenInfo));
241
+ const fromChainId = (0, _utils3._getEvmChainId)(fromChainInfo);
217
242
  const evmApi = this.chainService.getEvmApi(fromChainInfo.slug);
218
- const tokenContract = (0, _utils2._getContractAddressOfToken)(fromTokenInfo);
219
- const toTokenInfo = this.chainService.getAssetBySlug(params.request.pair.to);
220
- const toChainInfo = this.chainService.getChainInfoByKey((0, _utils2._getAssetOriginChain)(toTokenInfo));
221
- if ((0, _utils2._isNativeToken)(fromTokenInfo)) {
243
+ const tokenContract = (0, _utils3._getContractAddressOfToken)(fromTokenInfo);
244
+ const toTokenInfo = this.chainService.getAssetBySlug(bridgePairInfo.pair.to);
245
+ const toChainInfo = this.chainService.getChainInfoByKey((0, _utils3._getAssetOriginChain)(toTokenInfo));
246
+ if ((0, _utils3._isNativeToken)(fromTokenInfo)) {
222
247
  return Promise.resolve(undefined);
223
248
  }
224
249
  if (!fromChainId) {
@@ -227,9 +252,10 @@ class UniswapHandler {
227
252
  const inputData = {
228
253
  destinationTokenInfo: toTokenInfo,
229
254
  originTokenInfo: fromTokenInfo,
230
- sendingValue: sendingAmount,
255
+ sendingValue: _sendingAmount,
231
256
  sender: senderAddress,
232
257
  recipient: senderAddress,
258
+ // todo: there's a case swap - bridge to another address
233
259
  destinationChain: toChainInfo,
234
260
  originChain: fromChainInfo
235
261
  };
@@ -242,7 +268,7 @@ class UniswapHandler {
242
268
  const tx = await (0, _web.getERC20SpendingApprovalTx)(spokePoolAddress, senderAddress, tokenContract, evmApi);
243
269
  const evmFeeInfo = await this.feeService.subscribeChainFee((0, _getId.getId)(), fromTokenInfo.originChain, 'evm');
244
270
  const estimatedFee = await (0, _web.estimateTxFee)(tx, evmApi, evmFeeInfo);
245
- const nativeTokenSlug = (0, _utils2._getChainNativeTokenSlug)(fromChainInfo);
271
+ const nativeTokenSlug = (0, _utils3._getChainNativeTokenSlug)(fromChainInfo);
246
272
  const feeInfo = {
247
273
  feeComponent: [{
248
274
  feeType: _types.SwapFeeType.NETWORK_FEE,
@@ -302,6 +328,10 @@ class UniswapHandler {
302
328
  if (!selectedQuote) {
303
329
  return Promise.resolve(undefined);
304
330
  }
331
+ const actionList = JSON.stringify(path.map(step => step.action));
332
+ const swapXcm = actionList === JSON.stringify([_types.DynamicSwapType.SWAP, _types.DynamicSwapType.BRIDGE]);
333
+ const sendingValue = swapXcm ? (0, _bignumber.default)(request.fromAmount).multipliedBy(_utils.DEFAULT_EXCESS_AMOUNT_WEIGHT).toFixed(0, 1) : request.fromAmount;
334
+ const expectedReceive = swapXcm ? (0, _bignumber.default)(selectedQuote.toAmount).multipliedBy(_utils.DEFAULT_EXCESS_AMOUNT_WEIGHT).toFixed(0, 1) : selectedQuote.toAmount;
305
335
  const originTokenInfo = this.chainService.getAssetBySlug(selectedQuote.pair.from);
306
336
  const destinationTokenInfo = this.chainService.getAssetBySlug(selectedQuote.pair.to);
307
337
  const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
@@ -311,12 +341,12 @@ class UniswapHandler {
311
341
  type: _types.SwapStepType.SWAP,
312
342
  // @ts-ignore
313
343
  metadata: {
314
- sendingValue: request.fromAmount.toString(),
315
- expectedReceive: selectedQuote.toAmount,
344
+ sendingValue,
345
+ expectedReceive,
316
346
  originTokenInfo,
317
347
  destinationTokenInfo,
318
- sender: (0, _utils._reformatAddressWithChain)(request.address, originChain),
319
- receiver: (0, _utils._reformatAddressWithChain)(request.recipient || request.address, destinationChain),
348
+ sender: (0, _utils2._reformatAddressWithChain)(request.address, originChain),
349
+ receiver: (0, _utils2._reformatAddressWithChain)(request.recipient || request.address, destinationChain),
320
350
  version: 2
321
351
  }
322
352
  };
@@ -328,6 +358,20 @@ class UniswapHandler {
328
358
  request,
329
359
  selectedQuote
330
360
  } = params;
361
+ /**
362
+ * Explain: All processes will go through one of below processes. If a step do not have, it returns undefined and
363
+ * the stepIndex is still counted up
364
+ *
365
+ * Processes:
366
+ * approve - permit - swap or
367
+ * approve - permit - swap - approve - bridge or
368
+ * approve - bridge - approve - permit - swap
369
+ */
370
+ const actionList = JSON.stringify(path.map(step => step.action));
371
+ const bridgeSwap = actionList === JSON.stringify([_types.DynamicSwapType.BRIDGE, _types.DynamicSwapType.SWAP]);
372
+ const swapBridge = actionList === JSON.stringify([_types.DynamicSwapType.SWAP, _types.DynamicSwapType.BRIDGE]);
373
+ const isBridgeFirst = stepIndex === 1 && bridgeSwap;
374
+ const isBridgeSecond = stepIndex === 4 && swapBridge;
331
375
 
332
376
  // stepIndex is not corresponding index in path, because uniswap include approval and permit step
333
377
  const bridgePairInfo = path.find(action => action.action === _types.DynamicSwapType.BRIDGE);
@@ -344,9 +388,18 @@ class UniswapHandler {
344
388
  if (!fromChainInfo || !toChainInfo || !fromChainInfo || !toChainInfo) {
345
389
  throw Error('Token or chain not found');
346
390
  }
347
- const senderAddress = (0, _utils._reformatAddressWithChain)(request.address, fromChainInfo);
348
- const receiverAddress = (0, _utils._reformatAddressWithChain)(request.recipient || request.address, toChainInfo);
349
- const sendingValue = (0, _bignumber.default)(selectedQuote.toAmount).div(1.02).toFixed(0, 1);
391
+ let receiverAddress;
392
+ let mockSendingValue;
393
+ const senderAddress = (0, _utils2._reformatAddressWithChain)(request.address, fromChainInfo);
394
+ if (isBridgeFirst) {
395
+ receiverAddress = (0, _utils2._reformatAddressWithChain)(request.address, toChainInfo);
396
+ mockSendingValue = (0, _bignumber.default)(selectedQuote.fromAmount).toFixed(0, 1);
397
+ } else if (isBridgeSecond) {
398
+ receiverAddress = (0, _utils2._reformatAddressWithChain)(request.recipient || request.address, toChainInfo);
399
+ mockSendingValue = (0, _bignumber.default)(selectedQuote.toAmount).toFixed(0, 1);
400
+ } else {
401
+ return undefined;
402
+ }
350
403
  try {
351
404
  const evmApi = await this.chainService.getEvmApi(fromChainInfo.slug).isReady;
352
405
  const feeInfo = await this.feeService.subscribeChainFee((0, _getId.getId)(), fromTokenInfo.originChain, 'evm');
@@ -358,33 +411,45 @@ class UniswapHandler {
358
411
  evmApi,
359
412
  feeInfo,
360
413
  // Mock sending value to get payment info
361
- sendingValue,
414
+ sendingValue: mockSendingValue,
362
415
  sender: senderAddress,
363
416
  recipient: receiverAddress
364
417
  });
365
-
366
- // // todo: wait until this ready to get destination fee. the real receiveAmount is deduce by this fee
367
- // const acrossQuote = await getAcrossQuote({
368
- // destinationChain: toChainInfo,
369
- // destinationTokenInfo: toTokenInfo,
370
- // originChain: fromChainInfo,
371
- // originTokenInfo: fromTokenInfo,
372
- // recipient: receiverAddress,
373
- // sender: senderAddress,
374
- // sendingValue,
375
- // feeInfo
376
- // });
377
-
418
+ const acrossQuote = await (0, _acrossBridge.getAcrossQuote)({
419
+ destinationChain: toChainInfo,
420
+ destinationTokenInfo: toTokenInfo,
421
+ originChain: fromChainInfo,
422
+ originTokenInfo: fromTokenInfo,
423
+ recipient: receiverAddress,
424
+ sender: senderAddress,
425
+ sendingValue: mockSendingValue,
426
+ feeInfo
427
+ });
428
+ const acrossQuoteMetadata = acrossQuote.metadata;
378
429
  const estimatedBridgeFee = await (0, _web.estimateTxFee)(tx, evmApi, feeInfo);
379
- const expectedReceive = (0, _bignumber.default)(sendingValue).minus(estimatedBridgeFee).toFixed(0, 1);
430
+ const estimatedDestinationFee = (0, _bignumber.default)(mockSendingValue).minus(acrossQuoteMetadata.outputAmount).toFixed(0, 1); // todo: should better handle on backend and return desFee metadata instead of minus like this
431
+
432
+ let sendingValue;
433
+ let expectedReceive;
434
+ if (isBridgeFirst) {
435
+ expectedReceive = selectedQuote.fromAmount;
436
+ sendingValue = (0, _bignumber.default)(estimatedDestinationFee).multipliedBy(_utils.FEE_RATE_MULTIPLIER.medium).plus(selectedQuote.fromAmount).toFixed(0, 1);
437
+ } else if (isBridgeSecond) {
438
+ expectedReceive = selectedQuote.toAmount;
439
+ sendingValue = (0, _bignumber.default)(selectedQuote.toAmount).multipliedBy(_utils.DEFAULT_EXCESS_AMOUNT_WEIGHT).toFixed(0, 1);
440
+ } else {
441
+ return undefined;
442
+ }
443
+ console.log('[i] estimatedBridgeFee', estimatedBridgeFee);
444
+ console.log('[i] estimatedDestinationFee', estimatedDestinationFee);
380
445
  const fee = {
381
446
  feeComponent: [{
382
447
  feeType: _types.SwapFeeType.NETWORK_FEE,
383
448
  amount: estimatedBridgeFee,
384
- tokenSlug: (0, _utils2._getChainNativeTokenSlug)(fromChainInfo)
449
+ tokenSlug: (0, _utils3._getChainNativeTokenSlug)(fromChainInfo)
385
450
  }],
386
- defaultFeeToken: (0, _utils2._getChainNativeTokenSlug)(fromChainInfo),
387
- feeOptions: [(0, _utils2._getChainNativeTokenSlug)(fromChainInfo)]
451
+ defaultFeeToken: (0, _utils3._getChainNativeTokenSlug)(fromChainInfo),
452
+ feeOptions: [(0, _utils3._getChainNativeTokenSlug)(fromChainInfo)]
388
453
  };
389
454
  const step = {
390
455
  // @ts-ignore
@@ -479,7 +544,7 @@ class UniswapHandler {
479
544
  if (approval) {
480
545
  var _priority$options, _priority$options$Fee, _priority$options2;
481
546
  const evmApi = this.chainService.getEvmApi(fromAsset.originChain);
482
- const priority = await (0, _utils3.calculateGasFeeParams)(evmApi, evmApi.chainSlug);
547
+ const priority = await (0, _utils4.calculateGasFeeParams)(evmApi, evmApi.chainSlug);
483
548
  transactionConfig = {
484
549
  from: approval.from,
485
550
  to: approval.to,
@@ -511,7 +576,7 @@ class UniswapHandler {
511
576
  }
512
577
  async approveSpendingBridge(approveStep) {
513
578
  const fromAsset = this.chainService.getAssetBySlug(approveStep.tokenApprove);
514
- const fromChain = (0, _utils2._getAssetOriginChain)(fromAsset);
579
+ const fromChain = (0, _utils3._getAssetOriginChain)(fromAsset);
515
580
  const evmApi = this.chainService.getEvmApi(fromAsset.originChain);
516
581
  const sender = approveStep.owner;
517
582
  const sendingValue = approveStep.amount;
@@ -652,7 +717,7 @@ class UniswapHandler {
652
717
  submitSwapOrder,
653
718
  cronCheckTxSuccess
654
719
  },
655
- transferNativeAmount: (0, _utils2._isNativeToken)(fromAsset) ? params.quote.fromAmount : '0',
720
+ transferNativeAmount: (0, _utils3._isNativeToken)(fromAsset) ? params.quote.fromAmount : '0',
656
721
  extrinsicType: _KoniTypes.ExtrinsicType.SWAP,
657
722
  chainType: _KoniTypes.ChainType.EVM,
658
723
  isDutch: true
@@ -670,7 +735,7 @@ class UniswapHandler {
670
735
  txChain: fromAsset.originChain,
671
736
  txData,
672
737
  extrinsic: extrinsic,
673
- transferNativeAmount: (0, _utils2._isNativeToken)(fromAsset) ? params.quote.fromAmount : '0',
738
+ transferNativeAmount: (0, _utils3._isNativeToken)(fromAsset) ? params.quote.fromAmount : '0',
674
739
  extrinsicType: _KoniTypes.ExtrinsicType.SWAP,
675
740
  chainType: _KoniTypes.ChainType.EVM
676
741
  };
@@ -745,7 +810,7 @@ class UniswapHandler {
745
810
  if (swapIndex <= -1) {
746
811
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
747
812
  }
748
- if (swapXcm && bridgeIndex <= -1) {
813
+ if ((swapXcm || xcmSwap) && bridgeIndex <= -1) {
749
814
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
750
815
  }
751
816
  if (swap) {
@@ -756,7 +821,7 @@ class UniswapHandler {
756
821
  return this.swapBaseHandler.validateSwapXcmProcess(params, swapIndex, bridgeIndex);
757
822
  }
758
823
  if (xcmSwap) {
759
- return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
824
+ return this.swapBaseHandler.validateXcmSwapProcess(params, swapIndex, bridgeIndex);
760
825
  }
761
826
  if (xcmSwapXcm) {
762
827
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
@@ -46,7 +46,7 @@ class SwapService {
46
46
  var _subwalletApiSdk$swap;
47
47
  const availableQuotes = [];
48
48
 
49
- // hotfix
49
+ // hotfix // todo: remove later
50
50
  const request = {
51
51
  ..._request,
52
52
  isSupportKyberVersion: true
@@ -43,6 +43,7 @@ export declare function validationConnectMiddleware(koni: KoniState, url: string
43
43
  export declare function validationEvmDataTransactionMiddleware(koni: KoniState, url: string, payload: PayloadValidated): Promise<PayloadValidated>;
44
44
  export declare function validationEvmSignMessageMiddleware(koni: KoniState, url: string, payload_: PayloadValidated): Promise<PayloadValidated>;
45
45
  export declare function validationAuthWCMiddleware(koni: KoniState, url: string, payload: PayloadValidated, topic?: string): Promise<PayloadValidated>;
46
+ export declare function validationAuthCardanoMiddleware(koni: KoniState, url: string, payload: PayloadValidated): Promise<PayloadValidated>;
46
47
  export declare function validationCardanoSignDataMiddleware(koni: KoniState, url: string, payload_: PayloadValidated): Promise<PayloadValidated>;
47
48
  export declare function convertErrorMessage(message_: string, name?: string): string[];
48
49
  export declare function convertErrorFormat(errors: Error[]): ErrorValidation[];
@@ -7,11 +7,11 @@ import { EvmProviderError } from '@subwallet/extension-base/background/errors/Ev
7
7
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
8
8
  import { CardanoProviderErrorType, EvmProviderErrorType } from '@subwallet/extension-base/background/KoniTypes';
9
9
  import { BasicTxErrorType } from '@subwallet/extension-base/types';
10
- import { BN_ZERO, combineEthFee, createPromiseHandler, isSameAddress, stripUrl, wait } from '@subwallet/extension-base/utils';
10
+ import { BN_ZERO, combineEthFee, createPromiseHandler, isSameAddress, reformatAddress, stripUrl, wait } from '@subwallet/extension-base/utils';
11
11
  import { validateAddressNetwork } from '@subwallet/extension-base/utils/cardano';
12
12
  import { isContractAddress, parseContractInput } from '@subwallet/extension-base/utils/eth/parseTransaction';
13
13
  import { getId } from '@subwallet/extension-base/utils/getId';
14
- import { isCardanoAddress, isSubstrateAddress } from '@subwallet/keyring';
14
+ import { isCardanoAddress, isCardanoBaseAddress, isCardanoRewardAddress, isSubstrateAddress } from '@subwallet/keyring';
15
15
  import { keyring } from '@subwallet/ui-keyring';
16
16
  import { getSdkError } from '@walletconnect/utils';
17
17
  import BigN from 'bignumber.js';
@@ -128,36 +128,33 @@ export async function generateValidationProcess(koni, url, payloadValidate, vali
128
128
  }
129
129
  return resultValidated;
130
130
  }
131
+ function handleAuthError(payload, message, errorPosition, errors) {
132
+ payload.errorPosition = errorPosition;
133
+ errors.push(new Error(convertErrorMessage(message)[0]));
134
+ return payload;
135
+ }
131
136
  export async function validationAuthMiddleware(koni, url, payload) {
132
137
  const {
133
138
  address,
134
139
  errors
135
140
  } = payload;
136
141
  if (!address || !isString(address)) {
137
- payload.errorPosition = 'dApp';
138
- const [message] = convertErrorMessage('Not found address to sign');
139
- errors.push(new Error(message));
142
+ return handleAuthError(payload, 'Not found address to sign', 'dApp', errors);
140
143
  } else {
141
144
  try {
142
145
  payload.pair = keyring.getPair(address);
143
146
  if (!payload.pair) {
144
- payload.errorPosition = 'dApp';
145
- const [message] = convertErrorMessage('Unable to find account');
146
- errors.push(new Error(message));
147
+ return handleAuthError(payload, 'Unable to find account', 'dApp', errors);
147
148
  } else {
148
149
  const authList = await koni.getAuthList();
149
150
  const authInfo = authList[stripUrl(url)];
150
151
  if (!authInfo || !authInfo.isAllowed || !authInfo.isAllowedMap[payload.pair.address]) {
151
- payload.errorPosition = 'dApp';
152
- const [message] = convertErrorMessage('Account not in allowed list', '');
153
- errors.push(new Error(message));
152
+ return handleAuthError(payload, 'Account not in allowed list', 'dApp', errors);
154
153
  }
155
154
  payload.authInfo = authInfo;
156
155
  }
157
156
  } catch (e) {
158
- const [message] = convertErrorMessage(e.message);
159
- payload.errorPosition = 'dApp';
160
- errors.push(new Error(message));
157
+ return handleAuthError(payload, e.message, 'dApp', errors);
161
158
  }
162
159
  }
163
160
  return payload;
@@ -545,6 +542,44 @@ export function validationAuthWCMiddleware(koni, url, payload, topic) {
545
542
  });
546
543
  return promise;
547
544
  }
545
+ export async function validationAuthCardanoMiddleware(koni, url, payload) {
546
+ const authList = await koni.getAuthList();
547
+ const authInfo = authList[stripUrl(url)];
548
+ const {
549
+ address,
550
+ errors
551
+ } = payload;
552
+ if (!authInfo || !authInfo.isAllowed) {
553
+ return handleAuthError(payload, 'Account not in allowed list', 'dApp', errors);
554
+ }
555
+ const currentAddress = authInfo.currentAccount;
556
+ const currentNetwork = authInfo.currentNetworkMap.cardano || 'cardano';
557
+ const currentNetworkId = +(currentNetwork === 'cardano');
558
+ if (!currentAddress || !authInfo.isAllowedMap[currentAddress]) {
559
+ return handleAuthError(payload, 'Unable to find account', 'dApp', errors);
560
+ }
561
+ const pair = keyring.getPair(currentAddress);
562
+ if (!pair) {
563
+ return handleAuthError(payload, 'Unable to find account', 'dApp', errors);
564
+ }
565
+ payload.pair = pair;
566
+ if (isCardanoBaseAddress(address)) {
567
+ if (!authInfo.isAllowedMap[address]) {
568
+ return handleAuthError(payload, 'Account not in allowed list', 'dApp', errors);
569
+ }
570
+ const addressByChainFormat = reformatAddress(currentAddress, currentNetworkId);
571
+ if (!isSameAddress(addressByChainFormat, address)) {
572
+ return handleAuthError(payload, 'Current account is changed', 'dApp', errors);
573
+ }
574
+ } else if (isCardanoRewardAddress(address)) {
575
+ const rewardAddress = pair.cardano.rewardAddress;
576
+ const addressByChainFormat = reformatAddress(rewardAddress, currentNetworkId);
577
+ if (!isSameAddress(addressByChainFormat, address)) {
578
+ return handleAuthError(payload, 'Current account is changed', 'dApp', errors);
579
+ }
580
+ }
581
+ return payload;
582
+ }
548
583
  export async function validationCardanoSignDataMiddleware(koni, url, payload_) {
549
584
  const {
550
585
  address,
@@ -589,6 +624,7 @@ export async function validationCardanoSignDataMiddleware(koni, url, payload_) {
589
624
  const payloadAfterValidated = {
590
625
  address,
591
626
  payload: payload,
627
+ currentAddress: authInfo === null || authInfo === void 0 ? void 0 : authInfo.currentAccount,
592
628
  hashPayload: payload,
593
629
  canSign: canSign,
594
630
  id: ''
@@ -8,7 +8,7 @@ import { withErrorLog } from '@subwallet/extension-base/background/handlers/help
8
8
  import { isSubscriptionRunning, unsubscribe } from '@subwallet/extension-base/background/handlers/subscriptions';
9
9
  import { APIItemState, CardanoProviderErrorType, ChainType, EvmProviderErrorType, ExternalRequestPromiseStatus, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
10
10
  import { BACKEND_API_URL, BACKEND_PRICE_HISTORY_URL, MANTA_PAY_BALANCE_INTERVAL, REMIND_EXPORT_ACCOUNT } from '@subwallet/extension-base/constants';
11
- import { convertErrorFormat, generateValidationProcess, validationAuthMiddleware, validationAuthWCMiddleware, validationCardanoSignDataMiddleware, validationConnectMiddleware, validationEvmDataTransactionMiddleware, validationEvmSignMessageMiddleware } from '@subwallet/extension-base/core/logic-validation';
11
+ import { convertErrorFormat, generateValidationProcess, validationAuthCardanoMiddleware, validationAuthMiddleware, validationAuthWCMiddleware, validationCardanoSignDataMiddleware, validationConnectMiddleware, validationEvmDataTransactionMiddleware, validationEvmSignMessageMiddleware } from '@subwallet/extension-base/core/logic-validation';
12
12
  import { BalanceService } from '@subwallet/extension-base/services/balance-service';
13
13
  import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
14
14
  import BuyService from '@subwallet/extension-base/services/buy-service';
@@ -1046,14 +1046,12 @@ export default class KoniState {
1046
1046
  errors: [],
1047
1047
  networkKey: ''
1048
1048
  };
1049
- const validationSteps = [validationAuthMiddleware, validationCardanoSignDataMiddleware];
1049
+ const validationSteps = [validationAuthCardanoMiddleware, validationCardanoSignDataMiddleware];
1050
1050
  const result = await generateValidationProcess(this, url, payloadValidation, validationSteps);
1051
- if (!isSameAddress(address, currentAddress)) {
1052
- throw new CardanoProviderError(CardanoProviderErrorType.ACCOUNT_CHANGED);
1053
- }
1054
1051
  const errorsFormated = convertErrorFormat(result.errors);
1055
1052
  const payloadAfterValidated = {
1056
1053
  ...result.payloadAfterValidated,
1054
+ currentAddress,
1057
1055
  errors: errorsFormated,
1058
1056
  id
1059
1057
  };
@@ -1161,7 +1159,6 @@ export default class KoniState {
1161
1159
  };
1162
1160
  }
1163
1161
  }
1164
- transactionValue = transactionValue.checked_sub(CardanoWasm.Value.new(tx.body().fee()));
1165
1162
  const transactionBody = tx.body();
1166
1163
  const getSpecificUtxo = this.chainService.getSpecificUtxo.bind(this);
1167
1164
  requireKeyHashes.push(...extractKeyHashFromCertificate(transactionBody.certs()));
@@ -1174,9 +1171,8 @@ export default class KoniState {
1174
1171
  const keyHashAddressMap = {};
1175
1172
  const pair = keyring.getPair(currentAddress);
1176
1173
  if (pair) {
1177
- const publicKey = CardanoWasm.Bip32PublicKey.from_bytes(pair.publicKey);
1178
- const paymentPubKey = publicKey.derive(0).derive(0).to_raw_key().hash().to_hex();
1179
- const stakePubKey = publicKey.derive(2).derive(0).to_raw_key().hash().to_hex();
1174
+ const paymentPubKey = CardanoWasm.Bip32PublicKey.from_hex(pair.cardano.paymentPubKey).to_raw_key().hash().to_hex();
1175
+ const stakePubKey = CardanoWasm.Bip32PublicKey.from_hex(pair.cardano.stakePubKey).to_raw_key().hash().to_hex();
1180
1176
  keyHashAddressMap[paymentPubKey] = 'payment';
1181
1177
  keyHashAddressMap[stakePubKey] = 'stake';
1182
1178
  } else {
@@ -53,6 +53,7 @@ export default class KoniTabs {
53
53
  private cardanoGetAccountList;
54
54
  private cardanoGetAccountBalance;
55
55
  private cardanoGetChangeAddress;
56
+ private cardanoGetRewardAddress;
56
57
  private cardanoGetCurrentNetworkId;
57
58
  private cardanoGetUtxo;
58
59
  private cardanoGetCollateral;
@@ -27,6 +27,7 @@ import { isEthereumAddress } from '@polkadot/util-crypto';
27
27
  function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthTypes) {
28
28
  const accountSelected = authInfo ? authInfo.isAllowed ? Object.keys(authInfo.isAllowedMap).filter(address => authInfo.isAllowedMap[address]) : [] : [];
29
29
  const authTypeFilter = ({
30
+ json,
30
31
  type
31
32
  }) => {
32
33
  if (accountAuthTypes) {
@@ -39,10 +40,19 @@ function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthTyp
39
40
  ton: TonKeypairTypes,
40
41
  cardano: CardanoKeypairTypes
41
42
  };
42
- return accountAuthTypes.some(authType => {
43
+ const isValidTypes = accountAuthTypes.some(authType => {
43
44
  var _validTypes$authType;
44
45
  return (_validTypes$authType = validTypes[authType]) === null || _validTypes$authType === void 0 ? void 0 : _validTypes$authType.includes(type);
45
46
  });
47
+ if (!isValidTypes) {
48
+ return false;
49
+ }
50
+
51
+ // This condition ensures that the resulting UTXOs from the user's transaction are not sent to addresses the wallet cannot manage.
52
+ if (type === 'cardano' && json.meta.isReadOnly) {
53
+ return false;
54
+ }
55
+ return true;
46
56
  } else {
47
57
  return true;
48
58
  }
@@ -1099,8 +1109,8 @@ export default class KoniTabs {
1099
1109
  this.#koniState.setAuthorize(authList);
1100
1110
  }
1101
1111
  return accountList.map(address => {
1102
- const isTestnet = (authInfo === null || authInfo === void 0 ? void 0 : authInfo.currentNetworkMap.cardano) !== 'cardano_preproduction';
1103
- const addressChainFormat = reformatAddress(address, +isTestnet);
1112
+ const isMainnet = (authInfo === null || authInfo === void 0 ? void 0 : authInfo.currentNetworkMap.cardano) !== 'cardano_preproduction';
1113
+ const addressChainFormat = reformatAddress(address, +isMainnet);
1104
1114
  return convertCardanoAddressToHex(addressChainFormat);
1105
1115
  });
1106
1116
  }
@@ -1128,10 +1138,31 @@ export default class KoniTabs {
1128
1138
  address,
1129
1139
  network
1130
1140
  } = await this.getCurrentInformationCardanoDapp(url);
1131
- const isTestnet = network !== 'cardano_preproduction';
1132
- const addressChainFormat = reformatAddress(address, +isTestnet);
1141
+ const isMainnet = network !== 'cardano_preproduction';
1142
+ const addressChainFormat = reformatAddress(address, +isMainnet);
1133
1143
  return convertCardanoAddressToHex(addressChainFormat);
1134
1144
  }
1145
+ async cardanoGetRewardAddress(id, url) {
1146
+ const authList = await this.#koniState.getAuthList();
1147
+ const urlStripped = stripUrl(url);
1148
+ const authInfo = authList[urlStripped];
1149
+ if (!authInfo || !authInfo.isAllowedMap) {
1150
+ throw new CardanoProviderError(CardanoProviderErrorType.REFUSED_REQUEST, 'You need to connect to the wallet first');
1151
+ }
1152
+ const accountList = await this.getCurrentAccount(url, 'cardano');
1153
+ const currentCardanoAccount = authInfo.currentAccount;
1154
+ if (currentCardanoAccount !== accountList[0]) {
1155
+ authList[urlStripped].currentAccount = accountList[0];
1156
+ this.#koniState.setAuthorize(authList);
1157
+ }
1158
+ return accountList.map(address => {
1159
+ const pair = keyring.getPair(address);
1160
+ const rewardAddress = pair.cardano.rewardAddress;
1161
+ const isTestnet = (authInfo === null || authInfo === void 0 ? void 0 : authInfo.currentNetworkMap.cardano) !== 'cardano_preproduction';
1162
+ const addressChainFormat = reformatAddress(rewardAddress, +isTestnet);
1163
+ return convertCardanoAddressToHex(addressChainFormat);
1164
+ });
1165
+ }
1135
1166
  async cardanoGetCurrentNetworkId(id, url) {
1136
1167
  let currentChain;
1137
1168
  let autoActiveChain = false;
@@ -1312,6 +1343,8 @@ export default class KoniTabs {
1312
1343
  return await this.cardanoGetAccountBalance(id, url);
1313
1344
  case 'cardano(account.get.change.address)':
1314
1345
  return await this.cardanoGetChangeAddress(id, url);
1346
+ case 'cardano(account.get.reward.address)':
1347
+ return await this.cardanoGetRewardAddress(id, url);
1315
1348
  case 'cardano(account.get.collateral)':
1316
1349
  return await this.cardanoGetCollateral(id, url, request);
1317
1350
  case 'cardano(account.get.utxos)':
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.3.37-0",
20
+ "version": "1.3.39-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -2710,13 +2710,13 @@
2710
2710
  "@sora-substrate/type-definitions": "^1.17.7",
2711
2711
  "@substrate/connect": "^0.8.9",
2712
2712
  "@subwallet/chain-list": "0.2.104",
2713
- "@subwallet/extension-base": "^1.3.37-0",
2714
- "@subwallet/extension-chains": "^1.3.37-0",
2715
- "@subwallet/extension-dapp": "^1.3.37-0",
2716
- "@subwallet/extension-inject": "^1.3.37-0",
2717
- "@subwallet/keyring": "^0.1.11",
2718
- "@subwallet/subwallet-api-sdk": "^1.3.37-0",
2719
- "@subwallet/ui-keyring": "^0.1.11",
2713
+ "@subwallet/extension-base": "^1.3.39-0",
2714
+ "@subwallet/extension-chains": "^1.3.39-0",
2715
+ "@subwallet/extension-dapp": "^1.3.39-0",
2716
+ "@subwallet/extension-inject": "^1.3.39-0",
2717
+ "@subwallet/keyring": "^0.1.12",
2718
+ "@subwallet/subwallet-api-sdk": "^1.3.39-0",
2719
+ "@subwallet/ui-keyring": "^0.1.12",
2720
2720
  "@ton/core": "^0.56.3",
2721
2721
  "@ton/crypto": "^3.2.0",
2722
2722
  "@ton/ton": "^15.0.0",
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.37-0'
10
+ version: '1.3.39-0'
11
11
  };