@subwallet/extension-base 1.3.35-0 → 1.3.37-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 (39) hide show
  1. package/background/KoniTypes.d.ts +13 -0
  2. package/background/types.d.ts +2 -1
  3. package/cjs/core/logic-validation/request.js +13 -1
  4. package/cjs/koni/background/handlers/Extension.js +189 -108
  5. package/cjs/koni/background/handlers/State.js +14 -9
  6. package/cjs/packageInfo.js +1 -1
  7. package/cjs/services/request-service/handler/AuthRequestHandler.js +4 -1
  8. package/cjs/services/request-service/handler/EvmRequestHandler.js +4 -1
  9. package/cjs/services/swap-service/handler/kyber-handler.js +355 -0
  10. package/cjs/services/swap-service/handler/uniswap-handler.js +209 -40
  11. package/cjs/services/swap-service/index.js +28 -2
  12. package/cjs/services/swap-service/utils.js +4 -1
  13. package/cjs/services/transaction-service/index.js +252 -28
  14. package/cjs/types/swap/index.js +2 -1
  15. package/cjs/utils/cardano.js +10 -2
  16. package/core/logic-validation/request.js +13 -1
  17. package/koni/background/handlers/Extension.d.ts +1 -0
  18. package/koni/background/handlers/Extension.js +82 -2
  19. package/koni/background/handlers/State.js +15 -10
  20. package/package.json +14 -9
  21. package/packageInfo.js +1 -1
  22. package/services/chain-service/types.d.ts +1 -1
  23. package/services/event-service/types.d.ts +6 -6
  24. package/services/request-service/handler/AuthRequestHandler.js +4 -1
  25. package/services/request-service/handler/EvmRequestHandler.js +4 -1
  26. package/services/swap-service/handler/kyber-handler.d.ts +28 -0
  27. package/services/swap-service/handler/kyber-handler.js +346 -0
  28. package/services/swap-service/handler/uniswap-handler.d.ts +48 -0
  29. package/services/swap-service/handler/uniswap-handler.js +209 -40
  30. package/services/swap-service/index.js +28 -2
  31. package/services/swap-service/utils.js +4 -1
  32. package/services/transaction-service/helpers/index.d.ts +5 -5
  33. package/services/transaction-service/index.d.ts +10 -5
  34. package/services/transaction-service/index.js +234 -12
  35. package/services/transaction-service/types.d.ts +23 -10
  36. package/types/swap/index.d.ts +4 -1
  37. package/types/swap/index.js +2 -1
  38. package/utils/cardano.d.ts +2 -0
  39. package/utils/cardano.js +7 -0
@@ -41,7 +41,7 @@ import WalletConnectService from '@subwallet/extension-base/services/wallet-conn
41
41
  import { SWStorage } from '@subwallet/extension-base/storage';
42
42
  import { BasicTxErrorType } from '@subwallet/extension-base/types';
43
43
  import { addLazy, isManifestV3, isSameAddress, reformatAddress, stripUrl, targetIsWeb } from '@subwallet/extension-base/utils';
44
- import { convertCardanoHexToBech32 } from '@subwallet/extension-base/utils/cardano';
44
+ import { convertCardanoHexToBech32, validateAddressNetwork } from '@subwallet/extension-base/utils/cardano';
45
45
  import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
46
46
  import subwalletApiSdk from '@subwallet/subwallet-api-sdk';
47
47
  import { keyring } from '@subwallet/ui-keyring';
@@ -1094,13 +1094,13 @@ export default class KoniState {
1094
1094
  if (authInfo !== null && authInfo !== void 0 && authInfo.isAllowed) {
1095
1095
  autoActiveChain = true;
1096
1096
  }
1097
- const currentEvmNetwork = this.requestService.getDAppChainInfo({
1097
+ const currentCardanoNetwork = this.requestService.getDAppChainInfo({
1098
1098
  autoActive: autoActiveChain,
1099
1099
  accessType: 'cardano',
1100
1100
  defaultChain: networkKey,
1101
1101
  url
1102
1102
  });
1103
- networkKey = (currentEvmNetwork === null || currentEvmNetwork === void 0 ? void 0 : currentEvmNetwork.slug) || 'cardano';
1103
+ networkKey = (currentCardanoNetwork === null || currentCardanoNetwork === void 0 ? void 0 : currentCardanoNetwork.slug) || 'cardano';
1104
1104
  const allUtxos = await this.chainService.getUtxosByAddress(currentAddress, networkKey);
1105
1105
  const outputTransactionUnSpend = CardanoWasm.TransactionOutputs.new();
1106
1106
  inputs.to_js_value().forEach(input => {
@@ -1137,12 +1137,23 @@ export default class KoniState {
1137
1137
  values: convertValueToAsset(output)
1138
1138
  };
1139
1139
  if (isSameAddress(currentAddress, address)) {
1140
+ if (!validateAddressNetwork(address, currentCardanoNetwork)) {
1141
+ throw new CardanoProviderError(CardanoProviderErrorType.ACCOUNT_CHANGED, t('Current network is changed'));
1142
+ }
1140
1143
  transactionValue = transactionValue.checked_add(amount);
1141
1144
  addressInputAmountMap[address].isOwner = true;
1142
1145
  addressOutputAmountMap[address].isOwner = true;
1143
1146
  }
1147
+
1148
+ // Check if address is valid with current network
1149
+ if (!validateAddressNetwork(address, currentCardanoNetwork)) {
1150
+ throw new CardanoProviderError(CardanoProviderErrorType.INVALID_REQUEST, t('Current network is not match with input address'));
1151
+ }
1144
1152
  }
1145
1153
  for (const address in addressOutputMap) {
1154
+ if (!validateAddressNetwork(address, currentCardanoNetwork)) {
1155
+ throw new CardanoProviderError(CardanoProviderErrorType.INVALID_REQUEST, t('Current network is not match with output address'));
1156
+ }
1146
1157
  if (!addressInputAmountMap[address] && !addressOutputMap[address].is_zero()) {
1147
1158
  addressOutputAmountMap[address] = {
1148
1159
  values: convertValueToAsset(addressOutputMap[address]),
@@ -1250,13 +1261,7 @@ export default class KoniState {
1250
1261
  async onMV3Update() {
1251
1262
  const migrationStatus = await SWStorage.instance.getItem('mv3_migration');
1252
1263
  if (!migrationStatus || migrationStatus !== 'done') {
1253
- if (isManifestV3) {
1254
- // Open migration tab
1255
- const url = `${chrome.runtime.getURL('index.html')}#/mv3-migration`;
1256
- await openPopup(url);
1257
-
1258
- // migrateMV3LocalStorage will be called when user open migration tab with data from localStorage on frontend
1259
- } else {
1264
+ if (!isManifestV3) {
1260
1265
  this.migrateMV3LocalStorage(JSON.stringify(self.localStorage)).catch(console.error);
1261
1266
  }
1262
1267
  }
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "./cjs/detectPackage.js"
18
18
  ],
19
19
  "type": "module",
20
- "version": "1.3.35-0",
20
+ "version": "1.3.37-0",
21
21
  "main": "./cjs/index.js",
22
22
  "module": "./index.js",
23
23
  "types": "./index.d.ts",
@@ -1911,6 +1911,11 @@
1911
1911
  "require": "./cjs/services/swap-service/handler/hydradx-handler.js",
1912
1912
  "default": "./services/swap-service/handler/hydradx-handler.js"
1913
1913
  },
1914
+ "./services/swap-service/handler/kyber-handler": {
1915
+ "types": "./services/swap-service/handler/kyber-handler.d.ts",
1916
+ "require": "./cjs/services/swap-service/handler/kyber-handler.js",
1917
+ "default": "./services/swap-service/handler/kyber-handler.js"
1918
+ },
1914
1919
  "./services/swap-service/handler/simpleswap-handler": {
1915
1920
  "types": "./services/swap-service/handler/simpleswap-handler.d.ts",
1916
1921
  "require": "./cjs/services/swap-service/handler/simpleswap-handler.js",
@@ -2705,20 +2710,20 @@
2705
2710
  "@sora-substrate/type-definitions": "^1.17.7",
2706
2711
  "@substrate/connect": "^0.8.9",
2707
2712
  "@subwallet/chain-list": "0.2.104",
2708
- "@subwallet/extension-base": "^1.3.35-0",
2709
- "@subwallet/extension-chains": "^1.3.35-0",
2710
- "@subwallet/extension-dapp": "^1.3.35-0",
2711
- "@subwallet/extension-inject": "^1.3.35-0",
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",
2712
2717
  "@subwallet/keyring": "^0.1.11",
2713
- "@subwallet/subwallet-api-sdk": "^1.3.35-0",
2718
+ "@subwallet/subwallet-api-sdk": "^1.3.37-0",
2714
2719
  "@subwallet/ui-keyring": "^0.1.11",
2715
2720
  "@ton/core": "^0.56.3",
2716
2721
  "@ton/crypto": "^3.2.0",
2717
2722
  "@ton/ton": "^15.0.0",
2718
2723
  "@walletconnect/keyvaluestorage": "^1.1.1",
2719
- "@walletconnect/sign-client": "^2.14.0",
2720
- "@walletconnect/types": "^2.14.0",
2721
- "@walletconnect/utils": "^2.14.0",
2724
+ "@walletconnect/sign-client": "^2.20.2",
2725
+ "@walletconnect/types": "^2.20.2",
2726
+ "@walletconnect/utils": "^2.20.2",
2722
2727
  "avail-js-sdk": "^0.2.12",
2723
2728
  "axios": "^1.6.2",
2724
2729
  "bignumber.js": "^9.1.1",
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.35-0'
10
+ version: '1.3.37-0'
11
11
  };
@@ -15,8 +15,8 @@ import { ChainProperties, ChainType, RuntimeVersion } from '@polkadot/types/inte
15
15
  import { AnyJson, Registry } from '@polkadot/types/types';
16
16
  export interface _DataMap {
17
17
  chainInfoMap: Record<string, _ChainInfo>;
18
- chainStateMap: Record<string, _ChainState>;
19
18
  assetRegistry: Record<string, _ChainAsset>;
19
+ chainStateMap: Record<string, _ChainState>;
20
20
  assetRefMap: Record<string, _AssetRef>;
21
21
  }
22
22
  export declare enum _ChainConnectionStatus {
@@ -1,4 +1,4 @@
1
- import { SWTransaction } from '@subwallet/extension-base/services/transaction-service/types';
1
+ import { SWTransactionBase } from '@subwallet/extension-base/services/transaction-service/types';
2
2
  import { CurrentAccountInfo } from '@subwallet/extension-base/types';
3
3
  export interface EventRegistry {
4
4
  'general.sleep': [boolean];
@@ -27,13 +27,13 @@ export interface EventRegistry {
27
27
  'asset.ready': [boolean];
28
28
  'asset.online.ready': [boolean];
29
29
  'asset.updateState': [string];
30
- 'transaction.done': [SWTransaction];
31
- 'transaction.failed': [SWTransaction | undefined];
32
- 'transaction.timeout': [SWTransaction | undefined];
30
+ 'transaction.done': [SWTransactionBase];
31
+ 'transaction.failed': [SWTransactionBase | undefined];
32
+ 'transaction.timeout': [SWTransactionBase | undefined];
33
33
  'transaction.submitStaking': [string];
34
- 'transaction.transferNft': [SWTransaction | undefined];
34
+ 'transaction.transferNft': [SWTransactionBase | undefined];
35
35
  'mantaPay.initSync': [string | undefined];
36
- 'mantaPay.submitTransaction': [SWTransaction | undefined];
36
+ 'mantaPay.submitTransaction': [SWTransactionBase | undefined];
37
37
  'mantaPay.enable': [string];
38
38
  'migration.done': [boolean];
39
39
  'campaign.ready': [boolean];
@@ -260,7 +260,10 @@ export default class AuthRequestHandler {
260
260
  origin,
261
261
  url,
262
262
  accountAuthTypes: [...new Set([...accountAuthTypes, ...((existed === null || existed === void 0 ? void 0 : existed.accountAuthTypes) || [])])],
263
- currentNetworkMap: existed ? existed.currentNetworkMap : defaultNetworkMap
263
+ currentNetworkMap: existed ? {
264
+ ...defaultNetworkMap,
265
+ ...existed.currentNetworkMap
266
+ } : defaultNetworkMap
264
267
  };
265
268
  this.setAuthorize(authorizeList, () => {
266
269
  cb();
@@ -22,7 +22,8 @@ export default class EvmRequestHandler {
22
22
  evmSignatureRequest: {},
23
23
  evmSendTransactionRequest: {},
24
24
  evmWatchTransactionRequest: {},
25
- errorConnectNetwork: {}
25
+ errorConnectNetwork: {},
26
+ submitApiRequest: {}
26
27
  });
27
28
  confirmationsPromiseMap = {};
28
29
  constructor(requestService) {
@@ -214,6 +215,8 @@ export default class EvmRequestHandler {
214
215
  result.payload = await this.signMessage(request);
215
216
  } else if (t === 'evmSendTransactionRequest') {
216
217
  result.payload = await this.signTransaction(request);
218
+ } else if (t === 'submitApiRequest') {
219
+ return;
217
220
  }
218
221
  if (t === 'evmSignatureRequest' || t === 'evmSendTransactionRequest') {
219
222
  const isAlwaysRequired = await this.#requestService.settingService.isAlwaysRequired;
@@ -0,0 +1,28 @@
1
+ import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
2
+ import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo, OptimalSwapPathParamsV2, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types';
3
+ import { BalanceService } from '../../balance-service';
4
+ import { ChainService } from '../../chain-service';
5
+ import FeeService from '../../fee-service/service';
6
+ import TransactionService from '../../transaction-service';
7
+ import { SwapBaseInterface } from './base-handler';
8
+ export interface KyberSwapQuoteMetadata {
9
+ priceImpact?: string;
10
+ }
11
+ export declare const KYBER_CLIENT_ID: string;
12
+ export declare class KyberHandler implements SwapBaseInterface {
13
+ private swapBaseHandler;
14
+ transactionService: TransactionService;
15
+ providerSlug: SwapProviderId;
16
+ constructor(chainService: ChainService, balanceService: BalanceService, transactionService: TransactionService, feeService: FeeService);
17
+ get chainService(): ChainService;
18
+ get balanceService(): BalanceService;
19
+ get feeService(): FeeService;
20
+ get providerInfo(): import("@subwallet/extension-base/types").SwapProvider;
21
+ generateOptimalProcessV2(params: OptimalSwapPathParamsV2): Promise<CommonOptimalSwapPath>;
22
+ getApprovalStep(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
23
+ getSubmitStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
24
+ handleSwapProcess(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
25
+ private tokenApproveSpending;
26
+ handleSubmitStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
27
+ validateSwapProcessV2(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
28
+ }
@@ -0,0 +1,346 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
5
+ import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
6
+ import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
7
+ import { estimateTxFee, getERC20Allowance, getERC20SpendingApprovalTx } from '@subwallet/extension-base/koni/api/contract-handler/evm/web3';
8
+ import { BasicTxErrorType, CommonStepType, DynamicSwapType, SwapErrorType, SwapFeeType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
9
+ import { _reformatAddressWithChain, combineEthFee } from '@subwallet/extension-base/utils';
10
+ import { getId } from '@subwallet/extension-base/utils/getId';
11
+ import BigNumber from 'bignumber.js';
12
+ import { _getChainNativeTokenSlug, _getContractAddressOfToken, _isNativeToken } from "../../chain-service/utils/index.js";
13
+ import { calculateGasFeeParams } from "../../fee-service/utils/index.js";
14
+ import { SwapBaseHandler } from "./base-handler.js";
15
+ export const KYBER_CLIENT_ID = process.env.KYBER_CLIENT_ID || '';
16
+ const kyberUrl = 'https://aggregator-api.kyberswap.com';
17
+ async function buildTxForSwap(params, chain) {
18
+ const {
19
+ recipient,
20
+ sender,
21
+ slippageTolerance
22
+ } = params;
23
+ let routeSummary = params.routeSummary;
24
+ if (!routeSummary || !routeSummary.tokenIn || !routeSummary.tokenOut || !routeSummary.amountIn) {
25
+ const queryParams = new URLSearchParams({
26
+ tokenIn: routeSummary.tokenIn,
27
+ tokenOut: routeSummary.tokenOut,
28
+ amountIn: routeSummary.amountIn,
29
+ gasInclude: 'true'
30
+ });
31
+ const url = `${kyberUrl}/${chain}/api/v1/routes?${queryParams.toString()}`;
32
+ try {
33
+ var _routeData$data;
34
+ const res = await fetch(url, {
35
+ method: 'GET',
36
+ headers: {
37
+ 'Content-Type': 'application/json',
38
+ 'x-client-id': KYBER_CLIENT_ID,
39
+ accept: 'application/json'
40
+ }
41
+ });
42
+ const routeData = await res.json();
43
+ if (!routeData.success || !((_routeData$data = routeData.data) !== null && _routeData$data !== void 0 && _routeData$data.routeSummary)) {
44
+ return {
45
+ error: new TransactionError(BasicTxErrorType.INTERNAL_ERROR, routeData.message)
46
+ };
47
+ }
48
+ routeSummary = routeData.data.routeSummary;
49
+ } catch (error) {
50
+ console.error('Error:', error);
51
+ return {
52
+ error: new TransactionError(BasicTxErrorType.INTERNAL_ERROR)
53
+ };
54
+ }
55
+ }
56
+ const body = {
57
+ routeSummary,
58
+ sender,
59
+ recipient,
60
+ slippageTolerance,
61
+ ignoreCappedSlippage: true,
62
+ enableGasEstimation: true
63
+ };
64
+ try {
65
+ const res = await fetch(`${kyberUrl}/${chain}/api/v1/route/build`, {
66
+ method: 'POST',
67
+ headers: {
68
+ 'Content-Type': 'application/json',
69
+ 'x-client-id': KYBER_CLIENT_ID,
70
+ accept: 'application/json'
71
+ },
72
+ body: JSON.stringify(body)
73
+ });
74
+ const data = await res.json();
75
+ const requestData = data.data;
76
+ if (!requestData || !requestData.routerAddress || !requestData.data || !requestData.gas) {
77
+ var _data$details$map, _data$details, _data$message$toLower, _data$message;
78
+ const lowerDetails = (_data$details$map = (_data$details = data.details) === null || _data$details === void 0 ? void 0 : _data$details.map(d => d.toLowerCase())) !== null && _data$details$map !== void 0 ? _data$details$map : [];
79
+ const msg = (_data$message$toLower = (_data$message = data.message) === null || _data$message === void 0 ? void 0 : _data$message.toLowerCase()) !== null && _data$message$toLower !== void 0 ? _data$message$toLower : '';
80
+ if (lowerDetails.some(d => d.includes('insufficient liquidity'))) {
81
+ return {
82
+ error: new SwapError(SwapErrorType.NOT_ENOUGH_LIQUIDITY)
83
+ };
84
+ }
85
+ if (lowerDetails.some(d => d.includes('execution reverted')) || msg.includes('smaller than estimated')) {
86
+ return {
87
+ error: new SwapError(SwapErrorType.NOT_MEET_MIN_EXPECTED)
88
+ };
89
+ }
90
+ return {
91
+ error: new TransactionError(BasicTxErrorType.INTERNAL_ERROR, data.message)
92
+ };
93
+ }
94
+ return {
95
+ data: {
96
+ from: sender,
97
+ to: requestData.routerAddress,
98
+ value: requestData.transactionValue,
99
+ data: requestData.data,
100
+ gas: requestData.gas
101
+ }
102
+ };
103
+ } catch (error) {
104
+ console.error('Kyber error:', error);
105
+ return {
106
+ error: new TransactionError(BasicTxErrorType.INTERNAL_ERROR)
107
+ };
108
+ }
109
+ }
110
+ export class KyberHandler {
111
+ constructor(chainService, balanceService, transactionService, feeService) {
112
+ this.swapBaseHandler = new SwapBaseHandler({
113
+ chainService,
114
+ balanceService,
115
+ feeService,
116
+ providerName: 'Kyber',
117
+ providerSlug: SwapProviderId.KYBER
118
+ });
119
+ this.transactionService = transactionService;
120
+ this.providerSlug = SwapProviderId.KYBER;
121
+ }
122
+ get chainService() {
123
+ return this.swapBaseHandler.chainService;
124
+ }
125
+ get balanceService() {
126
+ return this.swapBaseHandler.balanceService;
127
+ }
128
+ get feeService() {
129
+ return this.swapBaseHandler.feeService;
130
+ }
131
+ get providerInfo() {
132
+ return this.swapBaseHandler.providerInfo;
133
+ }
134
+ generateOptimalProcessV2(params) {
135
+ return this.swapBaseHandler.generateOptimalProcessV2(params, [this.getApprovalStep.bind(this), this.getSubmitStep.bind(this)]);
136
+ }
137
+ async getApprovalStep(params) {
138
+ const selectedQuote = params.selectedQuote;
139
+ if (selectedQuote) {
140
+ const fromAsset = this.chainService.getAssetBySlug(selectedQuote.pair.from);
141
+ if (_isNativeToken(fromAsset)) {
142
+ return Promise.resolve(undefined);
143
+ }
144
+ const metadata = selectedQuote.metadata;
145
+ const routerContract = metadata.routerAddress;
146
+ const evmApi = this.chainService.getEvmApi(fromAsset.originChain);
147
+ const fromContractAddress = _getContractAddressOfToken(fromAsset);
148
+ const allowance = await getERC20Allowance(routerContract, params.request.address, fromContractAddress, evmApi);
149
+ if (allowance && new BigNumber(allowance).gt(params.request.fromAmount)) {
150
+ return Promise.resolve(undefined);
151
+ }
152
+ const sendingAmount = selectedQuote.toAmount;
153
+ const senderAddress = params.request.address;
154
+ const fromTokenInfo = this.chainService.getAssetBySlug(selectedQuote.pair.from);
155
+ const tokenContract = _getContractAddressOfToken(fromTokenInfo);
156
+ const spenderAddress = metadata.routerAddress;
157
+ const submitStep = {
158
+ name: 'Approve token',
159
+ type: CommonStepType.TOKEN_APPROVAL,
160
+ metadata: {
161
+ tokenApprove: fromTokenInfo.slug,
162
+ contractAddress: tokenContract,
163
+ spenderAddress: spenderAddress,
164
+ amount: sendingAmount,
165
+ owner: senderAddress
166
+ }
167
+ };
168
+ const tx = await getERC20SpendingApprovalTx(spenderAddress, senderAddress, tokenContract, evmApi);
169
+ const evmFeeInfo = await this.feeService.subscribeChainFee(getId(), fromTokenInfo.originChain, 'evm');
170
+ const estimatedFee = await estimateTxFee(tx, evmApi, evmFeeInfo);
171
+ const fromChainInfo = this.chainService.getChainInfoByKey(fromTokenInfo.originChain);
172
+ const nativeTokenSlug = _getChainNativeTokenSlug(fromChainInfo);
173
+ const feeInfo = {
174
+ feeComponent: [{
175
+ feeType: SwapFeeType.NETWORK_FEE,
176
+ amount: estimatedFee,
177
+ tokenSlug: nativeTokenSlug
178
+ }],
179
+ defaultFeeToken: nativeTokenSlug,
180
+ feeOptions: [nativeTokenSlug]
181
+ };
182
+ return Promise.resolve([submitStep, feeInfo]);
183
+ }
184
+ return Promise.resolve(undefined);
185
+ }
186
+ async getSubmitStep(params, stepIndex) {
187
+ const {
188
+ path,
189
+ request,
190
+ selectedQuote
191
+ } = params;
192
+
193
+ // stepIndex is not corresponding index in path, because uniswap include approval and permit step
194
+ const stepData = path.find(action => action.action === DynamicSwapType.SWAP);
195
+ if (!stepData || !stepData.pair) {
196
+ return Promise.resolve(undefined);
197
+ }
198
+ if (!selectedQuote) {
199
+ return Promise.resolve(undefined);
200
+ }
201
+ const originTokenInfo = this.chainService.getAssetBySlug(selectedQuote.pair.from);
202
+ const destinationTokenInfo = this.chainService.getAssetBySlug(selectedQuote.pair.to);
203
+ const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
204
+ const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
205
+ const submitStep = {
206
+ name: 'Swap',
207
+ type: SwapStepType.SWAP,
208
+ // @ts-ignore
209
+ metadata: {
210
+ sendingValue: request.fromAmount.toString(),
211
+ expectedReceive: selectedQuote.toAmount,
212
+ originTokenInfo,
213
+ destinationTokenInfo,
214
+ sender: _reformatAddressWithChain(request.address, originChain),
215
+ receiver: _reformatAddressWithChain(request.recipient || request.address, destinationChain),
216
+ version: 2
217
+ }
218
+ };
219
+ return Promise.resolve([submitStep, selectedQuote.feeInfo]);
220
+ }
221
+ async handleSwapProcess(params) {
222
+ const {
223
+ currentStep,
224
+ process
225
+ } = params;
226
+ const type = process.steps[currentStep].type;
227
+ switch (type) {
228
+ case CommonStepType.DEFAULT:
229
+ return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
230
+ case CommonStepType.TOKEN_APPROVAL:
231
+ return this.tokenApproveSpending(params);
232
+ case SwapStepType.SWAP:
233
+ return this.handleSubmitStep(params);
234
+ default:
235
+ return this.handleSubmitStep(params);
236
+ }
237
+ }
238
+ async tokenApproveSpending(params) {
239
+ const fromAsset = this.chainService.getAssetBySlug(params.quote.pair.from);
240
+ const fromContract = _getContractAddressOfToken(fromAsset);
241
+ const evmApi = this.chainService.getEvmApi(fromAsset.originChain);
242
+ const chain = fromAsset.originChain;
243
+ const metadata = params.quote.metadata;
244
+ if (!metadata || !metadata.routerAddress) {
245
+ throw new TransactionError(BasicTxErrorType.INVALID_PARAMS);
246
+ }
247
+ const routerContract = metadata.routerAddress;
248
+ const transactionConfig = await getERC20SpendingApprovalTx(routerContract, params.address, fromContract, evmApi);
249
+ const _data = {
250
+ spenderAddress: routerContract,
251
+ contractAddress: fromContract,
252
+ amount: params.quote.fromAmount,
253
+ owner: params.address,
254
+ chain: chain
255
+ };
256
+ return Promise.resolve({
257
+ txChain: chain,
258
+ extrinsicType: ExtrinsicType.TOKEN_SPENDING_APPROVAL,
259
+ extrinsic: transactionConfig,
260
+ txData: _data,
261
+ transferNativeAmount: '0',
262
+ chainType: ChainType.EVM
263
+ });
264
+ }
265
+ async handleSubmitStep(params) {
266
+ var _params$recipient;
267
+ const fromAsset = this.chainService.getAssetBySlug(params.quote.pair.from);
268
+ const toAsset = this.chainService.getAssetBySlug(params.quote.pair.to);
269
+ const chainInfo = this.chainService.getChainInfoByKey(fromAsset.originChain);
270
+ const toChainInfo = this.chainService.getChainInfoByKey(toAsset.originChain);
271
+ const sender = _reformatAddressWithChain(params.address, chainInfo);
272
+ const recipient = _reformatAddressWithChain((_params$recipient = params.recipient) !== null && _params$recipient !== void 0 ? _params$recipient : sender, toChainInfo);
273
+ const metadata = params.quote.metadata;
274
+ const slippageTolerance = params.slippage * 10000;
275
+ const rawTx = await buildTxForSwap({
276
+ routeSummary: metadata.routeSummary,
277
+ sender: params.address,
278
+ recipient,
279
+ slippageTolerance
280
+ }, metadata.network);
281
+ if (rawTx.error) {
282
+ console.error('Kyber error:', rawTx.error);
283
+ throw rawTx.error;
284
+ }
285
+ const evmApi = this.chainService.getEvmApi(fromAsset.originChain);
286
+ const priority = await calculateGasFeeParams(evmApi, evmApi.chainSlug);
287
+ const fee = combineEthFee(priority);
288
+ const transactionConfig = {
289
+ ...rawTx.data,
290
+ ...fee
291
+ };
292
+ const txData = {
293
+ address: params.address,
294
+ provider: this.providerInfo,
295
+ quote: params.quote,
296
+ slippage: params.slippage,
297
+ recipient: params.recipient,
298
+ process: params.process
299
+ };
300
+ return {
301
+ txChain: fromAsset.originChain,
302
+ txData,
303
+ extrinsic: transactionConfig,
304
+ transferNativeAmount: _isNativeToken(fromAsset) ? params.quote.fromAmount : '0',
305
+ extrinsicType: ExtrinsicType.SWAP,
306
+ chainType: ChainType.EVM
307
+ };
308
+ }
309
+ async validateSwapProcessV2(params) {
310
+ // todo: recheck address and recipient format in params
311
+ const {
312
+ process,
313
+ selectedQuote
314
+ } = params; // todo: review flow, currentStep param.
315
+
316
+ // todo: validate path with optimalProcess
317
+ // todo: review error message in case many step swap
318
+ if (BigNumber(selectedQuote.fromAmount).lte(0)) {
319
+ return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
320
+ }
321
+ const actionList = JSON.stringify(process.path.map(step => step.action));
322
+ const swap = actionList === JSON.stringify([DynamicSwapType.SWAP]);
323
+ const swapXcm = actionList === JSON.stringify([DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
324
+ const xcmSwap = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP]);
325
+ const xcmSwapXcm = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
326
+ const swapIndex = params.process.steps.findIndex(step => step.type === SwapStepType.SWAP); // todo
327
+
328
+ if (swapIndex <= -1) {
329
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
330
+ }
331
+ if (swap) {
332
+ return this.swapBaseHandler.validateSwapOnlyProcess(params, swapIndex); // todo: create interface for input request
333
+ }
334
+
335
+ if (swapXcm) {
336
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
337
+ }
338
+ if (xcmSwap) {
339
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
340
+ }
341
+ if (xcmSwapXcm) {
342
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
343
+ }
344
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
345
+ }
346
+ }
@@ -12,6 +12,53 @@ export declare type PermitData = {
12
12
  types: Record<string, unknown>;
13
13
  values: unknown;
14
14
  };
15
+ export interface UniswapMetadata {
16
+ permitData: PermitData;
17
+ quote: UniswapQuote;
18
+ routing: string;
19
+ }
20
+ declare type UniswapQuote = UniswapClassicQuote | UniswapDutchQuote;
21
+ interface UniswapClassicQuote {
22
+ swapper: string;
23
+ chainId: number;
24
+ input: {
25
+ amount: string;
26
+ token: string;
27
+ };
28
+ output: {
29
+ amount: string;
30
+ token: string;
31
+ };
32
+ }
33
+ interface UniswapDutchQuote {
34
+ orderInfo: {
35
+ swapper: string;
36
+ chainId: number;
37
+ input: UniswapDutchInput;
38
+ outputs: UniswapDutchOutput[];
39
+ };
40
+ orderId: string;
41
+ }
42
+ interface UniswapDutchInput {
43
+ startAmount: string;
44
+ endAmount: string;
45
+ token: string;
46
+ }
47
+ interface UniswapDutchOutput {
48
+ startAmount: string;
49
+ endAmount: string;
50
+ token: string;
51
+ recipient: string;
52
+ }
53
+ export interface UniswapOrders {
54
+ orders: UniswapOrderInfo[];
55
+ }
56
+ export interface UniswapOrderInfo {
57
+ orderStatus: 'open' | 'expired' | 'error' | 'cancelled' | 'filled' | 'unverified' | 'insufficient-funds';
58
+ orderId: string;
59
+ swapper: string;
60
+ txHash: string;
61
+ }
15
62
  export declare class UniswapHandler implements SwapBaseInterface {
16
63
  private swapBaseHandler;
17
64
  transactionService: TransactionService;
@@ -44,3 +91,4 @@ export declare class UniswapHandler implements SwapBaseInterface {
44
91
  };
45
92
  validateSwapProcessV2(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
46
93
  }
94
+ export {};