@rabbitio/ui-kit 1.0.0-beta.42 → 1.0.0-beta.45

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 (67) hide show
  1. package/.gitlab-ci.yml +29 -0
  2. package/.husky/commit-msg +8 -0
  3. package/.husky/pre-push +1 -0
  4. package/README.md +13 -4
  5. package/dist/index.cjs +1545 -148
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.css +23630 -0
  8. package/dist/index.css.map +1 -1
  9. package/dist/index.modern.js +1318 -103
  10. package/dist/index.modern.js.map +1 -1
  11. package/dist/index.module.js +1534 -149
  12. package/dist/index.module.js.map +1 -1
  13. package/dist/index.umd.js +1544 -152
  14. package/dist/index.umd.js.map +1 -1
  15. package/package.json +16 -3
  16. package/src/assets/image/icons/arrow-tosca.svg +3 -0
  17. package/src/assets/image/icons/arrow-white.svg +14 -0
  18. package/src/assets/image/icons/failed-validation-icon.svg +15 -0
  19. package/src/assets/image/icons/successful-validation-icon.svg +10 -0
  20. package/src/common/amountUtils.js +4 -2
  21. package/src/common/tests/integration/external-apis/ipAddressProviders/getClientIpAddress.test.js +14 -0
  22. package/src/common/utils/cache.js +4 -4
  23. package/src/components/atoms/BackgroundTitle/BackgroundTitle.jsx +44 -0
  24. package/src/components/atoms/BackgroundTitle/background-title.module.scss +52 -0
  25. package/src/components/atoms/Validation/Validation.jsx +130 -0
  26. package/src/components/atoms/Validation/validation.module.scss +15 -0
  27. package/src/components/atoms/buttons/Close/Close.jsx +64 -0
  28. package/src/components/atoms/buttons/Close/close.module.scss +75 -0
  29. package/src/components/atoms/buttons/LinkButton/LinkButton.jsx +121 -0
  30. package/src/components/atoms/buttons/LinkButton/link-button.module.scss +45 -0
  31. package/src/components/organisms/Dialog/Dialog.jsx +515 -0
  32. package/src/components/organisms/Dialog/DialogButtons/DialogButtons.jsx +122 -0
  33. package/src/components/organisms/Dialog/DialogButtons/dialog-buttons.module.scss +25 -0
  34. package/src/components/organisms/Dialog/DialogStep/DialogStep.jsx +664 -0
  35. package/src/components/organisms/Dialog/DialogStep/dialog-step.module.scss +362 -0
  36. package/src/components/organisms/Dialog/dialog.module.scss +223 -0
  37. package/src/components/tests/utils/inputValueProviders/provideFormatOfFloatValueByInputString.test.js +139 -0
  38. package/src/components/tests/utils/urlQueryUtils/getQueryParameterValues.test.js +71 -0
  39. package/src/components/tests/utils/urlQueryUtils/saveQueryParameterAndValues.test.js +144 -0
  40. package/src/components/utils/inputValueProviders.js +58 -0
  41. package/src/constants/organisms/dialog/DialogStep/dialogStep.js +1 -0
  42. package/src/constants/organisms/dialog/dialog.js +29 -0
  43. package/src/index.js +11 -0
  44. package/src/robustExteranlApiCallerService/robustExternalAPICallerService.js +3 -1
  45. package/src/robustExteranlApiCallerService/tests/robustExternalAPICallerService/robustExternalAPICallerService/callExternalAPI/_performCallAttempt.test.js +787 -0
  46. package/src/robustExteranlApiCallerService/tests/robustExternalAPICallerService/robustExternalAPICallerService/callExternalAPI/callExternalAPI.test.js +745 -0
  47. package/src/robustExteranlApiCallerService/tests/robustExternalAPICallerService/robustExternalAPICallerService/constructor.test.js +31 -0
  48. package/src/swaps-lib/external-apis/swapProvider.js +17 -4
  49. package/src/swaps-lib/external-apis/swapspaceSwapProvider.js +91 -30
  50. package/src/swaps-lib/models/baseSwapCreationInfo.js +4 -1
  51. package/src/swaps-lib/models/existingSwap.js +3 -0
  52. package/src/swaps-lib/models/existingSwapWithFiatData.js +4 -0
  53. package/src/swaps-lib/services/publicSwapService.js +32 -4
  54. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/_fetchSupportedCurrenciesIfNeeded.test.js +506 -0
  55. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/createSwap.test.js +1311 -0
  56. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/getAllSupportedCurrencies.test.js +76 -0
  57. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/getDepositCurrencies.test.js +82 -0
  58. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/getSwapInfo.test.js +1892 -0
  59. package/src/swaps-lib/test/external-apis/swapspaceSwapProvider/getWithdrawalCurrencies.test.js +111 -0
  60. package/src/swaps-lib/test/utils/swapUtils/safeHandleRequestsLimitExceeding.test.js +88 -0
  61. package/stories/stubs/exampleContent.jsx +20 -0
  62. package/styles/fonts/NunitoSans-Bold.ttf +0 -0
  63. package/styles/fonts/NunitoSans-ExtraBold.ttf +0 -0
  64. package/styles/fonts/NunitoSans-Light.ttf +0 -0
  65. package/styles/fonts/NunitoSans-Regular.ttf +0 -0
  66. package/styles/fonts/NunitoSans-SemiBold.ttf +0 -0
  67. package/styles/index.scss +14 -13
@@ -0,0 +1,31 @@
1
+ import should from "should";
2
+
3
+ import { describe, it } from "vitest";
4
+
5
+ import { ExternalApiProvider } from "../../../externalApiProvider.js";
6
+ import { RobustExternalAPICallerService } from "../../../robustExternalAPICallerService.js";
7
+ import { ApiGroup } from "../../../../common/external-apis/apiGroups.js";
8
+
9
+ describe("RobustExternalAPICallerService", function () {
10
+ describe("#constructor", function () {
11
+ const someProviders = [
12
+ new ExternalApiProvider(
13
+ "ggee.com",
14
+ "get",
15
+ 10000,
16
+ new ApiGroup("aaa2141r1f", 1)
17
+ ),
18
+ ];
19
+
20
+ it("Should set niceFactor field to 1 for given providers Array", async function () {
21
+ const instance = new RobustExternalAPICallerService(
22
+ "someBio",
23
+ someProviders
24
+ );
25
+
26
+ instance.providers.forEach((provider) =>
27
+ provider.niceFactor.should.be.equal(1)
28
+ );
29
+ });
30
+ });
31
+ });
@@ -7,6 +7,8 @@ export class SwapProvider {
7
7
  TOO_LOW: "tooLow",
8
8
  TOO_HIGH: "tooHigh",
9
9
  NOT_SUPPORTED: "notSupported",
10
+ NO_FIXED_BUT_HAVE_FLOATING: "noFixedButHaveFloating",
11
+ NO_FLOATING_BUT_HAVE_FIXED: "noFloatingButHaveFixed",
10
12
  };
11
13
 
12
14
  static CREATION_FAIL_REASONS = {
@@ -98,6 +100,7 @@ export class SwapProvider {
98
100
  * @param fromCoin {Coin}
99
101
  * @param toCoin {Coin}
100
102
  * @param amountCoins {string}
103
+ * @param [fixed=false] {boolean|null} null means fixed or float doesn't matter
101
104
  * @param [fromCoinToUsdRate=null] pass if you want to increase the min amount returned
102
105
  * by provider with some fixed "insurance" amount to cover min amount fluctuations.
103
106
  * @return {Promise<({
@@ -113,15 +116,22 @@ export class SwapProvider {
113
116
  * greatestMax: (string|null),
114
117
  * rate: (string|null),
115
118
  * durationMinutesRange: string,
119
+ * fixed: boolean,
116
120
  * [rawSwapData]: Object
117
121
  * })>}
118
122
  */
119
- async getSwapInfo(fromCoin, toCoin, amountCoins, fromCoinToUsdRate = null) {
123
+ async getSwapInfo(
124
+ fromCoin,
125
+ toCoin,
126
+ amountCoins,
127
+ fixed = false,
128
+ fromCoinToUsdRate = null
129
+ ) {
120
130
  throw new Error("Not implemented in base");
121
131
  }
122
132
 
123
133
  /**
124
- * For fail result we return one of SwapProvider.CREATION_FAIL_REASONS or SwapProvider.COMMON_ERRORS.
134
+ * For fail result we return one of SwapProvider.CREATION_FAIL_REASONS or SwapProvider.COMMON_ERRORS.*
125
135
  *
126
136
  * @param fromCoin {Coin}
127
137
  * @param toCoin {Coin}
@@ -130,6 +140,7 @@ export class SwapProvider {
130
140
  * @param refundAddress {string}
131
141
  * @param rawSwapData {Object|null}
132
142
  * @param clientIpAddress {string}
143
+ * @param fixed {boolean}
133
144
  * @param [toCurrencyExtraId=""] {string} optional extra ID
134
145
  * @param [refundExtraId=""] {string} optional extra ID for refund address
135
146
  * @return {Promise<({
@@ -142,7 +153,8 @@ export class SwapProvider {
142
153
  * toAmount: string,
143
154
  * toAddress: string,
144
155
  * rate: string,
145
- * fromCurrencyExtraId: string|undefined
156
+ * fromCurrencyExtraId: string|undefined,
157
+ * fixed: boolean
146
158
  * }|{
147
159
  * result: false,
148
160
  * reason: string,
@@ -155,8 +167,9 @@ export class SwapProvider {
155
167
  amount,
156
168
  toAddress,
157
169
  refundAddress,
158
- rawSwapData = null,
170
+ rawSwapData,
159
171
  clientIpAddress,
172
+ fixed,
160
173
  toCurrencyExtraId = "",
161
174
  refundExtraId = ""
162
175
  ) {
@@ -172,7 +172,6 @@ export class SwapspaceSwapProvider extends SwapProvider {
172
172
  }`;
173
173
  const defaultDecimalPlacesForCoinNotSupportedOOB = 8;
174
174
  const defaultMinConfirmationsForCoinNotSupportedOOB = 1;
175
- // TODO: [dev] maybe we should recognize standard protocols?
176
175
  coin = new Coin(
177
176
  item.name,
178
177
  ticker,
@@ -199,7 +198,7 @@ export class SwapspaceSwapProvider extends SwapProvider {
199
198
  network: item.network,
200
199
  hasExtraId: item.hasExtraId,
201
200
  extraIdName: item.extraIdName,
202
- isPopular: !!item?.popular,
201
+ isPopular: !!item.popular,
203
202
  iconURL: item.icon
204
203
  ? `https://storage.swapspace.co${item.icon}`
205
204
  : FALLBACK_ICON_URL,
@@ -264,13 +263,18 @@ export class SwapspaceSwapProvider extends SwapProvider {
264
263
  "Loading USDT->coin rate as not found in cache:",
265
264
  coin?.ticker
266
265
  );
267
- const result = await this.getSwapInfo(usdtTrc20, coin, "5000");
266
+ const result = await this.getSwapInfo(
267
+ usdtTrc20,
268
+ coin,
269
+ "5000",
270
+ false
271
+ );
268
272
  if (!result.result) {
269
273
  return { result: false };
270
274
  }
271
275
 
272
276
  // This calculation is not precise as we cannot recognize the actual fee and network fee. Just approximate.
273
- const standardSwapspaceFeeMultiplier = 1.004; // usually 0.2%
277
+ const standardSwapspaceFeeMultiplier = 1.004; // fee is usually 0.4%
274
278
  const rate = BigNumber(1)
275
279
  .div(
276
280
  BigNumber(result.rate).times(standardSwapspaceFeeMultiplier)
@@ -301,19 +305,28 @@ export class SwapspaceSwapProvider extends SwapProvider {
301
305
  }
302
306
  }
303
307
 
304
- async getSwapInfo(fromCoin, toCoin, amountCoins, fromCoinToUsdRate = null) {
308
+ async getSwapInfo(
309
+ fromCoin,
310
+ toCoin,
311
+ amountCoins,
312
+ fixed = false,
313
+ fromCoinToUsdRate = null
314
+ ) {
305
315
  const loggerSource = "getSwapInfo";
306
316
  try {
307
317
  if (
308
318
  !(fromCoin instanceof Coin) ||
309
319
  !(toCoin instanceof Coin) ||
310
320
  typeof amountCoins !== "string" ||
311
- BigNumber(amountCoins).lt("0")
321
+ BigNumber(amountCoins).lt("0") ||
322
+ (fixed !== null && typeof fixed !== "boolean")
312
323
  ) {
313
324
  throw new Error(
314
- `Wrong input params: ${amountCoins} ${fromCoin.ticker} -> ${toCoin.ticker}` +
315
- (fromCoin instanceof Coin) +
316
- (toCoin instanceof Coin)
325
+ `Wrong input params: ${amountCoins} ${fromCoin.ticker} -> ${
326
+ toCoin.ticker
327
+ }, ${fromCoin instanceof Coin}, ${
328
+ toCoin instanceof Coin
329
+ }, ${typeof fixed} ${fixed}`
317
330
  );
318
331
  }
319
332
  const fromCoinSwapspaceDetails = this._supportedCoins.find(
@@ -344,32 +357,57 @@ export class SwapspaceSwapProvider extends SwapProvider {
344
357
  * But we are better off using the most actual rates.
345
358
  */
346
359
  const response = await axios.get(
347
- `${this._URL}/api/v2/amounts?fromCurrency=${fromCoinSwapspaceDetails.code}&fromNetwork=${fromCoinSwapspaceDetails.network}&toNetwork=${toCoinSwapspaceDetails.network}&toCurrency=${toCoinSwapspaceDetails.code}&amount=${amountCoins}&float=true&estimated=false`
360
+ `${this._URL}/api/v2/amounts?fromCurrency=${fromCoinSwapspaceDetails.code}&fromNetwork=${fromCoinSwapspaceDetails.network}&toNetwork=${toCoinSwapspaceDetails.network}&toCurrency=${toCoinSwapspaceDetails.code}&amount=${amountCoins}&estimated=false`
348
361
  );
349
362
  Logger.log(
350
363
  `Retrieved ${response?.data?.length} options`,
351
364
  loggerSource
352
365
  );
353
366
  const options = Array.isArray(response.data) ? response.data : [];
354
- const exchangesSupportingThePair = options.filter(
355
- (exchange) =>
356
- exchange?.exists &&
357
- !BANNED_PARTNERS.find(
358
- (bannedPartner) => bannedPartner === exchange?.partner
359
- ) &&
360
- exchange?.fixed === false &&
361
- (exchange.min === 0 ||
362
- exchange.max === 0 ||
363
- exchange.max > exchange.min ||
364
- ((typeof exchange.min !== "number" ||
365
- typeof exchange.max !== "number") &&
366
- exchange.toAmount > 0))
367
- );
367
+ let exchangesSupportingThePairDespiteFixedOrFloating =
368
+ options.filter(
369
+ (exchange) =>
370
+ exchange?.exists &&
371
+ !BANNED_PARTNERS.find(
372
+ (bannedPartner) =>
373
+ bannedPartner === exchange?.partner
374
+ ) &&
375
+ (exchange?.fixed === false ||
376
+ exchange?.fixed === true) &&
377
+ (exchange.min === 0 ||
378
+ exchange.max === 0 ||
379
+ exchange.max > exchange.min ||
380
+ ((typeof exchange.min !== "number" ||
381
+ typeof exchange.max !== "number") &&
382
+ exchange.toAmount > 0))
383
+ );
384
+ let exchangesSupportingThePair =
385
+ exchangesSupportingThePairDespiteFixedOrFloating;
386
+ if (fixed != null) {
387
+ exchangesSupportingThePair =
388
+ exchangesSupportingThePairDespiteFixedOrFloating.filter(
389
+ (option) => option.fixed === fixed
390
+ );
391
+ }
368
392
  Logger.log(
369
393
  `${exchangesSupportingThePair?.length} of them have exist=true`,
370
394
  loggerSource
371
395
  );
372
- if (!exchangesSupportingThePair.length) {
396
+ if (exchangesSupportingThePair.length === 0) {
397
+ if (
398
+ exchangesSupportingThePairDespiteFixedOrFloating.length >
399
+ 0 &&
400
+ fixed !== null
401
+ ) {
402
+ return {
403
+ result: false,
404
+ reason: fixed
405
+ ? SwapProvider.NO_SWAPS_REASONS
406
+ .NO_FIXED_BUT_HAVE_FLOATING
407
+ : SwapProvider.NO_SWAPS_REASONS
408
+ .NO_FLOATING_BUT_HAVE_FIXED,
409
+ };
410
+ }
373
411
  return {
374
412
  result: false,
375
413
  reason: SwapProvider.NO_SWAPS_REASONS.NOT_SUPPORTED,
@@ -491,6 +529,7 @@ export class SwapspaceSwapProvider extends SwapProvider {
491
529
  ? AmountUtils.trim(rate, this._maxRateDigits)
492
530
  : null,
493
531
  durationMinutesRange: bestOpt.duration ?? null,
532
+ fixed: bestOpt.fixed,
494
533
  rawSwapData: bestOpt,
495
534
  };
496
535
  }
@@ -535,6 +574,7 @@ export class SwapspaceSwapProvider extends SwapProvider {
535
574
  refundAddress,
536
575
  rawSwapData,
537
576
  clientIpAddress,
577
+ fixed,
538
578
  toCurrencyExtraId = "",
539
579
  refundExtraId = ""
540
580
  ) {
@@ -546,10 +586,13 @@ export class SwapspaceSwapProvider extends SwapProvider {
546
586
  !(toCoin instanceof Coin) ||
547
587
  typeof amount !== "string" ||
548
588
  typeof toAddress !== "string" ||
549
- typeof refundAddress !== "string"
589
+ typeof refundAddress !== "string" ||
590
+ typeof clientIpAddress != "string" ||
591
+ typeof fixed != "boolean" ||
592
+ clientIpAddress.length === 0
550
593
  ) {
551
594
  throw new Error(
552
- `Invalid input: ${fromCoin} ${toCoin} ${amount} ${toAddress} ${refundAddress}`
595
+ `Invalid input: ${fromCoin} ${toCoin} ${amount} ${toAddress} ${refundAddress} ${clientIpAddress?.length} ${fixed}`
553
596
  );
554
597
  }
555
598
  if (
@@ -565,6 +608,18 @@ export class SwapspaceSwapProvider extends SwapProvider {
565
608
  );
566
609
  }
567
610
 
611
+ const [fromCurrencyHasExtraId, toCurrencyHasExtraId] =
612
+ this._supportedCoins.reduce(
613
+ (prev, coinData) => [
614
+ coinData.coin.ticker === fromCoin.ticker
615
+ ? coinData.hasExtraId
616
+ : prev[0],
617
+ coinData.coin.ticker === toCoin.ticker
618
+ ? coinData.hasExtraId
619
+ : prev[1],
620
+ ],
621
+ [false, false]
622
+ );
568
623
  await this._fetchSupportedCurrenciesIfNeeded();
569
624
  const requestData = {
570
625
  partner: partner,
@@ -574,9 +629,12 @@ export class SwapspaceSwapProvider extends SwapProvider {
574
629
  toNetwork: rawSwapData?.toNetwork,
575
630
  address: toAddress,
576
631
  amount: amount,
577
- fixed: false,
578
- extraId: toCurrencyExtraId ?? "",
579
- refundExtraId: refundExtraId ?? "", // This param is not documented. But the refund is usually manual so this is not critical.
632
+ fixed: fixed,
633
+ extraId: toCurrencyHasExtraId ? toCurrencyExtraId ?? "" : "",
634
+ // This param is not documented. But the refund is usually manual so this is not critical.
635
+ refundExtraId: fromCurrencyHasExtraId
636
+ ? refundExtraId ?? ""
637
+ : "",
580
638
  rateId: rawSwapData?.id,
581
639
  userIp: clientIpAddress,
582
640
  refund: refundAddress,
@@ -600,6 +658,7 @@ export class SwapspaceSwapProvider extends SwapProvider {
600
658
  if (
601
659
  typeof result?.from?.amount !== "number" ||
602
660
  typeof result?.from?.address !== "string" ||
661
+ typeof result?.fixed !== "boolean" ||
603
662
  typeof result?.to?.amount !== "number" ||
604
663
  typeof result?.to?.address !== "string"
605
664
  )
@@ -632,6 +691,7 @@ export class SwapspaceSwapProvider extends SwapProvider {
632
691
  toAddress: result?.to?.address,
633
692
  fromCurrencyExtraId: result?.from?.extraId ?? "",
634
693
  rate: AmountUtils.trim(rate, this._maxRateDigits),
694
+ fixed: result.fixed,
635
695
  };
636
696
  }
637
697
  const errorMessage = `Swap creation succeeded but the response is wrong: ${safeStringify(
@@ -785,6 +845,7 @@ export class SwapspaceSwapProvider extends SwapProvider {
785
845
  expiresAt,
786
846
  swap.confirmations,
787
847
  AmountUtils.trim(swap.rate, this._maxRateDigits),
848
+ swap.fixed,
788
849
  swap.refundAddress,
789
850
  addressToSendCoinsToSwapspace,
790
851
  fromCoin,
@@ -11,6 +11,7 @@ export class BaseSwapCreationInfo {
11
11
  * @param max {string}
12
12
  * @param fiatMax {number}
13
13
  * @param durationMinutesRange {string}
14
+ * @param fixed {boolean}
14
15
  */
15
16
  constructor(
16
17
  fromCoin,
@@ -23,7 +24,8 @@ export class BaseSwapCreationInfo {
23
24
  fiatMin,
24
25
  max,
25
26
  fiatMax,
26
- durationMinutesRange
27
+ durationMinutesRange,
28
+ fixed
27
29
  ) {
28
30
  this.fromCoin = fromCoin;
29
31
  this.toCoin = toCoin;
@@ -36,5 +38,6 @@ export class BaseSwapCreationInfo {
36
38
  this.max = max;
37
39
  this.fiatMax = fiatMax;
38
40
  this.durationMinutesRange = durationMinutesRange;
41
+ this.fixed = fixed;
39
42
  }
40
43
  }
@@ -6,6 +6,7 @@ export class ExistingSwap {
6
6
  * @param expiresAt {number}
7
7
  * @param confirmations {number}
8
8
  * @param rate {string}
9
+ * @param fixed {boolean}
9
10
  * @param refundAddress {string}
10
11
  * @param payToAddress {string}
11
12
  * @param fromCoin {Coin}
@@ -29,6 +30,7 @@ export class ExistingSwap {
29
30
  expiresAt,
30
31
  confirmations,
31
32
  rate,
33
+ fixed,
32
34
  refundAddress,
33
35
  payToAddress,
34
36
  fromCoin,
@@ -51,6 +53,7 @@ export class ExistingSwap {
51
53
  this.expiresAt = expiresAt;
52
54
  this.confirmations = confirmations;
53
55
  this.rate = rate;
56
+ this.fixed = fixed;
54
57
  this.refundAddress = refundAddress;
55
58
  this.payToAddress = payToAddress;
56
59
  this.fromCoin = fromCoin;
@@ -8,6 +8,7 @@ export class ExistingSwapWithFiatData extends ExistingSwap {
8
8
  * @param expiresAt {number}
9
9
  * @param confirmations {number}
10
10
  * @param rate {string}
11
+ * @param fixed {boolean}
11
12
  * @param refundAddress {string}
12
13
  * @param payToAddress {string}
13
14
  * @param fromCoin {Coin}
@@ -35,6 +36,7 @@ export class ExistingSwapWithFiatData extends ExistingSwap {
35
36
  expiresAt,
36
37
  confirmations,
37
38
  rate,
39
+ fixed,
38
40
  refundAddress,
39
41
  payToAddress,
40
42
  fromCoin,
@@ -62,6 +64,7 @@ export class ExistingSwapWithFiatData extends ExistingSwap {
62
64
  expiresAt,
63
65
  confirmations,
64
66
  rate,
67
+ fixed,
65
68
  refundAddress,
66
69
  payToAddress,
67
70
  fromCoin,
@@ -106,6 +109,7 @@ export class ExistingSwapWithFiatData extends ExistingSwap {
106
109
  existingSwap.expiresAt,
107
110
  existingSwap.confirmations,
108
111
  existingSwap.rate,
112
+ existingSwap.fixed,
109
113
  existingSwap.refundAddress,
110
114
  existingSwap.payToAddress,
111
115
  existingSwap.fromCoin,
@@ -23,6 +23,10 @@ export class PublicSwapService {
23
23
  AMOUNT_LESS_THAN_MIN_SWAPPABLE: "amountLessThanMinSwappable",
24
24
  AMOUNT_HIGHER_THAN_MAX_SWAPPABLE: "amountHigherThanMaxSwappable",
25
25
  PAIR_NOT_SUPPORTED: "pairNotSupported",
26
+ NO_FIXED_BUT_HAVE_FLOATING_PUBLIC_SWAP_OPTION:
27
+ "noFixedButHaveFloatingPublicSwapOption",
28
+ NO_FLOATING_BUT_HAVE_FIXED_PUBLIC_SWAP_OPTION:
29
+ "noFloatingButHaveFixedPublicSwapOption",
26
30
  };
27
31
 
28
32
  static _fiatDecimalsCount =
@@ -173,6 +177,7 @@ export class PublicSwapService {
173
177
  * @param fromCoin {Coin}
174
178
  * @param toCoin {Coin}
175
179
  * @param fromAmountCoins {string}
180
+ * @param [fixed=false] {boolean|null} null means fixed or float doesn't matter
176
181
  * @param [withoutFiat=false] {boolean} pass true if you don't need the fiat equivalent - this will diminish requests count
177
182
  * @return {Promise<{
178
183
  * result: false,
@@ -191,6 +196,7 @@ export class PublicSwapService {
191
196
  fromCoin,
192
197
  toCoin,
193
198
  fromAmountCoins,
199
+ fixed = false,
194
200
  withoutFiat = false
195
201
  ) {
196
202
  const loggerSource = "getPublicSwapDetails";
@@ -203,6 +209,7 @@ export class PublicSwapService {
203
209
  fromCoin,
204
210
  toCoin,
205
211
  fromAmountCoins,
212
+ fixed,
206
213
  coinUsdtRate
207
214
  );
208
215
  const min = details.result ? details.min : details.smallestMin;
@@ -236,12 +243,12 @@ export class PublicSwapService {
236
243
  if (
237
244
  details?.reason ===
238
245
  SwapProvider.NO_SWAPS_REASONS.NOT_SUPPORTED
239
- )
246
+ ) {
240
247
  return composeFailResult(
241
248
  PublicSwapService.PUBLIC_SWAP_DETAILS_FAIL_REASONS
242
249
  .PAIR_NOT_SUPPORTED
243
250
  );
244
- else if (
251
+ } else if (
245
252
  details?.reason ===
246
253
  SwapProvider.COMMON_ERRORS.REQUESTS_LIMIT_EXCEEDED
247
254
  ) {
@@ -250,6 +257,22 @@ export class PublicSwapService {
250
257
  PublicSwapService.PUBLIC_SWAPS_COMMON_ERRORS
251
258
  .REQUESTS_LIMIT_EXCEEDED
252
259
  );
260
+ } else if (
261
+ details?.reason ===
262
+ SwapProvider.NO_SWAPS_REASONS.NO_FLOATING_BUT_HAVE_FIXED
263
+ ) {
264
+ return composeFailResult(
265
+ PublicSwapService.PUBLIC_SWAP_DETAILS_FAIL_REASONS
266
+ .NO_FLOATING_BUT_HAVE_FIXED_PUBLIC_SWAP_OPTION
267
+ );
268
+ } else if (
269
+ details?.reason ===
270
+ SwapProvider.NO_SWAPS_REASONS.NO_FIXED_BUT_HAVE_FLOATING
271
+ ) {
272
+ return composeFailResult(
273
+ PublicSwapService.PUBLIC_SWAP_DETAILS_FAIL_REASONS
274
+ .NO_FIXED_BUT_HAVE_FLOATING_PUBLIC_SWAP_OPTION
275
+ );
253
276
  }
254
277
  }
255
278
 
@@ -283,7 +306,8 @@ export class PublicSwapService {
283
306
  fiatMin,
284
307
  max,
285
308
  fiatMax,
286
- details.durationMinutesRange
309
+ details.durationMinutesRange,
310
+ details.fixed
287
311
  ),
288
312
  };
289
313
  Logger.log(
@@ -330,7 +354,8 @@ export class PublicSwapService {
330
354
  * fromCoin: Coin,
331
355
  * rate: string,
332
356
  * swapId: string,
333
- * fromCurrencyExtraId: string
357
+ * fromCurrencyExtraId: string,
358
+ * fixed: boolean
334
359
  * }|{
335
360
  * result: false,
336
361
  * reason: string
@@ -380,6 +405,7 @@ export class PublicSwapService {
380
405
  refundAddress,
381
406
  swapCreationInfo.rawSwapData,
382
407
  clientIp,
408
+ swapCreationInfo.fixed,
383
409
  toCurrencyExtraId,
384
410
  refundExtraId
385
411
  );
@@ -442,6 +468,7 @@ export class PublicSwapService {
442
468
  );
443
469
  }
444
470
 
471
+ // TODO: feature, cirtical] add GA event. task_id=tbd
445
472
  EventBusInstance.dispatch(
446
473
  PublicSwapService.PUBLIC_SWAP_CREATED_EVENT,
447
474
  null,
@@ -465,6 +492,7 @@ export class PublicSwapService {
465
492
  durationMinutesRange: swapCreationInfo.durationMinutesRange,
466
493
  address: result.fromAddress, // CRITICAL: this is the address to send coins to swaps provider
467
494
  fromCurrencyExtraId: result.fromCurrencyExtraId ?? "", // CRITICAL: this is the extra ID for address to send coins to swaps provider
495
+ fixed: result.fixed,
468
496
  };
469
497
 
470
498
  this._savePublicSwapIdLocally(result.swapId);