@subwallet/extension-base 1.3.10-0 → 1.3.11-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/errors/SwapError.js +5 -0
  2. package/cjs/background/errors/SwapError.js +5 -0
  3. package/cjs/core/logic-validation/swap.js +27 -0
  4. package/cjs/packageInfo.js +1 -1
  5. package/cjs/services/chain-service/utils/patch.js +1 -1
  6. package/cjs/services/swap-service/handler/chainflip-handler.js +0 -1
  7. package/cjs/services/swap-service/handler/simpleswap-handler.js +444 -0
  8. package/cjs/services/swap-service/index.js +15 -3
  9. package/cjs/services/swap-service/utils.js +13 -2
  10. package/cjs/services/transaction-service/index.js +14 -10
  11. package/cjs/services/transaction-service/utils.js +9 -1
  12. package/cjs/types/swap/index.js +7 -3
  13. package/cjs/utils/number.js +11 -6
  14. package/core/logic-validation/swap.d.ts +2 -1
  15. package/core/logic-validation/swap.js +26 -0
  16. package/package.json +11 -6
  17. package/packageInfo.js +1 -1
  18. package/services/chain-service/utils/patch.js +1 -1
  19. package/services/swap-service/handler/chainflip-handler.js +0 -1
  20. package/services/swap-service/handler/simpleswap-handler.d.ts +24 -0
  21. package/services/swap-service/handler/simpleswap-handler.js +434 -0
  22. package/services/swap-service/index.d.ts +2 -1
  23. package/services/swap-service/index.js +13 -2
  24. package/services/swap-service/utils.d.ts +2 -0
  25. package/services/swap-service/utils.js +10 -1
  26. package/services/transaction-service/index.js +15 -11
  27. package/services/transaction-service/utils.d.ts +2 -1
  28. package/services/transaction-service/utils.js +9 -2
  29. package/types/swap/index.d.ts +15 -3
  30. package/types/swap/index.js +5 -2
  31. package/utils/number.d.ts +9 -1
  32. package/utils/number.js +10 -4
@@ -47,6 +47,11 @@ const defaultErrorMap = {
47
47
  MAKE_POOL_NOT_ENOUGH_EXISTENTIAL_DEPOSIT: {
48
48
  message: detectTranslate('Insufficient liquidity to complete the swap. Lower your amount and try again'),
49
49
  code: undefined
50
+ },
51
+ NOT_MEET_MIN_EXPECTED: {
52
+ // TODO: update message
53
+ message: detectTranslate('Unable to process this swap at the moment. Try again later'),
54
+ code: undefined
50
55
  }
51
56
  };
52
57
  export class SwapError extends SWError {
@@ -53,6 +53,11 @@ const defaultErrorMap = {
53
53
  MAKE_POOL_NOT_ENOUGH_EXISTENTIAL_DEPOSIT: {
54
54
  message: (0, _utils.detectTranslate)('Insufficient liquidity to complete the swap. Lower your amount and try again'),
55
55
  code: undefined
56
+ },
57
+ NOT_MEET_MIN_EXPECTED: {
58
+ // TODO: update message
59
+ message: (0, _utils.detectTranslate)('Unable to process this swap at the moment. Try again later'),
60
+ code: undefined
56
61
  }
57
62
  };
58
63
  class SwapError extends _SWError.SWError {
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports._getChainflipEarlyValidationError = _getChainflipEarlyValidationError;
8
8
  exports._getEarlyAssetHubValidationError = _getEarlyAssetHubValidationError;
9
9
  exports._getEarlyHydradxValidationError = _getEarlyHydradxValidationError;
10
+ exports._getSimpleSwapEarlyValidationError = _getSimpleSwapEarlyValidationError;
10
11
  exports._validateBalanceToSwap = _validateBalanceToSwap;
11
12
  exports._validateBalanceToSwapOnAssetHub = _validateBalanceToSwapOnAssetHub;
12
13
  exports._validateSwapRecipient = _validateSwapRecipient;
@@ -149,4 +150,30 @@ function _getEarlyAssetHubValidationError(error, metadata) {
149
150
  default:
150
151
  return new _SwapError.SwapError(error);
151
152
  }
153
+ }
154
+ function _getSimpleSwapEarlyValidationError(error, metadata) {
155
+ // todo: support more providers
156
+ switch (error) {
157
+ case _swap.SwapErrorType.NOT_MEET_MIN_SWAP:
158
+ {
159
+ const message = `Amount too low. Increase your amount above ${metadata.minSwap.value} ${metadata.minSwap.symbol} and try again`;
160
+ return new _SwapError.SwapError(error, message);
161
+ }
162
+ case _swap.SwapErrorType.SWAP_EXCEED_ALLOWANCE:
163
+ {
164
+ if (metadata.maxSwap) {
165
+ return new _SwapError.SwapError(error, `Amount too high. Lower your amount below ${metadata.maxSwap.value} ${metadata.maxSwap.symbol} and try again`);
166
+ } else {
167
+ return new _SwapError.SwapError(error, 'Amount too high. Lower your amount and try again');
168
+ }
169
+ }
170
+ case _swap.SwapErrorType.ASSET_NOT_SUPPORTED:
171
+ return new _SwapError.SwapError(error, 'This swap pair is not supported');
172
+ case _swap.SwapErrorType.UNKNOWN:
173
+ return new _SwapError.SwapError(error, `Undefined error. Check your Internet and ${metadata.chain.slug} connection or contact support`);
174
+ case _swap.SwapErrorType.ERROR_FETCHING_QUOTE:
175
+ return new _SwapError.SwapError(error, 'No swap quote found. Adjust your amount or try again later.');
176
+ default:
177
+ return new _SwapError.SwapError(error);
178
+ }
152
179
  }
@@ -13,6 +13,6 @@ const packageInfo = {
13
13
  name: '@subwallet/extension-base',
14
14
  path: typeof __dirname === 'string' ? __dirname : 'auto',
15
15
  type: 'cjs',
16
- version: '1.3.10-0'
16
+ version: '1.3.11-0'
17
17
  };
18
18
  exports.packageInfo = packageInfo;
@@ -11,7 +11,7 @@ const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
11
11
  const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
12
12
  const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
13
13
  const fetchFile = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'list.json' : 'preview.json';
14
- const ChainListVersion = '0.2.95'; // update this when build chainlist
14
+ const ChainListVersion = '0.2.96'; // update this when build chainlist
15
15
 
16
16
  // todo: move this interface to chainlist
17
17
 
@@ -370,7 +370,6 @@ class ChainflipSwapHandler {
370
370
  }
371
371
  });
372
372
 
373
- console.log('depositAddressResp', depositAddressResponse);
374
373
  const txData = {
375
374
  address,
376
375
  provider: this.providerInfo,
@@ -0,0 +1,444 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.simpleSwapApiKey = exports.SimpleSwapHandler = void 0;
7
+ var _SwapError = require("@subwallet/extension-base/background/errors/SwapError");
8
+ var _TransactionError = require("@subwallet/extension-base/background/errors/TransactionError");
9
+ var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
10
+ var _swap = require("@subwallet/extension-base/core/logic-validation/swap");
11
+ var _utils = require("@subwallet/extension-base/services/chain-service/utils");
12
+ var _types = require("@subwallet/extension-base/types");
13
+ var _utils2 = require("@subwallet/extension-base/utils");
14
+ var _bignumber = _interopRequireWildcard(require("bignumber.js"));
15
+ var _smartContract = require("../../balance-service/transfer/smart-contract");
16
+ var _token = require("../../balance-service/transfer/token");
17
+ var _utils3 = require("../utils");
18
+ var _baseHandler = require("./base-handler");
19
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
20
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
21
+ // Copyright 2019-2022 @subwallet/extension-base
22
+ // SPDX-License-Identifier: Apache-2.0
23
+
24
+ const apiUrl = 'https://api.simpleswap.io';
25
+ const simpleSwapApiKey = process.env.SIMPLE_SWAP_API_KEY || '';
26
+ exports.simpleSwapApiKey = simpleSwapApiKey;
27
+ const toBNString = (input, decimal) => {
28
+ const raw = new _bignumber.BigNumber(input);
29
+ return raw.shiftedBy(decimal).integerValue(_bignumber.BigNumber.ROUND_CEIL).toFixed();
30
+ };
31
+ const fetchSwapList = async params => {
32
+ const swapListParams = new URLSearchParams({
33
+ api_key: `${simpleSwapApiKey}`,
34
+ fixed: 'false',
35
+ symbol: params.fromSymbol
36
+ });
37
+ const response = await fetch(`${apiUrl}/get_pairs?${swapListParams.toString()}`, {
38
+ headers: {
39
+ accept: 'application/json'
40
+ }
41
+ });
42
+ return await response.json();
43
+ };
44
+ const fetchRanges = async params => {
45
+ const rangesParams = new URLSearchParams({
46
+ api_key: `${simpleSwapApiKey}`,
47
+ fixed: 'false',
48
+ currency_from: params.fromSymbol,
49
+ currency_to: params.toSymbol
50
+ });
51
+ const response = await fetch(`${apiUrl}/get_ranges?${rangesParams.toString()}`, {
52
+ headers: {
53
+ accept: 'application/json'
54
+ }
55
+ });
56
+ return await response.json();
57
+ };
58
+ async function getEstimate(request, fromAsset, toAsset) {
59
+ const fromSymbol = _utils3.SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING[fromAsset.slug];
60
+ const toSymbol = _utils3.SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING[toAsset.slug];
61
+ const assetDecimals = (0, _utils._getAssetDecimals)(fromAsset);
62
+ if (!fromSymbol || !toSymbol) {
63
+ throw new _SwapError.SwapError(_types.SwapErrorType.ASSET_NOT_SUPPORTED);
64
+ }
65
+ const formatedAmount = (0, _utils2.formatNumber)(request.fromAmount, assetDecimals, s => s);
66
+ const params = new URLSearchParams({
67
+ api_key: `${simpleSwapApiKey}`,
68
+ fixed: 'false',
69
+ currency_from: fromSymbol,
70
+ currency_to: toSymbol,
71
+ amount: formatedAmount
72
+ });
73
+ try {
74
+ const response = await fetch(`${apiUrl}/get_estimated?${params.toString()}`, {
75
+ headers: {
76
+ accept: 'application/json'
77
+ }
78
+ });
79
+ if (!response.ok) {
80
+ throw new _SwapError.SwapError(_types.SwapErrorType.ERROR_FETCHING_QUOTE);
81
+ }
82
+ const resToAmount = await response.json();
83
+ const toAmount = toBNString(resToAmount, (0, _utils._getAssetDecimals)(toAsset));
84
+ const bnToAmount = new _bignumber.default(toAmount);
85
+ const walletFeeRate = 4 / 1000;
86
+ const toAmountBeforeFee = bnToAmount.dividedBy(new _bignumber.default(1 - walletFeeRate));
87
+ const walletFeeAmount = toAmountBeforeFee.multipliedBy(4).dividedBy(1000).toString();
88
+ return {
89
+ toAmount,
90
+ walletFeeAmount
91
+ };
92
+ } catch (err) {
93
+ console.error('Error:', err);
94
+ throw new _SwapError.SwapError(_types.SwapErrorType.ERROR_FETCHING_QUOTE);
95
+ }
96
+ }
97
+ const createSwapRequest = async params => {
98
+ const fromDecimals = (0, _utils._getAssetDecimals)(params.fromAsset);
99
+ const toDecimals = (0, _utils._getAssetDecimals)(params.toAsset);
100
+ const formatedAmount = (0, _utils2.formatNumber)(params.fromAmount, fromDecimals, s => s);
101
+ const requestBody = {
102
+ fixed: false,
103
+ currency_from: params.fromSymbol,
104
+ currency_to: params.toSymbol,
105
+ amount: formatedAmount,
106
+ // Convert to small number due to require of api
107
+ address_to: params.receiver,
108
+ extra_id_to: '',
109
+ user_refund_address: params.sender,
110
+ user_refund_extra_id: ''
111
+ };
112
+ const response = await fetch(`${apiUrl}/create_exchange?api_key=${simpleSwapApiKey}`, {
113
+ method: 'POST',
114
+ headers: {
115
+ 'Content-Type': 'application/json',
116
+ Accept: 'application/json'
117
+ },
118
+ body: JSON.stringify(requestBody)
119
+ });
120
+ const depositAddressResponse = await response.json();
121
+ return {
122
+ id: depositAddressResponse.id,
123
+ addressFrom: depositAddressResponse.address_from,
124
+ amountTo: toBNString(depositAddressResponse.amount_to, toDecimals)
125
+ };
126
+ };
127
+ class SimpleSwapHandler {
128
+ constructor(chainService, balanceService) {
129
+ this.swapBaseHandler = new _baseHandler.SwapBaseHandler({
130
+ chainService,
131
+ balanceService,
132
+ providerName: 'SimpleSwap',
133
+ providerSlug: _types.SwapProviderId.SIMPLE_SWAP
134
+ });
135
+ this.providerSlug = _types.SwapProviderId.SIMPLE_SWAP;
136
+ }
137
+ async validateSwapProcess(params) {
138
+ const amount = params.selectedQuote.fromAmount;
139
+ const bnAmount = BigInt(amount);
140
+ if (bnAmount <= BigInt(0)) {
141
+ return Promise.resolve([new _TransactionError.TransactionError(_types.BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')]);
142
+ }
143
+ let isXcmOk = false;
144
+ for (const [index, step] of params.process.steps.entries()) {
145
+ const getErrors = async () => {
146
+ switch (step.type) {
147
+ case _types.CommonStepType.DEFAULT:
148
+ return Promise.resolve([]);
149
+ case _types.CommonStepType.TOKEN_APPROVAL:
150
+ return Promise.reject(new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED));
151
+ default:
152
+ return this.swapBaseHandler.validateSwapStep(params, isXcmOk, index);
153
+ }
154
+ };
155
+ const errors = await getErrors();
156
+ if (errors.length) {
157
+ return errors;
158
+ } else if (step.type === _types.CommonStepType.XCM) {
159
+ isXcmOk = true;
160
+ }
161
+ }
162
+ return [];
163
+ }
164
+ get chainService() {
165
+ return this.swapBaseHandler.chainService;
166
+ }
167
+ get balanceService() {
168
+ return this.swapBaseHandler.balanceService;
169
+ }
170
+ get providerInfo() {
171
+ return this.swapBaseHandler.providerInfo;
172
+ }
173
+ get name() {
174
+ return this.swapBaseHandler.name;
175
+ }
176
+ get slug() {
177
+ return this.swapBaseHandler.slug;
178
+ }
179
+ async getSwapQuote(request) {
180
+ try {
181
+ var _metadata$maxSwap;
182
+ const fromAsset = this.chainService.getAssetBySlug(request.pair.from);
183
+ const toAsset = this.chainService.getAssetBySlug(request.pair.to);
184
+ if (!fromAsset || !toAsset) {
185
+ return new _SwapError.SwapError(_types.SwapErrorType.UNKNOWN);
186
+ }
187
+ const earlyValidation = await this.validateSwapRequest(request);
188
+ const metadata = earlyValidation.metadata;
189
+ if (earlyValidation.error) {
190
+ return (0, _swap._getSimpleSwapEarlyValidationError)(earlyValidation.error, metadata);
191
+ }
192
+ const {
193
+ toAmount,
194
+ walletFeeAmount
195
+ } = await getEstimate(request, fromAsset, toAsset);
196
+ const fromAmount = request.fromAmount;
197
+ const rate = (0, _utils3.calculateSwapRate)(request.fromAmount, toAmount, fromAsset, toAsset);
198
+ const fromChain = this.chainService.getChainInfoByKey(fromAsset.originChain);
199
+ const fromChainNativeTokenSlug = (0, _utils._getChainNativeTokenSlug)(fromChain);
200
+ const defaultFeeToken = (0, _utils._isNativeToken)(fromAsset) ? fromAsset.slug : fromChainNativeTokenSlug;
201
+ const chainType = (0, _utils._isChainSubstrateCompatible)(fromChain) ? _KoniTypes.ChainType.SUBSTRATE : _KoniTypes.ChainType.EVM;
202
+ let api;
203
+ if (chainType === _KoniTypes.ChainType.SUBSTRATE) {
204
+ api = this.chainService.getSubstrateApi(fromChain.slug);
205
+ } else {
206
+ api = this.chainService.getEvmApi(fromChain.slug);
207
+ }
208
+ const networkFeeAmount = await (0, _token.getTransferMockTxFee)(request.address, fromChain, fromAsset, api);
209
+ const networkFee = {
210
+ tokenSlug: fromChainNativeTokenSlug,
211
+ amount: networkFeeAmount.toString(),
212
+ feeType: _types.SwapFeeType.NETWORK_FEE
213
+ };
214
+ const walletFee = {
215
+ tokenSlug: toAsset.slug,
216
+ amount: walletFeeAmount,
217
+ feeType: _types.SwapFeeType.WALLET_FEE
218
+ };
219
+ return {
220
+ pair: request.pair,
221
+ fromAmount,
222
+ toAmount,
223
+ rate,
224
+ provider: this.providerInfo,
225
+ aliveUntil: +Date.now() + (_utils3.SWAP_QUOTE_TIMEOUT_MAP[this.slug] || _utils3.SWAP_QUOTE_TIMEOUT_MAP.default),
226
+ minSwap: toBNString(metadata.minSwap.value, (0, _utils._getAssetDecimals)(fromAsset)),
227
+ maxSwap: toBNString((_metadata$maxSwap = metadata.maxSwap) === null || _metadata$maxSwap === void 0 ? void 0 : _metadata$maxSwap.value, (0, _utils._getAssetDecimals)(fromAsset)),
228
+ estimatedArrivalTime: 3600,
229
+ isLowLiquidity: false,
230
+ feeInfo: {
231
+ feeComponent: [networkFee, walletFee],
232
+ defaultFeeToken,
233
+ feeOptions: [defaultFeeToken]
234
+ },
235
+ route: {
236
+ path: [fromAsset.slug, toAsset.slug]
237
+ }
238
+ };
239
+ } catch (e) {
240
+ return new _SwapError.SwapError(_types.SwapErrorType.UNKNOWN);
241
+ }
242
+ }
243
+ generateOptimalProcess(params) {
244
+ return this.swapBaseHandler.generateOptimalProcess(params, [this.getSubmitStep]);
245
+ }
246
+ async getSubmitStep(params) {
247
+ if (params.selectedQuote) {
248
+ const submitStep = {
249
+ name: 'Swap',
250
+ type: _types.SwapStepType.SWAP
251
+ };
252
+ return Promise.resolve([submitStep, params.selectedQuote.feeInfo]);
253
+ }
254
+ return Promise.resolve(undefined);
255
+ }
256
+ async validateSwapRequest(request) {
257
+ try {
258
+ const fromAsset = this.chainService.getAssetBySlug(request.pair.from);
259
+ const toAsset = this.chainService.getAssetBySlug(request.pair.to);
260
+ if (!fromAsset || !toAsset) {
261
+ return {
262
+ error: _types.SwapErrorType.ERROR_FETCHING_QUOTE
263
+ };
264
+ }
265
+ const fromSymbol = _utils3.SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING[fromAsset.slug];
266
+ const toSymbol = _utils3.SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING[toAsset.slug];
267
+ if (!fromSymbol || !toSymbol) {
268
+ return {
269
+ error: _types.SwapErrorType.ASSET_NOT_SUPPORTED
270
+ };
271
+ }
272
+ try {
273
+ const swapList = await fetchSwapList({
274
+ fromSymbol
275
+ });
276
+ if (!swapList.includes(toSymbol)) {
277
+ return {
278
+ error: _types.SwapErrorType.ASSET_NOT_SUPPORTED
279
+ };
280
+ }
281
+ } catch (err) {
282
+ console.error('Error:', err);
283
+ }
284
+ const ranges = await fetchRanges({
285
+ fromSymbol,
286
+ toSymbol
287
+ });
288
+ const {
289
+ max,
290
+ min
291
+ } = ranges;
292
+ const bnMin = toBNString(min, (0, _utils._getAssetDecimals)(fromAsset));
293
+ const bnAmount = BigInt(request.fromAmount);
294
+ if (bnAmount < BigInt(bnMin)) {
295
+ return {
296
+ error: _types.SwapErrorType.NOT_MEET_MIN_SWAP,
297
+ metadata: {
298
+ minSwap: {
299
+ value: min,
300
+ symbol: fromAsset.symbol
301
+ },
302
+ maxSwap: max ? {
303
+ value: max,
304
+ symbol: fromAsset.symbol
305
+ } : undefined,
306
+ chain: this.chainService.getChainInfoByKey(fromAsset.originChain)
307
+ }
308
+ };
309
+ }
310
+ if (max && bnAmount > BigInt(toBNString(max, (0, _utils._getAssetDecimals)(fromAsset)))) {
311
+ return {
312
+ error: _types.SwapErrorType.SWAP_EXCEED_ALLOWANCE,
313
+ metadata: {
314
+ minSwap: {
315
+ value: min,
316
+ symbol: fromAsset.symbol
317
+ },
318
+ maxSwap: {
319
+ value: max,
320
+ symbol: fromAsset.symbol
321
+ },
322
+ chain: this.chainService.getChainInfoByKey(fromAsset.originChain)
323
+ }
324
+ };
325
+ }
326
+ return {
327
+ metadata: {
328
+ minSwap: {
329
+ value: min,
330
+ symbol: fromAsset.symbol
331
+ },
332
+ maxSwap: max ? {
333
+ value: max,
334
+ symbol: fromAsset.symbol
335
+ } : undefined,
336
+ chain: this.chainService.getChainInfoByKey(fromAsset.originChain)
337
+ }
338
+ };
339
+ } catch (e) {
340
+ console.error(e);
341
+ return {
342
+ error: _types.SwapErrorType.UNKNOWN
343
+ };
344
+ }
345
+ }
346
+ async handleSwapProcess(params) {
347
+ const {
348
+ currentStep,
349
+ process
350
+ } = params;
351
+ const type = process.steps[currentStep].type;
352
+ switch (type) {
353
+ case _types.CommonStepType.DEFAULT:
354
+ return Promise.reject(new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED));
355
+ case _types.SwapStepType.SWAP:
356
+ return this.handleSubmitStep(params);
357
+ default:
358
+ return this.handleSubmitStep(params);
359
+ }
360
+ }
361
+ async handleSubmitStep(params) {
362
+ const {
363
+ address,
364
+ quote,
365
+ recipient
366
+ } = params;
367
+ const pair = quote.pair;
368
+ const fromAsset = this.chainService.getAssetBySlug(pair.from);
369
+ const toAsset = this.chainService.getAssetBySlug(pair.to);
370
+ const chainInfo = this.chainService.getChainInfoByKey(fromAsset.originChain);
371
+ const toChainInfo = this.chainService.getChainInfoByKey(toAsset.originChain);
372
+ const chainType = (0, _utils._isChainSubstrateCompatible)(chainInfo) ? _KoniTypes.ChainType.SUBSTRATE : _KoniTypes.ChainType.EVM;
373
+ const sender = (0, _utils2._reformatAddressWithChain)(address, chainInfo);
374
+ const receiver = (0, _utils2._reformatAddressWithChain)(recipient !== null && recipient !== void 0 ? recipient : sender, toChainInfo);
375
+ const fromSymbol = _utils3.SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING[fromAsset.slug];
376
+ const toSymbol = _utils3.SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING[toAsset.slug];
377
+ const {
378
+ fromAmount
379
+ } = quote;
380
+ const {
381
+ addressFrom,
382
+ amountTo,
383
+ id
384
+ } = await createSwapRequest({
385
+ fromSymbol,
386
+ toSymbol,
387
+ fromAmount,
388
+ fromAsset,
389
+ receiver,
390
+ sender,
391
+ toAsset
392
+ });
393
+
394
+ // Validate the amount to be swapped
395
+ const rate = (0, _bignumber.default)(amountTo).div((0, _bignumber.default)(quote.toAmount)).multipliedBy(100);
396
+ if (rate.lt(95)) {
397
+ throw new _SwapError.SwapError(_types.SwapErrorType.NOT_MEET_MIN_EXPECTED);
398
+ }
399
+
400
+ // Can modify quote.toAmount to amountTo after confirm real amount received
401
+
402
+ const txData = {
403
+ id: id,
404
+ address,
405
+ provider: this.providerInfo,
406
+ quote: params.quote,
407
+ slippage: params.slippage,
408
+ recipient: receiver,
409
+ process: params.process
410
+ };
411
+ let extrinsic;
412
+ if (chainType === _KoniTypes.ChainType.SUBSTRATE) {
413
+ const chainApi = this.chainService.getSubstrateApi(chainInfo.slug);
414
+ const substrateApi = await chainApi.isReady;
415
+ const [submittableExtrinsic] = await (0, _token.createTransferExtrinsic)({
416
+ from: address,
417
+ networkKey: chainInfo.slug,
418
+ substrateApi,
419
+ to: addressFrom,
420
+ tokenInfo: fromAsset,
421
+ transferAll: false,
422
+ value: quote.fromAmount
423
+ });
424
+ extrinsic = submittableExtrinsic;
425
+ } else {
426
+ if ((0, _utils._isNativeToken)(fromAsset)) {
427
+ const [transactionConfig] = await (0, _smartContract.getEVMTransactionObject)(chainInfo, address, addressFrom, quote.fromAmount, false, this.chainService.getEvmApi(chainInfo.slug));
428
+ extrinsic = transactionConfig;
429
+ } else {
430
+ const [transactionConfig] = await (0, _smartContract.getERC20TransactionObject)((0, _utils._getContractAddressOfToken)(fromAsset), chainInfo, address, addressFrom, quote.fromAmount, false, this.chainService.getEvmApi(chainInfo.slug));
431
+ extrinsic = transactionConfig;
432
+ }
433
+ }
434
+ return {
435
+ txChain: fromAsset.originChain,
436
+ txData,
437
+ extrinsic,
438
+ transferNativeAmount: (0, _utils._isNativeToken)(fromAsset) ? quote.fromAmount : '0',
439
+ extrinsicType: _KoniTypes.ExtrinsicType.SWAP,
440
+ chainType
441
+ };
442
+ }
443
+ }
444
+ exports.SimpleSwapHandler = SimpleSwapHandler;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.SwapService = void 0;
6
+ exports._isChainSupportedByProvider = exports.SwapService = void 0;
7
7
  var _SwapError = require("@subwallet/extension-base/background/errors/SwapError");
8
8
  var _TransactionError = require("@subwallet/extension-base/background/errors/TransactionError");
9
9
  var _types = require("@subwallet/extension-base/services/base/types");
@@ -16,9 +16,15 @@ var _serviceBase = require("@subwallet/extension-base/types/service-base");
16
16
  var _swap = require("@subwallet/extension-base/types/swap");
17
17
  var _utils2 = require("@subwallet/extension-base/utils");
18
18
  var _rxjs = require("rxjs");
19
+ var _simpleswapHandler = require("./handler/simpleswap-handler");
19
20
  // Copyright 2019-2022 @subwallet/extension-base
20
21
  // SPDX-License-Identifier: Apache-2.0
21
22
 
23
+ const _isChainSupportedByProvider = (providerSlug, chain) => {
24
+ const supportedChains = _utils._PROVIDER_TO_SUPPORTED_PAIR_MAP[providerSlug];
25
+ return supportedChains ? supportedChains.includes(chain) : false;
26
+ };
27
+ exports._isChainSupportedByProvider = _isChainSupportedByProvider;
22
28
  class SwapService {
23
29
  swapPairSubject = new _rxjs.BehaviorSubject([]);
24
30
  handlers = {};
@@ -35,7 +41,7 @@ class SwapService {
35
41
  const swappingSrcChain = this.chainService.getAssetBySlug(request.pair.from).originChain;
36
42
  await Promise.all(Object.values(this.handlers).map(async handler => {
37
43
  // temporary solution to reduce number of requests to providers, will work as long as there's only 1 provider for 1 chain
38
- if (!_utils._PROVIDER_TO_SUPPORTED_PAIR_MAP[handler.providerSlug].includes(swappingSrcChain)) {
44
+ if (!_isChainSupportedByProvider(handler.providerSlug, swappingSrcChain)) {
39
45
  return;
40
46
  }
41
47
  if (handler.init && handler.isReady === false) {
@@ -122,7 +128,10 @@ class SwapService {
122
128
  quoteError = (preferredErrorResp === null || preferredErrorResp === void 0 ? void 0 : preferredErrorResp.error) || (defaultErrorResp === null || defaultErrorResp === void 0 ? void 0 : defaultErrorResp.error);
123
129
  } else {
124
130
  var _selectedQuote;
125
- selectedQuote = availableQuotes[0];
131
+ selectedQuote = availableQuotes.find(quote => {
132
+ var _request$currentQuote;
133
+ return quote.provider.id === ((_request$currentQuote = request.currentQuote) === null || _request$currentQuote === void 0 ? void 0 : _request$currentQuote.id);
134
+ }) || availableQuotes[0];
126
135
  aliveUntil = ((_selectedQuote = selectedQuote) === null || _selectedQuote === void 0 ? void 0 : _selectedQuote.aliveUntil) || +Date.now() + _utils.SWAP_QUOTE_TIMEOUT_MAP.default;
127
136
  }
128
137
  return {
@@ -156,6 +165,9 @@ class SwapService {
156
165
  case _swap.SwapProviderId.ROCOCO_ASSET_HUB:
157
166
  this.handlers[providerId] = new _assetHub.AssetHubSwapHandler(this.chainService, this.state.balanceService, 'rococo_assethub');
158
167
  break;
168
+ case _swap.SwapProviderId.SIMPLE_SWAP:
169
+ this.handlers[providerId] = new _simpleswapHandler.SimpleSwapHandler(this.chainService, this.state.balanceService);
170
+ break;
159
171
  default:
160
172
  throw new Error('Unsupported provider');
161
173
  }
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports._PROVIDER_TO_SUPPORTED_PAIR_MAP = exports.SWAP_QUOTE_TIMEOUT_MAP = exports.CHAIN_FLIP_TESTNET_EXPLORER = exports.CHAIN_FLIP_SUPPORTED_TESTNET_MAPPING = exports.CHAIN_FLIP_SUPPORTED_TESTNET_ASSET_MAPPING = exports.CHAIN_FLIP_SUPPORTED_MAINNET_MAPPING = exports.CHAIN_FLIP_SUPPORTED_MAINNET_ASSET_MAPPING = exports.CHAIN_FLIP_MAINNET_EXPLORER = void 0;
7
+ exports._PROVIDER_TO_SUPPORTED_PAIR_MAP = exports.SWAP_QUOTE_TIMEOUT_MAP = exports.SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING = exports.SIMPLE_SWAP_EXPLORER = exports.CHAIN_FLIP_TESTNET_EXPLORER = exports.CHAIN_FLIP_SUPPORTED_TESTNET_MAPPING = exports.CHAIN_FLIP_SUPPORTED_TESTNET_ASSET_MAPPING = exports.CHAIN_FLIP_SUPPORTED_MAINNET_MAPPING = exports.CHAIN_FLIP_SUPPORTED_MAINNET_ASSET_MAPPING = exports.CHAIN_FLIP_MAINNET_EXPLORER = void 0;
8
8
  exports.calculateSwapRate = calculateSwapRate;
9
9
  exports.convertSwapRate = convertSwapRate;
10
10
  exports.getChainflipBroker = getChainflipBroker;
@@ -24,6 +24,8 @@ const CHAIN_FLIP_TESTNET_EXPLORER = 'https://blocks-perseverance.chainflip.io';
24
24
  exports.CHAIN_FLIP_TESTNET_EXPLORER = CHAIN_FLIP_TESTNET_EXPLORER;
25
25
  const CHAIN_FLIP_MAINNET_EXPLORER = 'https://scan.chainflip.io';
26
26
  exports.CHAIN_FLIP_MAINNET_EXPLORER = CHAIN_FLIP_MAINNET_EXPLORER;
27
+ const SIMPLE_SWAP_EXPLORER = 'https://simpleswap.io';
28
+ exports.SIMPLE_SWAP_EXPLORER = SIMPLE_SWAP_EXPLORER;
27
29
  const CHAIN_FLIP_SUPPORTED_MAINNET_MAPPING = {
28
30
  [_chainList.COMMON_CHAIN_SLUGS.POLKADOT]: _swap.Chains.Polkadot,
29
31
  [_chainList.COMMON_CHAIN_SLUGS.ETHEREUM]: _swap.Chains.Ethereum,
@@ -48,6 +50,14 @@ const CHAIN_FLIP_SUPPORTED_TESTNET_ASSET_MAPPING = {
48
50
  [_chainList.COMMON_ASSETS.USDC_SEPOLIA]: _swap.Assets.USDC
49
51
  };
50
52
  exports.CHAIN_FLIP_SUPPORTED_TESTNET_ASSET_MAPPING = CHAIN_FLIP_SUPPORTED_TESTNET_ASSET_MAPPING;
53
+ const SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING = {
54
+ 'bittensor-NATIVE-TAO': 'tao',
55
+ [_chainList.COMMON_ASSETS.ETH]: 'eth',
56
+ [_chainList.COMMON_ASSETS.DOT]: 'dot',
57
+ [_chainList.COMMON_ASSETS.USDC_ETHEREUM]: 'usdc',
58
+ [_chainList.COMMON_ASSETS.USDT_ETHEREUM]: 'usdterc20'
59
+ };
60
+ exports.SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING = SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING;
51
61
  const SWAP_QUOTE_TIMEOUT_MAP = {
52
62
  // in milliseconds
53
63
  default: 30000,
@@ -62,7 +72,8 @@ const _PROVIDER_TO_SUPPORTED_PAIR_MAP = {
62
72
  [_swap2.SwapProviderId.CHAIN_FLIP_TESTNET]: [_chainList.COMMON_CHAIN_SLUGS.CHAINFLIP_POLKADOT, _chainList.COMMON_CHAIN_SLUGS.ETHEREUM_SEPOLIA],
63
73
  [_swap2.SwapProviderId.POLKADOT_ASSET_HUB]: [_chainList.COMMON_CHAIN_SLUGS.POLKADOT_ASSET_HUB],
64
74
  [_swap2.SwapProviderId.KUSAMA_ASSET_HUB]: [_chainList.COMMON_CHAIN_SLUGS.KUSAMA_ASSET_HUB],
65
- [_swap2.SwapProviderId.ROCOCO_ASSET_HUB]: [_chainList.COMMON_CHAIN_SLUGS.ROCOCO_ASSET_HUB]
75
+ [_swap2.SwapProviderId.ROCOCO_ASSET_HUB]: [_chainList.COMMON_CHAIN_SLUGS.ROCOCO_ASSET_HUB],
76
+ [_swap2.SwapProviderId.SIMPLE_SWAP]: ['bittensor', _chainList.COMMON_CHAIN_SLUGS.ETHEREUM, _chainList.COMMON_CHAIN_SLUGS.POLKADOT]
66
77
  };
67
78
  exports._PROVIDER_TO_SUPPORTED_PAIR_MAP = _PROVIDER_TO_SUPPORTED_PAIR_MAP;
68
79
  function getSwapAlternativeAsset(swapPair) {
@@ -1063,7 +1063,7 @@ class TransactionService {
1063
1063
  }
1064
1064
  return emitter;
1065
1065
  }
1066
- async signAndSendSubstrateTransaction(_ref10) {
1066
+ signAndSendSubstrateTransaction(_ref10) {
1067
1067
  let {
1068
1068
  address,
1069
1069
  chain,
@@ -1079,8 +1079,9 @@ class TransactionService {
1079
1079
  extrinsicHash: id
1080
1080
  };
1081
1081
  const extrinsic = transaction;
1082
- const registry = extrinsic.registry;
1083
- const signedExtensions = registry.signedExtensions;
1082
+ // const registry = extrinsic.registry;
1083
+ // const signedExtensions = registry.signedExtensions;
1084
+
1084
1085
  const signerOption = {
1085
1086
  signer: {
1086
1087
  signPayload: async payload => {
@@ -1097,13 +1098,16 @@ class TransactionService {
1097
1098
  },
1098
1099
  withSignedTransaction: true
1099
1100
  };
1100
- if ((0, _utils4._isRuntimeUpdated)(signedExtensions)) {
1101
- const metadataHash = await this.state.chainService.calculateMetadataHash(chain);
1102
- if (metadataHash) {
1103
- signerOption.mode = 1;
1104
- signerOption.metadataHash = metadataHash;
1105
- }
1106
- }
1101
+
1102
+ // if (_isRuntimeUpdated(signedExtensions)) {
1103
+ // const metadataHash = await this.state.chainService.calculateMetadataHash(chain);
1104
+ //
1105
+ // if (metadataHash) {
1106
+ // signerOption.mode = 1;
1107
+ // signerOption.metadataHash = metadataHash;
1108
+ // }
1109
+ // }
1110
+
1107
1111
  extrinsic.signAsync(address, signerOption).then(async rs => {
1108
1112
  // Emit signed event
1109
1113
  emitter.emit('signed', eventData);