@subwallet/extension-base 1.3.62-0 → 1.3.64-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 (72) hide show
  1. package/cjs/koni/api/staking/bonding/utils.js +6 -0
  2. package/cjs/packageInfo.js +1 -1
  3. package/cjs/services/balance-service/transfer/smart-contract.js +14 -10
  4. package/cjs/services/balance-service/transfer/xcm/acrossBridge/index.js +0 -6
  5. package/cjs/services/balance-service/transfer/xcm/utils.js +2 -0
  6. package/cjs/services/chain-service/constants.js +16 -0
  7. package/cjs/services/chain-service/utils/index.js +24 -4
  8. package/cjs/services/chain-service/utils/patch.js +1 -1
  9. package/cjs/services/earning-service/constants/chains.js +2 -1
  10. package/cjs/services/earning-service/handlers/native-staking/base-para.js +6 -3
  11. package/cjs/services/earning-service/handlers/native-staking/energy.js +60 -6
  12. package/cjs/services/earning-service/handlers/native-staking/tanssi.js +496 -0
  13. package/cjs/services/earning-service/service.js +4 -0
  14. package/cjs/services/earning-service/utils/index.js +2 -0
  15. package/cjs/services/migration-service/scripts/MigrateTransactionHistoryBySymbol20251027.js +51 -0
  16. package/cjs/services/migration-service/scripts/databases/MigrateAssetSetting20251027.js +37 -0
  17. package/cjs/services/migration-service/scripts/index.js +5 -1
  18. package/cjs/services/swap-service/handler/base-handler.js +4 -1
  19. package/cjs/services/swap-service/handler/chainflip-handler.js +1 -17
  20. package/cjs/services/swap-service/handler/optimex-handler.js +421 -0
  21. package/cjs/services/swap-service/handler/simpleswap-handler.js +4 -2
  22. package/cjs/services/swap-service/index.js +38 -140
  23. package/cjs/services/swap-service/utils.js +16 -157
  24. package/cjs/services/transaction-service/helpers/index.js +2 -1
  25. package/cjs/types/service-base.js +0 -1
  26. package/cjs/types/swap/index.js +5 -8
  27. package/cjs/utils/account/common.js +1 -2
  28. package/koni/api/staking/bonding/utils.d.ts +1 -0
  29. package/koni/api/staking/bonding/utils.js +5 -0
  30. package/package.json +26 -6
  31. package/packageInfo.js +1 -1
  32. package/services/balance-service/transfer/smart-contract.d.ts +3 -2
  33. package/services/balance-service/transfer/smart-contract.js +35 -29
  34. package/services/balance-service/transfer/xcm/acrossBridge/index.d.ts +0 -4
  35. package/services/balance-service/transfer/xcm/acrossBridge/index.js +0 -4
  36. package/services/balance-service/transfer/xcm/utils.js +2 -0
  37. package/services/chain-service/constants.js +16 -0
  38. package/services/chain-service/utils/index.d.ts +3 -2
  39. package/services/chain-service/utils/index.js +20 -1
  40. package/services/chain-service/utils/patch.d.ts +1 -1
  41. package/services/chain-service/utils/patch.js +1 -1
  42. package/services/earning-service/constants/chains.d.ts +1 -0
  43. package/services/earning-service/constants/chains.js +2 -1
  44. package/services/earning-service/handlers/native-staking/base-para.js +6 -3
  45. package/services/earning-service/handlers/native-staking/energy.d.ts +6 -0
  46. package/services/earning-service/handlers/native-staking/energy.js +60 -8
  47. package/services/earning-service/handlers/native-staking/tanssi.d.ts +16 -0
  48. package/services/earning-service/handlers/native-staking/tanssi.js +478 -0
  49. package/services/earning-service/service.js +4 -0
  50. package/services/earning-service/utils/index.js +2 -0
  51. package/services/migration-service/scripts/MigrateTransactionHistoryBySymbol20251027.d.ts +4 -0
  52. package/services/migration-service/scripts/MigrateTransactionHistoryBySymbol20251027.js +42 -0
  53. package/services/migration-service/scripts/databases/MigrateAssetSetting20251027.d.ts +4 -0
  54. package/services/migration-service/scripts/databases/MigrateAssetSetting20251027.js +29 -0
  55. package/services/migration-service/scripts/index.js +5 -1
  56. package/services/swap-service/handler/base-handler.js +6 -3
  57. package/services/swap-service/handler/chainflip-handler.d.ts +0 -2
  58. package/services/swap-service/handler/chainflip-handler.js +2 -18
  59. package/services/swap-service/handler/optimex-handler.d.ts +43 -0
  60. package/services/swap-service/handler/optimex-handler.js +410 -0
  61. package/services/swap-service/handler/simpleswap-handler.js +5 -3
  62. package/services/swap-service/index.d.ts +0 -1
  63. package/services/swap-service/index.js +21 -123
  64. package/services/swap-service/utils.d.ts +6 -12
  65. package/services/swap-service/utils.js +8 -138
  66. package/services/transaction-service/helpers/index.js +2 -1
  67. package/types/service-base.d.ts +3 -4
  68. package/types/service-base.js +0 -2
  69. package/types/swap/index.d.ts +3 -1
  70. package/types/swap/index.js +7 -6
  71. package/types/yield/info/account/info.d.ts +5 -0
  72. package/utils/account/common.js +2 -3
@@ -1,13 +1,12 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { COMMON_ASSETS } from '@subwallet/chain-list';
5
4
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
6
5
  import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
7
6
  import { createBitcoinTransaction } from '@subwallet/extension-base/services/balance-service/transfer/bitcoin-transfer';
8
7
  import { getERC20TransactionObject, getEVMTransactionObject } from '@subwallet/extension-base/services/balance-service/transfer/smart-contract';
9
8
  import { createSubstrateExtrinsic } from '@subwallet/extension-base/services/balance-service/transfer/token';
10
- import { _getContractAddressOfToken, _isChainSubstrateCompatible, _isNativeToken, _isPureBitcoinChain } from '@subwallet/extension-base/services/chain-service/utils';
9
+ import { _chainInfoToChainType, _getContractAddressOfToken, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
11
10
  import { SwapBaseHandler } from '@subwallet/extension-base/services/swap-service/handler/base-handler';
12
11
  import { BasicTxErrorType, CommonStepType, DynamicSwapType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
13
12
  import { ProxyServiceRoute } from '@subwallet/extension-base/types/environment';
@@ -15,12 +14,7 @@ import { _reformatAddressWithChain, fetchFromProxyService } from '@subwallet/ext
15
14
  import { getId } from '@subwallet/extension-base/utils/getId';
16
15
  import BigNumber from 'bignumber.js';
17
16
  import * as bitcoin from 'bitcoinjs-lib';
18
- const INTERMEDIARY_MAINNET_ASSET_SLUG = COMMON_ASSETS.USDC_ETHEREUM;
19
- const INTERMEDIARY_TESTNET_ASSET_SLUG = COMMON_ASSETS.USDC_SEPOLIA;
20
17
  export class ChainflipSwapHandler {
21
- // private baseUrl: string;
22
- // private assetsUrl: string;
23
-
24
18
  constructor(chainService, balanceService, feeService, isTestnet = true) {
25
19
  this.swapBaseHandler = new SwapBaseHandler({
26
20
  chainService,
@@ -31,10 +25,7 @@ export class ChainflipSwapHandler {
31
25
  });
32
26
  this.isTestnet = isTestnet;
33
27
  this.providerSlug = isTestnet ? SwapProviderId.CHAIN_FLIP_TESTNET : SwapProviderId.CHAIN_FLIP_MAINNET;
34
- // this.baseUrl = getChainflipSwap(isTestnet);
35
- // this.assetsUrl = getAssetsUrl(isTestnet);
36
28
  }
37
-
38
29
  get chainService() {
39
30
  return this.swapBaseHandler.chainService;
40
31
  }
@@ -50,13 +41,6 @@ export class ChainflipSwapHandler {
50
41
  get slug() {
51
42
  return this.swapBaseHandler.slug;
52
43
  }
53
- get intermediaryAssetSlug() {
54
- if (this.isTestnet) {
55
- return INTERMEDIARY_TESTNET_ASSET_SLUG;
56
- } else {
57
- return INTERMEDIARY_MAINNET_ASSET_SLUG;
58
- }
59
- }
60
44
  async handleSubmitStep(params) {
61
45
  const {
62
46
  address,
@@ -70,7 +54,7 @@ export class ChainflipSwapHandler {
70
54
  const fromAsset = this.chainService.getAssetBySlug(pair.from);
71
55
  const chainInfo = this.chainService.getChainInfoByKey(fromAsset.originChain);
72
56
  const toChainInfo = this.chainService.getChainInfoByKey(fromAsset.originChain);
73
- const chainType = _isChainSubstrateCompatible(chainInfo) ? ChainType.SUBSTRATE : _isPureBitcoinChain(chainInfo) ? ChainType.BITCOIN : ChainType.EVM; // todo: improve throw error for unknown chain
57
+ const chainType = _chainInfoToChainType(chainInfo);
74
58
  const receiver = _reformatAddressWithChain(recipient !== null && recipient !== void 0 ? recipient : address, toChainInfo);
75
59
  const minReceive = new BigNumber(quote.rate).times(1 - slippage).toString();
76
60
  const processMetadata = process.steps[currentStep].metadata;
@@ -0,0 +1,43 @@
1
+ import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
2
+ import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
3
+ import { BalanceService } from '@subwallet/extension-base/services/balance-service';
4
+ import { ChainService } from '@subwallet/extension-base/services/chain-service';
5
+ import FeeService from '@subwallet/extension-base/services/fee-service/service';
6
+ import { SwapBaseInterface } from '@subwallet/extension-base/services/swap-service/handler/base-handler';
7
+ import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo, OptimalSwapPathParamsV2, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types';
8
+ interface OptimexTradeMetadata {
9
+ trade_id: string;
10
+ deposit_address: string;
11
+ payload: string;
12
+ need_approve: boolean;
13
+ approve_address: string;
14
+ approve_payload: string;
15
+ }
16
+ export declare class OptimexHandler implements SwapBaseInterface {
17
+ private readonly baseUrl;
18
+ private currentTradeMetadata;
19
+ private swapBaseHandler;
20
+ private isTestnet;
21
+ providerSlug: SwapProviderId;
22
+ constructor(chainService: ChainService, balanceService: BalanceService, feeService: FeeService, isTestnet?: boolean);
23
+ get chainService(): ChainService;
24
+ get providerInfo(): import("@subwallet/extension-base/types").SwapProvider;
25
+ get name(): string;
26
+ get slug(): string;
27
+ generateOptimalProcessV2(params: OptimalSwapPathParamsV2): Promise<CommonOptimalSwapPath>;
28
+ initTrade(request: OptimalSwapPathParamsV2): Promise<OptimexTradeMetadata | undefined>;
29
+ getApprovalStep(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
30
+ getSubmitStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
31
+ validateSwapProcessV2(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
32
+ handleSwapProcess(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
33
+ handleApproveStep(params: SwapSubmitParams): {
34
+ txChain: string;
35
+ txData: string;
36
+ extrinsic: {};
37
+ extrinsicType: ExtrinsicType;
38
+ transferNativeAmount: string;
39
+ chainType: ChainType;
40
+ };
41
+ handleSubmitStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
42
+ }
43
+ export {};
@@ -0,0 +1,410 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
5
+ import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
6
+ import { estimateTxFee } from '@subwallet/extension-base/koni/api/contract-handler/evm/web3';
7
+ import { createBitcoinTransaction } from '@subwallet/extension-base/services/balance-service/transfer/bitcoin-transfer';
8
+ import { getERC20TransactionObject, getEVMTransactionObject } from '@subwallet/extension-base/services/balance-service/transfer/smart-contract';
9
+ import { _chainInfoToChainType, _getChainNativeTokenSlug, _getContractAddressOfToken, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
10
+ import { SwapBaseHandler } from '@subwallet/extension-base/services/swap-service/handler/base-handler';
11
+ import { getAmountAfterSlippage } from '@subwallet/extension-base/services/swap-service/utils';
12
+ import { BasicTxErrorType, CommonStepType, DynamicSwapType, SwapFeeType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
13
+ import { _reformatAddressWithChain, combineBitcoinFee, getSizeInfo } from '@subwallet/extension-base/utils';
14
+ import { getId } from '@subwallet/extension-base/utils/getId';
15
+ import keyring from '@subwallet/ui-keyring';
16
+ import BigNumber from 'bignumber.js';
17
+ import * as bitcoin from 'bitcoinjs-lib';
18
+ import { hexStripPrefix, u8aToHex } from '@polkadot/util';
19
+ const OptimexBaseUrl = {
20
+ mainnet: 'https://subwallet-provider.optimex.xyz',
21
+ testnet: 'https://provider-stg.bitdex.xyz'
22
+ };
23
+ export class OptimexHandler {
24
+ constructor(chainService, balanceService, feeService, isTestnet = true) {
25
+ this.swapBaseHandler = new SwapBaseHandler({
26
+ chainService,
27
+ balanceService,
28
+ feeService,
29
+ providerName: isTestnet ? 'Optimex Testnet' : 'Optimex',
30
+ providerSlug: isTestnet ? SwapProviderId.OPTIMEX_TESTNET : SwapProviderId.OPTIMEX
31
+ });
32
+ this.providerSlug = isTestnet ? SwapProviderId.OPTIMEX_TESTNET : SwapProviderId.OPTIMEX;
33
+ this.baseUrl = isTestnet ? OptimexBaseUrl.testnet : OptimexBaseUrl.mainnet;
34
+ this.isTestnet = isTestnet;
35
+ }
36
+ get chainService() {
37
+ return this.swapBaseHandler.chainService;
38
+ }
39
+ get providerInfo() {
40
+ return this.swapBaseHandler.providerInfo;
41
+ }
42
+ get name() {
43
+ return this.swapBaseHandler.name;
44
+ }
45
+ get slug() {
46
+ return this.swapBaseHandler.slug;
47
+ }
48
+ async generateOptimalProcessV2(params) {
49
+ const tradeMetadata = await this.initTrade(params);
50
+ if (!tradeMetadata) {
51
+ throw new Error('Error generating optimal process: Cannot init Optimex trade');
52
+ }
53
+ const isNeedApprove = tradeMetadata.need_approve;
54
+ this.currentTradeMetadata = tradeMetadata;
55
+ if (!isNeedApprove) {
56
+ return this.swapBaseHandler.generateOptimalProcessV2(params, [this.getSubmitStep.bind(this)]);
57
+ }
58
+ if (!tradeMetadata.approve_address || !tradeMetadata.approve_payload) {
59
+ throw new Error('Error generating optimal process: Lack of approve info');
60
+ }
61
+ return this.swapBaseHandler.generateOptimalProcessV2(params, [this.getApprovalStep.bind(this), this.getSubmitStep.bind(this)]);
62
+ }
63
+ async initTrade(request) {
64
+ var _request$selectedQuot, _request$selectedQuot2;
65
+ const pair = request.request.pair;
66
+ const fromAsset = this.chainService.getAssetBySlug(pair.from);
67
+ const fromChain = this.chainService.getChainInfoByKey(fromAsset.originChain);
68
+ const fromChainType = _chainInfoToChainType(fromChain);
69
+ const sender = request.request.address;
70
+ const receiver = request.request.recipient;
71
+ const sendingValue = request.request.fromAmount;
72
+ const slippage = request.request.slippage;
73
+ const metadata = (_request$selectedQuot = request.selectedQuote) === null || _request$selectedQuot === void 0 ? void 0 : _request$selectedQuot.metadata;
74
+ const walletFeeInfo = (_request$selectedQuot2 = request.selectedQuote) === null || _request$selectedQuot2 === void 0 ? void 0 : _request$selectedQuot2.feeInfo.feeComponent.find(fee => fee.feeType === SwapFeeType.WALLET_FEE);
75
+ if (!metadata || !walletFeeInfo) {
76
+ return undefined;
77
+ }
78
+ let initTradeRequest;
79
+ const swAffiliate = walletFeeInfo.metadata;
80
+ if (fromChainType === ChainType.EVM) {
81
+ initTradeRequest = {
82
+ session_id: metadata.session_id,
83
+ amount_in: sendingValue,
84
+ from_user_address: sender,
85
+ // compressPublicKey for BTC and SOLANA, address for EVM
86
+ to_user_address: receiver || '',
87
+ // Receiving address
88
+ user_refund_address: sender,
89
+ // Refund address if trade fails
90
+ user_refund_pubkey: sender,
91
+ // Refund pubkey if trade fails, in btc is pubkey and in evm is address
92
+ creator_public_key: sender,
93
+ // Compressed public key, in btc is pubkey and in evm is address
94
+ from_wallet_address: sender,
95
+ // Creator address
96
+ min_amount_out: getAmountAfterSlippage(metadata.best_quote_after_fees, slippage),
97
+ affiliate_info: [swAffiliate]
98
+ };
99
+ } else if (fromChainType === ChainType.BITCOIN) {
100
+ const fromPublicKey = hexStripPrefix(u8aToHex(keyring.getPair(sender).publicKey));
101
+ initTradeRequest = {
102
+ session_id: metadata.session_id,
103
+ amount_in: sendingValue,
104
+ from_user_address: fromPublicKey,
105
+ to_user_address: receiver || '',
106
+ user_refund_address: sender,
107
+ user_refund_pubkey: fromPublicKey,
108
+ creator_public_key: fromPublicKey,
109
+ from_wallet_address: sender,
110
+ min_amount_out: getAmountAfterSlippage(metadata.best_quote_after_fees, slippage),
111
+ affiliate_info: [swAffiliate]
112
+ };
113
+ } else {
114
+ return undefined;
115
+ }
116
+ let tradeInfo;
117
+ try {
118
+ const rawResponse = await fetch(`${this.baseUrl}/v1/trades/initiate`, {
119
+ method: 'POST',
120
+ body: JSON.stringify(initTradeRequest),
121
+ headers: {
122
+ 'Content-Type': 'application/json'
123
+ }
124
+ });
125
+ if (!rawResponse.ok) {
126
+ console.log('Error bad request while init quote');
127
+ return undefined;
128
+ }
129
+ const response = await rawResponse.json();
130
+ tradeInfo = response.data;
131
+ } catch (e) {
132
+ console.log('Error while init quote');
133
+ return undefined;
134
+ }
135
+ return tradeInfo;
136
+ }
137
+ async getApprovalStep(params) {
138
+ // todo: handle this when support route has approve step
139
+ // const selectedQuote = params.selectedQuote;
140
+ //
141
+ // if (selectedQuote) {
142
+ // const metadata = selectedQuote.metadata as OptimexMetadata;
143
+ // }
144
+
145
+ return Promise.resolve(undefined);
146
+ }
147
+ async getSubmitStep(params, stepIndex) {
148
+ var _this$currentTradeMet;
149
+ if (!params.selectedQuote) {
150
+ return Promise.resolve(undefined);
151
+ }
152
+ const originTokenInfo = this.chainService.getAssetBySlug(params.selectedQuote.pair.from);
153
+ const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
154
+ const destinationTokenInfo = this.chainService.getAssetBySlug(params.selectedQuote.pair.to);
155
+ const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
156
+ const originChainType = _chainInfoToChainType(originChain);
157
+ const originChainNativeTokenSlug = _getChainNativeTokenSlug(originChain);
158
+
159
+ // Optimex do not return fee in quote. Need calculate network fee manually from client side
160
+ let networkFeeAmount;
161
+ const depositAddress = (_this$currentTradeMet = this.currentTradeMetadata) === null || _this$currentTradeMet === void 0 ? void 0 : _this$currentTradeMet.deposit_address;
162
+ if (!depositAddress) {
163
+ console.log('Optimex Trade metadata is undefined, request for new quote');
164
+ return Promise.resolve(undefined);
165
+ }
166
+ try {
167
+ if (originChainType === ChainType.EVM) {
168
+ const evmApi = this.chainService.getEvmApi(originChain.slug);
169
+ const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(getId(), originChain.slug, 'evm');
170
+ let transactionConfig;
171
+ if (_isNativeToken(originTokenInfo)) {
172
+ var _this$currentTradeMet2;
173
+ [transactionConfig] = await getEVMTransactionObject({
174
+ chain: originChain.slug,
175
+ evmApi,
176
+ from: params.request.address,
177
+ to: depositAddress,
178
+ value: params.request.fromAmount,
179
+ feeInfo,
180
+ transferAll: false,
181
+ fallbackFee: true,
182
+ data: (_this$currentTradeMet2 = this.currentTradeMetadata) === null || _this$currentTradeMet2 === void 0 ? void 0 : _this$currentTradeMet2.payload
183
+ });
184
+ } else {
185
+ [transactionConfig] = await getERC20TransactionObject({
186
+ assetAddress: _getContractAddressOfToken(originTokenInfo),
187
+ chain: originChain.slug,
188
+ evmApi: this.chainService.getEvmApi(originChain.slug),
189
+ from: params.request.address,
190
+ to: depositAddress,
191
+ value: params.request.fromAmount,
192
+ feeInfo,
193
+ transferAll: false
194
+ });
195
+ }
196
+ networkFeeAmount = await estimateTxFee(transactionConfig, evmApi, feeInfo);
197
+ } else if (originChainType === ChainType.BITCOIN) {
198
+ const bitcoinApi = this.chainService.getBitcoinApi(originChain.slug);
199
+ const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(getId(), originChain.slug, 'bitcoin');
200
+ const network = originChain.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
201
+ const [transaction] = await createBitcoinTransaction({
202
+ bitcoinApi,
203
+ chain: originChain.slug,
204
+ from: params.request.address,
205
+ feeInfo,
206
+ to: depositAddress,
207
+ transferAll: false,
208
+ value: params.request.fromAmount,
209
+ network
210
+ });
211
+ const feeCombine = combineBitcoinFee(feeInfo, undefined, undefined); // todo: recheck when implement custom fee
212
+
213
+ const recipients = [];
214
+ for (const txOutput of transaction.txOutputs) {
215
+ txOutput.address && recipients.push(txOutput.address);
216
+ }
217
+ const sizeInfo = getSizeInfo({
218
+ inputLength: transaction.inputCount,
219
+ recipients: recipients,
220
+ sender: params.request.address
221
+ });
222
+ networkFeeAmount = Math.ceil(feeCombine.feeRate * sizeInfo.txVBytes).toString();
223
+ } else {
224
+ console.log('Unsupported swap from this chain type', originChainType);
225
+ return Promise.resolve(undefined);
226
+ }
227
+ } catch (e) {
228
+ throw new Error(e.message);
229
+ }
230
+ const networkFee = {
231
+ amount: networkFeeAmount || '0',
232
+ feeType: SwapFeeType.NETWORK_FEE,
233
+ tokenSlug: originChainNativeTokenSlug
234
+ };
235
+ const submitStep = {
236
+ name: 'Swap',
237
+ type: SwapStepType.SWAP,
238
+ // @ts-ignore
239
+ metadata: {
240
+ sendingValue: params.request.fromAmount.toString(),
241
+ expectedReceive: params.selectedQuote.toAmount,
242
+ originTokenInfo,
243
+ destinationTokenInfo,
244
+ sender: _reformatAddressWithChain(params.request.address, originChain),
245
+ receiver: _reformatAddressWithChain(params.request.recipient || params.request.address, destinationChain),
246
+ version: 2
247
+ }
248
+ };
249
+ const feeInfo = {
250
+ defaultFeeToken: params.selectedQuote.feeInfo.defaultFeeToken,
251
+ feeComponent: [...params.selectedQuote.feeInfo.feeComponent, networkFee],
252
+ feeOptions: params.selectedQuote.feeInfo.feeOptions
253
+ };
254
+ return Promise.resolve([submitStep, feeInfo]);
255
+ }
256
+ async validateSwapProcessV2(params) {
257
+ const {
258
+ process,
259
+ selectedQuote
260
+ } = params;
261
+ if (BigNumber(selectedQuote.fromAmount).lte(0)) {
262
+ return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
263
+ }
264
+ const actionList = JSON.stringify(process.path.map(step => step.action));
265
+ const swap = actionList === JSON.stringify([DynamicSwapType.SWAP]);
266
+ const swapXcm = actionList === JSON.stringify([DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
267
+ const xcmSwap = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP]);
268
+ const xcmSwapXcm = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
269
+ const swapIndex = params.process.steps.findIndex(step => step.type === SwapStepType.SWAP);
270
+ if (swapIndex <= -1) {
271
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
272
+ }
273
+ if (swap) {
274
+ return this.swapBaseHandler.validateSwapOnlyProcess(params, swapIndex);
275
+ }
276
+ if (swapXcm) {
277
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
278
+ }
279
+ if (xcmSwap) {
280
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
281
+ }
282
+ if (xcmSwapXcm) {
283
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
284
+ }
285
+ return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
286
+ }
287
+ async handleSwapProcess(params) {
288
+ const {
289
+ currentStep,
290
+ process
291
+ } = params;
292
+ const type = process.steps[currentStep].type;
293
+ switch (type) {
294
+ case CommonStepType.DEFAULT:
295
+ return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
296
+ case CommonStepType.TOKEN_APPROVAL:
297
+ return this.handleApproveStep(params);
298
+ case SwapStepType.SWAP:
299
+ return this.handleSubmitStep(params);
300
+ default:
301
+ return this.handleSubmitStep(params);
302
+ }
303
+ }
304
+ handleApproveStep(params) {
305
+ // todo: handle this when support route has approve step
306
+ const fromAsset = this.chainService.getAssetBySlug(params.quote.pair.from);
307
+ return {
308
+ txChain: fromAsset.originChain,
309
+ txData: '',
310
+ extrinsic: {},
311
+ extrinsicType: ExtrinsicType.TOKEN_SPENDING_APPROVAL,
312
+ transferNativeAmount: '0',
313
+ chainType: ChainType.EVM
314
+ };
315
+ }
316
+ async handleSubmitStep(params) {
317
+ var _this$currentTradeMet3, _this$currentTradeMet4, _this$currentTradeMet5;
318
+ const {
319
+ address,
320
+ process,
321
+ quote,
322
+ recipient,
323
+ slippage
324
+ } = params;
325
+ const pair = quote.pair;
326
+ const fromAsset = this.chainService.getAssetBySlug(pair.from);
327
+ const chainInfo = this.chainService.getChainInfoByKey(fromAsset.originChain);
328
+ const chainType = _chainInfoToChainType(chainInfo);
329
+ const depositAddress = (_this$currentTradeMet3 = this.currentTradeMetadata) === null || _this$currentTradeMet3 === void 0 ? void 0 : _this$currentTradeMet3.deposit_address;
330
+ const tradeId = (_this$currentTradeMet4 = this.currentTradeMetadata) === null || _this$currentTradeMet4 === void 0 ? void 0 : _this$currentTradeMet4.trade_id;
331
+ const payload = (_this$currentTradeMet5 = this.currentTradeMetadata) === null || _this$currentTradeMet5 === void 0 ? void 0 : _this$currentTradeMet5.payload; // undefined in case swap from btc
332
+
333
+ if (!depositAddress || !tradeId) {
334
+ throw new Error('Optimex Trade metadata is undefined, request for new quote');
335
+ }
336
+ const txData = {
337
+ address,
338
+ provider: this.providerInfo,
339
+ quote,
340
+ slippage,
341
+ recipient,
342
+ process
343
+ };
344
+ let extrinsic;
345
+
346
+ // dont remove this log
347
+ console.log('Optimex Trade metadata:', this.currentTradeMetadata);
348
+ console.log('Optimex Trade channel:', this.isTestnet ? `https://provider-api-docs.vercel.app/swap/${tradeId}` : `https://provider-api-docs.vercel.app/swap/${tradeId}?env=sub_wallet`);
349
+ if (chainType === ChainType.BITCOIN) {
350
+ const bitcoinApi = this.chainService.getBitcoinApi(chainInfo.slug);
351
+ const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(getId(), chainInfo.slug, 'bitcoin');
352
+ const network = chainInfo.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
353
+ const [transaction] = await createBitcoinTransaction({
354
+ bitcoinApi,
355
+ chain: chainInfo.slug,
356
+ from: address,
357
+ feeInfo,
358
+ to: depositAddress,
359
+ transferAll: false,
360
+ value: quote.fromAmount,
361
+ network
362
+ });
363
+ extrinsic = transaction;
364
+ } else if (chainType === ChainType.EVM) {
365
+ const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(getId(), chainInfo.slug, 'evm');
366
+ if (_isNativeToken(fromAsset)) {
367
+ const [transactionConfig] = await getEVMTransactionObject({
368
+ chain: chainInfo.slug,
369
+ evmApi: this.chainService.getEvmApi(chainInfo.slug),
370
+ from: address,
371
+ to: depositAddress,
372
+ value: quote.fromAmount,
373
+ feeInfo,
374
+ transferAll: false,
375
+ data: payload
376
+ });
377
+ extrinsic = {
378
+ ...transactionConfig,
379
+ data: payload
380
+ };
381
+ } else {
382
+ const [transactionConfig] = await getERC20TransactionObject({
383
+ assetAddress: _getContractAddressOfToken(fromAsset),
384
+ chain: chainInfo.slug,
385
+ evmApi: this.chainService.getEvmApi(chainInfo.slug),
386
+ from: address,
387
+ to: depositAddress,
388
+ value: quote.fromAmount,
389
+ feeInfo,
390
+ transferAll: false
391
+ });
392
+ extrinsic = transactionConfig;
393
+ }
394
+ } else {
395
+ throw new Error('Unknown swap chain type');
396
+ }
397
+
398
+ // reset tradeMetadata after use // todo: review to check if need this clear
399
+ // this.currentTradeMetadata = undefined;
400
+
401
+ return {
402
+ txChain: fromAsset.originChain,
403
+ txData,
404
+ extrinsic,
405
+ transferNativeAmount: _isNativeToken(fromAsset) ? quote.fromAmount : '0',
406
+ extrinsicType: ExtrinsicType.SWAP,
407
+ chainType
408
+ };
409
+ }
410
+ }
@@ -4,7 +4,7 @@
4
4
  import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
5
5
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
6
6
  import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
7
- import { _getAssetDecimals, _getAssetSymbol, _getContractAddressOfToken, _isChainSubstrateCompatible, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
7
+ import { _chainInfoToChainType, _getAssetDecimals, _getAssetSymbol, _getContractAddressOfToken, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
8
8
  import { BasicTxErrorType, CommonStepType, DynamicSwapType, SwapErrorType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
9
9
  import { ProxyServiceRoute } from '@subwallet/extension-base/types/environment';
10
10
  import { _reformatAddressWithChain, fetchFromProxyService, formatNumber } from '@subwallet/extension-base/utils';
@@ -159,7 +159,7 @@ export class SimpleSwapHandler {
159
159
  const toAsset = this.chainService.getAssetBySlug(pair.to);
160
160
  const chainInfo = this.chainService.getChainInfoByKey(fromAsset.originChain);
161
161
  const toChainInfo = this.chainService.getChainInfoByKey(toAsset.originChain);
162
- const chainType = _isChainSubstrateCompatible(chainInfo) ? ChainType.SUBSTRATE : ChainType.EVM;
162
+ const chainType = _chainInfoToChainType(chainInfo);
163
163
  const sender = _reformatAddressWithChain(address, chainInfo);
164
164
  const receiver = _reformatAddressWithChain(recipient !== null && recipient !== void 0 ? recipient : sender, toChainInfo);
165
165
  const fromSymbol = _getAssetSymbol(fromAsset).toLowerCase();
@@ -222,7 +222,7 @@ export class SimpleSwapHandler {
222
222
  value: quote.fromAmount
223
223
  });
224
224
  extrinsic = submittableExtrinsic;
225
- } else {
225
+ } else if (chainType === ChainType.EVM) {
226
226
  const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(getId(), chainInfo.slug, 'evm');
227
227
  if (_isNativeToken(fromAsset)) {
228
228
  const [transactionConfig] = await getEVMTransactionObject({
@@ -248,6 +248,8 @@ export class SimpleSwapHandler {
248
248
  });
249
249
  extrinsic = transactionConfig;
250
250
  }
251
+ } else {
252
+ throw new Error('Unknown swap chain type');
251
253
  }
252
254
  return {
253
255
  txChain: fromAsset.originChain,
@@ -19,7 +19,6 @@ export declare class SwapService implements StoppableServiceInterface {
19
19
  private getDefaultProcessV2;
20
20
  generateOptimalProcessV2(params: OptimalSwapPathParamsV2): Promise<CommonOptimalSwapPath>;
21
21
  handleSwapRequestV2(request: SwapRequestV2): Promise<SwapRequestResult>;
22
- getAvailablePath(request: SwapRequestV2): [DynamicSwapAction[], SwapRequestV2 | undefined];
23
22
  getLatestQuoteFromSwapRequest(request: SwapRequestV2): Promise<{
24
23
  path: DynamicSwapAction[];
25
24
  swapQuoteResponse: SwapQuoteResponse;