diff --git a/.npmignore b/.npmignore
index 93ddc08..332eef1 100644
--- a/.npmignore
+++ b/.npmignore
@@ -3,7 +3,7 @@ node_modules
/dist
/docs
/src
-
+/dist/src
.env
# local env files
.env.local
diff --git a/package.json b/package.json
index 165d51d..6e2772c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@pontem/liquidswap-widget",
- "version": "0.2.12",
+ "version": "0.3.0",
"homepage": "https://github.com/pontem-network/liquidswap-widget#readme",
"description": "LiquidSwap widget as custom web component",
"files": [
@@ -49,7 +49,7 @@
"dependencies": {
"@metamask/jazzicon": "2.0.0",
"@pontem/aptos-wallet-adapter": "0.7.2",
- "@pontem/coins-registry": "2.1.8",
+ "@pontem/coins-registry": "2.1.19",
"@pontem/liquidswap-sdk": "0.6.1",
"@tsconfig/recommended": "1.0.2",
"@types/lodash": "4.14.182",
diff --git a/src/Swap/SwapContainer.vue b/src/Swap/SwapContainer.vue
index d71ffd6..c5a5af9 100644
--- a/src/Swap/SwapContainer.vue
+++ b/src/Swap/SwapContainer.vue
@@ -41,20 +41,21 @@
+ v-if="tokensChosen && !fullCurveOfDefaultPool"
+ class="swap__row"
+ :class="[mainStore.insideNativeWallet.value && 'swap__row--extra-padding']"
+ >
Caution: make sure the pair you are trading should be stable or
- uncorrelated. i.e USDC/USDT is stable and USDC/BTC is
- uncorrelatedCaution: make sure the pair you are trading should be stable or uncorrelated. i.e USDC/USDT
+ is stable and USDC/BTC is uncorrelated
-
+ v-show="tokensChosen && !fullCurveOfDefaultPool"
+ class="swap__row"
+ :class="[mainStore.insideNativeWallet.value && 'swap__row--extra-padding']"
+ >
+
-
+
-
+
Connect Wallet
@@ -115,7 +109,7 @@
:to-token="swapStore.toCurrency.token"
:from-token="swapStore.fromCurrency.token"
/>
-
+
@@ -131,7 +125,7 @@ import { ReservesContainer } from '@/components/ReservesContainer';
import { TxSettingsDialog } from '@/components/TxSettingsDialog';
import { ContractSwitch } from '@/components/ContractSwitch';
import { useCurrentAccountBalance } from '@/composables/useAccountBalance';
-import { useStore, useSwapStore, useTokensStore, usePoolsStore } from '@/store';
+import { useStore, useSwapStore, usePoolsStore } from '@/store';
import { d } from '@/utils/utils';
import SwapInfo from './SwapInfo.vue';
import SwapInput from './SwapInput.vue';
@@ -141,22 +135,21 @@ import {
VERSION_0,
VERSION_0_5,
CURVE_UNCORRELATED_V05,
- CURVE_UNCORRELATED
+ CURVE_UNCORRELATED,
} from '@/constants/constants';
import { getCurve, getShortCurveFromFull } from '@/utils/contracts';
-import { TVersionType } from "@/types";
+import { TCurveType, TVersionType } from '@/types';
+import { IPersistedPool } from '@/types/pools';
const mainStore = useStore();
const poolsStore = usePoolsStore();
const swapStore = useSwapStore();
-const tokensStore = useTokensStore();
const { account } = mainStore;
const version = computed(() => swapStore.version);
-const insideNativeWallet = computed(() => mainStore.insideNativeWallet.value);
const stableCurve = computed(() => getCurve('stable', version.value));
-const unstableCurve = computed(() => getCurve('uncorrelated', version.value));
+const unstableCurve = computed(() => getCurve('unstable', version.value));
const connected = computed(() => Boolean(account.value));
@@ -175,46 +168,43 @@ const curveType = computed(() =>
const fullCurveOfDefaultPool = computed(() => {
// Now all known pools have version 0
const isExistsDefaultPoolV0 = poolsStore.getCurveType(
- swapStore.fromCurrency?.token,
- swapStore.toCurrency?.token,
- VERSION_0,
+ swapStore.fromCurrency?.token,
+ swapStore.toCurrency?.token,
+ VERSION_0,
);
const isExistsDefaultPoolV05 = poolsStore.getCurveType(
- swapStore.fromCurrency?.token,
- swapStore.toCurrency?.token,
- VERSION_0_5,
+ swapStore.fromCurrency?.token,
+ swapStore.toCurrency?.token,
+ VERSION_0_5,
);
const hasDefaultPoolStableCurveV0 = [CURVE_STABLE, CURVE_STABLE_V05].includes(
- '' + isExistsDefaultPoolV0,
+ '' + isExistsDefaultPoolV0,
);
- const hasDefaultPoolStableCurveV05 = [
- CURVE_STABLE,
- CURVE_STABLE_V05,
- ].includes('' + isExistsDefaultPoolV05);
+ const hasDefaultPoolStableCurveV05 = [CURVE_STABLE, CURVE_STABLE_V05].includes(
+ '' + isExistsDefaultPoolV05,
+ );
- const hasDefaultPoolUncorrelatedCurveV0 = [
- CURVE_UNCORRELATED,
- CURVE_UNCORRELATED_V05,
- ].includes('' + isExistsDefaultPoolV0);
+ const hasDefaultPoolUncorrelatedCurveV0 = [CURVE_UNCORRELATED, CURVE_UNCORRELATED_V05].includes(
+ '' + isExistsDefaultPoolV0,
+ );
- const hasDefaultPoolUncorrelatedCurveV05 = [
- CURVE_UNCORRELATED,
- CURVE_UNCORRELATED_V05,
- ].includes('' + isExistsDefaultPoolV05);
+ const hasDefaultPoolUncorrelatedCurveV05 = [CURVE_UNCORRELATED, CURVE_UNCORRELATED_V05].includes(
+ '' + isExistsDefaultPoolV05,
+ );
if (
- (isExistsDefaultPoolV0 || isExistsDefaultPoolV05) &&
- (hasDefaultPoolStableCurveV0 || hasDefaultPoolStableCurveV05)
+ (isExistsDefaultPoolV0 || isExistsDefaultPoolV05) &&
+ (hasDefaultPoolStableCurveV0 || hasDefaultPoolStableCurveV05)
) {
return version.value === VERSION_0_5 ? CURVE_STABLE_V05 : CURVE_STABLE;
}
if (
- (isExistsDefaultPoolV0 || isExistsDefaultPoolV05) &&
- (hasDefaultPoolUncorrelatedCurveV0 || hasDefaultPoolUncorrelatedCurveV05)
+ (isExistsDefaultPoolV0 || isExistsDefaultPoolV05) &&
+ (hasDefaultPoolUncorrelatedCurveV0 || hasDefaultPoolUncorrelatedCurveV05)
) {
return version.value === VERSION_0_5 ? CURVE_UNCORRELATED_V05 : CURVE_UNCORRELATED;
}
@@ -223,41 +213,81 @@ const fullCurveOfDefaultPool = computed(() => {
});
watch([curveType, stableCurve, unstableCurve], () => {
- if (curveType.value) {
- swapStore.curve =
- curveType.value === stableCurve.value || curveType.value === 'stable'
- ? stableCurve.value
- : unstableCurve.value;
+ if (curveType.value) {
+ swapStore.curve =
+ curveType.value === stableCurve.value || curveType.value === 'stable'
+ ? stableCurve.value
+ : unstableCurve.value;
+ } else {
+ const shortName = getShortCurveFromFull(swapStore.curve);
+ const adaptedShoerName = shortName === 'uncorrelated' ? 'unstable' : 'stable';
+ swapStore.curve = getCurve(adaptedShoerName, version.value);
+ }
+});
+
+watch(
+ () => [swapStore.fromCurrency.token, swapStore.toCurrency.token],
+ async ([newFrom, newTo], [oldFrom, oldTo]) => {
+ if (!newFrom || !newTo) return;
+
+ // If the pair of tokens is the same, we don't need to set the curve
+ if (oldFrom === newTo && oldTo == newFrom) {
+ return;
}
- else {
- const shortName = getShortCurveFromFull(swapStore.curve);
- swapStore.curve = getCurve(shortName, version.value);
+
+ // need to reset the version when changing a pair of tokens
+ swapStore.version = VERSION_0;
+
+ let resultCurve: string | undefined;
+ let resultVersion: number = VERSION_0;
+ let resultPool: IPersistedPool | undefined;
+
+ for (const curveType of ['stable', 'unstable'] as TCurveType[]) {
+ for (const version of [VERSION_0_5, VERSION_0]) {
+ const curve = getCurve(curveType, version);
+
+ let pool = undefined;
+ try {
+ pool = await poolsStore.getPool(newFrom, newTo, curve, version);
+ } catch (error) {
+ console.error('SwapContainer: getPool', error);
+ }
+
+ if (
+ !resultPool ||
+ ((pool?.reserveX ?? 0) > resultPool.reserveX && (pool?.reserveY ?? 0) > resultPool.reserveY)
+ ) {
+ resultPool = pool;
+ resultCurve = curve;
+ resultVersion = version;
+ }
+ }
}
- },
-)
-const fromBalance = useCurrentAccountBalance(
- computed(() => swapStore.fromCurrency?.token),
-);
-const toBalance = useCurrentAccountBalance(
- computed(() => swapStore.toCurrency?.token),
+ /**
+ * Set uncorrelated pool version 0 as the default value.
+ * In this case, the user chooses the curve and version himself.
+ */
+ swapStore.curve = resultCurve;
+ swapStore.version = resultVersion;
+ },
);
+
+const fromBalance = useCurrentAccountBalance(computed(() => swapStore.fromCurrency?.token));
+const toBalance = useCurrentAccountBalance(computed(() => swapStore.toCurrency?.token));
const txSettingsDialog = ref();
const overlayAnchor = ref();
-const tokensChosen = computed(
- () => !!swapStore.fromCurrency.token && !!swapStore.toCurrency.token,
-);
+const tokensChosen = computed(() => !!swapStore.fromCurrency.token && !!swapStore.toCurrency.token);
const canSwitchContract = computed(() => {
const isToTokenChosen = swapStore.toCurrency?.token;
const isDefaultPool = !!fullCurveOfDefaultPool.value;
const hasDefaultPoolStableCurve = [CURVE_STABLE_V05, CURVE_STABLE].includes(
- '' + fullCurveOfDefaultPool.value,
+ '' + fullCurveOfDefaultPool.value,
);
const isPoolUnknown = fullCurveOfDefaultPool.value === false;
- const canSwitch =
- (isDefaultPool && hasDefaultPoolStableCurve) || isPoolUnknown;
+ const canSwitch = (isDefaultPool && hasDefaultPoolStableCurve) || isPoolUnknown;
return isToTokenChosen && canSwitch;
});
@@ -304,10 +334,7 @@ const buttonState = computed(() => {
};
}
- if (
- !toBalance.isExists.value &&
- !(toBalance.isFetching.value && toBalance.isFirstFetching.value)
- ) {
+ if (!toBalance.isExists.value && !(toBalance.isFetching.value && toBalance.isFirstFetching.value)) {
return {
disabled: false,
text: `Register ${toBalance.symbol.value} and Swap`,
@@ -322,18 +349,16 @@ const buttonState = computed(() => {
const priceImpactClass = computed(() => {
return swapStore.priceImpactState === 'normal'
- ? 'p-button-primary'
- : swapStore.priceImpactState === 'warning'
- ? 'p-button-warning_custom'
- : 'p-button-alert';
+ ? 'p-button-primary'
+ : swapStore.priceImpactState === 'warning'
+ ? 'p-button-warning_custom'
+ : 'p-button-alert';
});
function submitForm(e: Event) {
const isNextButton = (e.target as HTMLElement)?.enterKeyHint === 'next';
const isSubmitDisabled = buttonState.value.disabled;
- const cancelEvent = Boolean(
- (isNextButton || isSubmitDisabled) && connected.value,
- );
+ const cancelEvent = Boolean((isNextButton || isSubmitDisabled) && connected.value);
if (cancelEvent) return;
const handler = !connected.value ? onConnectWallet : showSwapDialog;
@@ -350,8 +375,7 @@ function toggleSwap() {
function showSwapDialog() {
const isShowSwapWarningDialog =
- swapStore.priceImpactState === 'warning' ||
- swapStore.priceImpactState === 'alert';
+ swapStore.priceImpactState === 'warning' || swapStore.priceImpactState === 'alert';
if (isShowSwapWarningDialog) {
mainStore.showDialog('priceImpact');
diff --git a/src/Swap/SwapInfo.vue b/src/Swap/SwapInfo.vue
index 56eaaa3..27a79a4 100644
--- a/src/Swap/SwapInfo.vue
+++ b/src/Swap/SwapInfo.vue
@@ -110,7 +110,7 @@ const slippageAmount = computed(() => swap.slippageAmount);
const hasSlippage = computed(
() =>
(version.value === VERSION_0 &&
- swap.curve === getCurve('uncorrelated', version.value)) ||
+ swap.curve === getCurve('unstable', version.value)) ||
version.value === VERSION_0_5,
);
diff --git a/src/components/ButtonToken/buttonToken.scss b/src/components/ButtonToken/buttonToken.scss
index 9c41302..b4228ba 100644
--- a/src/components/ButtonToken/buttonToken.scss
+++ b/src/components/ButtonToken/buttonToken.scss
@@ -10,7 +10,7 @@
color: white;
&:hover {
- background: linear-gradient(90deg, #015c68 0%, #04a57d 100%);
+ background: linear-gradient(90deg, #015c68 0%, #04a57d 100%) !important;
color: white;
}
diff --git a/src/components/ContractSwitch/ContractSwitch.vue b/src/components/ContractSwitch/ContractSwitch.vue
index 4ca02aa..e88f987 100644
--- a/src/components/ContractSwitch/ContractSwitch.vue
+++ b/src/components/ContractSwitch/ContractSwitch.vue
@@ -3,9 +3,9 @@
Pool Version
@@ -14,9 +14,11 @@
:options="poolVersionOptions"
option-disabled="disabled"
option-value="value"
+ data-tid="pool-version-switch-container"
option-label="label"
class="ml-auto no-a11y"
:unselectable="false"
+ :disabled="!canSwitchVersion"
>
{{ slotProps.option.label }}
@@ -28,42 +30,104 @@
diff --git a/src/components/CurveSwitch/CurveSwitch.vue b/src/components/CurveSwitch/CurveSwitch.vue
index e59dc70..d184115 100644
--- a/src/components/CurveSwitch/CurveSwitch.vue
+++ b/src/components/CurveSwitch/CurveSwitch.vue
@@ -3,15 +3,17 @@
Uncorrelated
-
+
@@ -20,8 +22,10 @@
isSelected: store.curve === curveStable,
busy: isBusy,
}"
+ :disabled="isStablePoolAbsent"
class="stable-switch-container__switch"
- @click="switchSelected(curveStable)"
+ data-tid="curve-switch-stable"
+ @click="!isStablePoolAbsent && switchSelected(curveStable)"
>
Stable
-
+
@@ -41,37 +45,40 @@ import { computed, watch } from 'vue';
import { useToast } from 'primevue/usetoast';
import PToast from 'primevue/toast';
import ToolTip from '@/components/ToolTip/Tooltip.vue';
-import {
- useSwapStore,
- useTokensStore,
-} from '@/store';
+import { useSwapStore, useTokensStore } from '@/store';
import { getCurve } from '@/utils/contracts';
+import { TCurveType } from '@/types';
+import { usePoolExistence } from '@/composables/usePoolExistence';
const toast = useToast();
const store = useSwapStore();
const tokenStore = useTokensStore();
+const poolExistence = usePoolExistence();
+
+interface IProps {
+ curve?: string;
+ version?: number;
+}
+
+defineProps();
const version = computed(() => store.version);
const curveStable = computed(() => getCurve('stable', version.value));
-const curveUncorrelated = computed(() => getCurve('uncorrelated', version.value));
+const curveUnstable = computed(() => getCurve('unstable', version.value));
+const isBusy = computed(() => (store.isBusy !== undefined ? store.isBusy.value : false));
-const isBusy = computed(() =>
- store.isBusy !== undefined ? store.isBusy.value : false,
+const isStableV0PoolAbsent = computed(() => computeIsPoolAbsent('stable', 0));
+const isStableV05PoolAbsent = computed(() => computeIsPoolAbsent('stable', 0.5));
+const isStablePoolAbsent = computed(() => isStableV0PoolAbsent.value && isStableV05PoolAbsent.value);
+const isUnstableV0PoolAbsent = computed(() => computeIsPoolAbsent('unstable', 0));
+const isUnstableV05PoolAbsent = computed(() => computeIsPoolAbsent('unstable', 0.5));
+const isUnstablePoolAbsent = computed(
+ () => isUnstableV0PoolAbsent.value && isUnstableV05PoolAbsent.value,
);
-const switchSelected = (curve: string) => {
- if (isBusy.value === true) return;
- store.curve = curve;
-};
-
watch(
- [
- () => store.fromCurrency.token,
- () => store.toCurrency.token,
- () => store.curve,
- () => store.version,
- ],
+ [() => store.fromCurrency.token, () => store.toCurrency.token, () => store.curve, () => store.version],
() => {
if (
store.curve === curveStable.value &&
@@ -88,7 +95,60 @@ watch(
group: 'tr',
});
}
+
+ checkPoolExistence('stable', 0);
+ checkPoolExistence('stable', 0.5);
+
+ checkPoolExistence('unstable', 0);
+ checkPoolExistence('unstable', 0.5);
},
{ deep: true },
);
+
+function computeIsPoolAbsent(curveType: TCurveType, version: number) {
+ const curve = getCurve(curveType, version);
+
+ return (
+ Boolean(store.fromCurrency.token) &&
+ Boolean(store.toCurrency.token) &&
+ !poolExistence.isFetching(
+ {
+ fromCoin: store.fromCurrency.token ?? '',
+ toCoin: store.toCurrency.token ?? '',
+ curve,
+ },
+ version,
+ ) &&
+ !poolExistence.poolExists(
+ {
+ fromCoin: store.fromCurrency.token ?? '',
+ toCoin: store.toCurrency.token ?? '',
+ curve,
+ },
+ version,
+ )
+ );
+}
+
+async function checkPoolExistence(curveType: TCurveType, version: number) {
+ const curve = getCurve(curveType, version);
+
+ if (!store.fromCurrency.token || !store.toCurrency.token || !curve) {
+ return;
+ }
+
+ await poolExistence.check(
+ {
+ fromCoin: store.fromCurrency.token,
+ toCoin: store.toCurrency.token,
+ curve,
+ },
+ version,
+ );
+}
+
+const switchSelected = (curve: string) => {
+ if (isBusy.value === true) return;
+ store.curve = curve;
+};
diff --git a/src/components/SwapConfirm/SwapInfo.vue b/src/components/SwapConfirm/SwapInfo.vue
index de841e6..232c909 100644
--- a/src/components/SwapConfirm/SwapInfo.vue
+++ b/src/components/SwapConfirm/SwapInfo.vue
@@ -78,7 +78,7 @@ const slippageAmount = computed(() => swapStore.slippageAmount);
const hasSlippage = computed(
() =>
(version.value === VERSION_0 &&
- swapStore.curve === getCurve('uncorrelated', version.value)) ||
+ swapStore.curve === getCurve('unstable', version.value)) ||
version.value === VERSION_0_5,
);
diff --git a/src/components/TxSettingsDialog/TxSettingsDialog.vue b/src/components/TxSettingsDialog/TxSettingsDialog.vue
index 0c8719b..10797c9 100644
--- a/src/components/TxSettingsDialog/TxSettingsDialog.vue
+++ b/src/components/TxSettingsDialog/TxSettingsDialog.vue
@@ -133,7 +133,7 @@ const slippage = createSyncRef('modelValue');
const hasSlippage = computed(
() =>
(version.value === VERSION_0 &&
- swapStore.curve === getCurve('uncorrelated', version.value)) ||
+ swapStore.curve === getCurve('unstable', version.value)) ||
version.value === VERSION_0_5,
);
diff --git a/src/composables/usePoolExistence.ts b/src/composables/usePoolExistence.ts
index 6894718..e48cf10 100644
--- a/src/composables/usePoolExistence.ts
+++ b/src/composables/usePoolExistence.ts
@@ -1,46 +1,89 @@
-import { Ref, ref, watch } from 'vue';
+import { Ref, reactive, watch } from 'vue';
import { ICreateToken, IPoolExist, TVersionType } from '@/types';
-import { useStore } from "@/store";
+import { useStore } from '@/store';
+import { VERSION_0, VERSION_0_5 } from '@/constants/constants';
+import { getShortCurveFromFull } from '@/utils/contracts';
type CurveType = 'stable' | 'uncorrelated';
+interface IPoolExistence {
+ exists: boolean;
+ isFetching: boolean;
+}
+
+function getPoolExistenceKey(params: IPoolExist, contract?: number) {
+ return `${params.fromCoin}|${params.toCoin}|${params.curve}|${contract}`;
+}
+
+const poolExistenceMap = reactive>({});
+
export function usePoolExistence() {
const mainStore = useStore();
const sdk = mainStore.sdk;
- const poolExists = ref(false);
- const isFetching = ref(false);
+ function getPoolExistenceEntity(params: IPoolExist, contract?: number) {
+ const poolExistenceKey = getPoolExistenceKey(params, contract);
- async function checkExistence(params: IPoolExist): Promise {
- isFetching.value = true;
- if (params.curve === undefined) {
- throw new Error('Curve type is undefined');
- }
- try {
- const response = await sdk.value.Swap.getLiquidityPoolResource({
- fromToken: params.fromCoin,
- toToken: params.toCoin,
- curveType: params.curve as CurveType,
- version: params.version,
- });
- isFetching.value = false;
- return !!response.liquidityPoolResource;
- } catch (error) {
-
- console.log('check Pool Existence error', error);
- return false;
- } finally {
- isFetching.value = false;
+ return poolExistenceMap[poolExistenceKey] ?? {};
+ }
+
+ function poolExists(params: IPoolExist, contract?: number) {
+ return getPoolExistenceEntity(params, contract).exists;
+ }
+
+ function isFetching(params: IPoolExist, contract?: number) {
+ return getPoolExistenceEntity(params, contract).isFetching;
+ }
+
+ async function checkExistence(params: IPoolExist, contract?: number) {
+ const poolExistenceKey = getPoolExistenceKey(params, contract);
+
+ if (!poolExistenceMap[poolExistenceKey]) {
+ poolExistenceMap[poolExistenceKey] = {
+ exists: false,
+ isFetching: false,
+ };
}
+
+ poolExistenceMap[poolExistenceKey].isFetching = true;
+
+ const shortCurve = getShortCurveFromFull(params.curve);
+ const res = await sdk.value.Swap.getLiquidityPoolResource({
+ fromToken: params.fromCoin,
+ toToken: params.toCoin,
+ curveType: shortCurve as CurveType,
+ version: contract == VERSION_0 ? VERSION_0 : VERSION_0_5,
+ });
+
+ poolExistenceMap[poolExistenceKey].isFetching = false;
+ return !!res.liquidityPoolResource;
}
- async function check(params: IPoolExist) {
- poolExists.value = await checkExistence(params);
+ async function check(params: IPoolExist, contract?: number) {
+ const poolExistenceKey = getPoolExistenceKey(params, contract);
+
+ if (!poolExistenceMap[poolExistenceKey]) {
+ poolExistenceMap[poolExistenceKey] = {
+ exists: false,
+ isFetching: false,
+ };
+ }
+ const res = await checkExistence(params, contract);
+ poolExistenceMap[poolExistenceKey].exists = res;
}
- function reset() {
- poolExists.value = false;
+ function reset(params: IPoolExist, contract?: number) {
+ const poolExistenceKey = getPoolExistenceKey(params, contract);
+
+ if (!poolExistenceMap[poolExistenceKey]) {
+ poolExistenceMap[poolExistenceKey] = {
+ exists: false,
+ isFetching: false,
+ };
+ }
+
+ poolExistenceMap[poolExistenceKey].exists = false;
}
function watchChanges(
@@ -53,14 +96,23 @@ export function usePoolExistence() {
[from.token, to.token, curve.value, version.value],
async () => {
if (!from.token || !to.token) {
- reset();
+ reset(
+ {
+ fromCoin: from.token ?? '',
+ toCoin: to.token ?? '',
+ curve: curve.value,
+ },
+ version?.value,
+ );
} else {
- await check({
- fromCoin: from.token,
- toCoin: to.token,
- curve: curve.value,
- version: version.value
- });
+ await check(
+ {
+ fromCoin: from.token,
+ toCoin: to.token,
+ curve: curve.value,
+ },
+ version.value,
+ );
}
},
{
@@ -70,11 +122,8 @@ export function usePoolExistence() {
}
return {
- // data
isFetching,
poolExists,
-
- // methods
check,
watch: watchChanges,
reset,
diff --git a/src/store/usePoolsStore.ts b/src/store/usePoolsStore.ts
index 2b8f772..76f389b 100644
--- a/src/store/usePoolsStore.ts
+++ b/src/store/usePoolsStore.ts
@@ -9,16 +9,10 @@ import { IPoolBase, IPersistedPool, IPoolInfo } from '@/types/pools';
import { IStorageBasic, TVersionType } from '@/types';
import { getCurve, getResourcesAccount, getContractVersionFromCurve } from '@/utils/contracts';
-import {
- getPoolLpInfoStr,
- getPoolLpStr,
- getPoolStr,
- getTitleForPool,
- destructCoinStorePoolStr,
-} from '@/utils/pools';
+import { getPoolLpInfoStr, getPoolLpStr, getPoolStr, getTitleForPool, destructCoinStorePoolStr } from '@/utils/pools';
import { useStore } from './useStore';
-import {CurveType} from "@pontem/liquidswap-sdk/dist/tsc/types/aptos";
+import { CurveType } from '@pontem/liquidswap-sdk/dist/tsc/types/aptos';
interface IStorage extends IStorageBasic {
pools: IPersistedPool[];
@@ -44,12 +38,7 @@ export const usePoolsStore = defineStore('poolsStore', () => {
/**
* To store added reserves
*/
- const poolsStorage = useStorage(
- 'pontemPools',
- { pools: [], version: 1 },
- window.localStorage,
- { writeDefaults: true },
- );
+ const poolsStorage = useStorage('pontemPools', { pools: [], version: 1 }, window.localStorage, { writeDefaults: true });
/**
* Storage for all loaded pools
@@ -58,7 +47,7 @@ export const usePoolsStore = defineStore('poolsStore', () => {
async function fetchPoolsList() {
const pools = CoinsRegistry.getPoolsFor(CORRECT_CHAIN) as IPoolInfo[];
- const mappedPools = pools.map(item => ({ ...item, curve: item.curve === 'unstable' ? 'uncorrelated' : item.curve }));
+ const mappedPools = pools.map((item) => ({ ...item, curve: item.curve === 'unstable' ? 'uncorrelated' : item.curve }));
registerPools(mappedPools);
fetchAndFillAPRs();
}
@@ -132,15 +121,9 @@ export const usePoolsStore = defineStore('poolsStore', () => {
if (!mainStore.account.value?.address) return;
const { networkId } = mainStore;
- const resources = await aptos.getAccountResources(
- mainStore.account.value.address,
- );
+ const resources = await aptos.getAccountResources(mainStore.account.value.address);
resources.forEach((element: any) => {
- if (
- element.type.indexOf('::stake::') !== -1 ||
- element.type.indexOf('lp_coin') === -1
- )
- return;
+ if (element.type.indexOf('::stake::') !== -1 || element.type.indexOf('lp_coin') === -1) return;
const [coinX, coinY, curveType] = destructCoinStorePoolStr(element.type);
const lpVersion = getContractVersionFromCurve(curveType);
const poolStr = getPoolStr(coinX, coinY, curveType, lpVersion);
@@ -170,10 +153,7 @@ export const usePoolsStore = defineStore('poolsStore', () => {
* @param canClean
* @returns
*/
- function persistToStorage(
- _pools: Record,
- canClean?: boolean,
- ) {
+ function persistToStorage(_pools: Record, canClean?: boolean) {
const persistingKeys = Object.keys(_pools).filter((key) => {
return _pools[key].addedX > 0 || _pools[key].addedY > 0;
});
@@ -192,10 +172,7 @@ export const usePoolsStore = defineStore('poolsStore', () => {
async function fetchReserves(liquidityPool: string, pool: IPersistedPool, contract?: TVersionType) {
const resourceAccount = getResourcesAccount(contract);
- const response = await aptos.getAccountResource(
- resourceAccount,
- liquidityPool,
- ) as unknown as Promise | any;
+ const response = (await aptos.getAccountResource(resourceAccount, liquidityPool)) as unknown as Promise | any;
if (!response) return;
@@ -206,10 +183,7 @@ export const usePoolsStore = defineStore('poolsStore', () => {
async function fetchLp(lpCoin: string, pool: IPersistedPool, contract?: TVersionType) {
try {
const resourcesAccount = getResourcesAccount(contract);
- const response = await aptos.getAccountResource(
- resourcesAccount,
- lpCoin,
- ) as unknown as Promise | any;
+ const response = (await aptos.getAccountResource(resourcesAccount, lpCoin)) as unknown as Promise | any;
if (!response || !response?.data?.supply?.vec[0]) return;
@@ -222,24 +196,15 @@ export const usePoolsStore = defineStore('poolsStore', () => {
const loadPool = async (pool: IPersistedPool) => {
const { coinX, coinY, curve, contract } = pool;
const curveStable = getCurve('stable', contract);
- const curveType =
- curve === 'stable' || curve === curveStable
- ? curveStable
- : getCurve('uncorrelated', contract);
+ const curveType = curve === 'stable' || curve === curveStable ? curveStable : getCurve('unstable', contract);
const liquidityPool = getPoolStr(coinX, coinY, curveType, contract);
const lpCoinInfo = getPoolLpInfoStr(getPoolLpStr(coinX, coinY, curveType, contract));
- await Promise.all([
- fetchReserves(liquidityPool, pool, contract),
- fetchLp(lpCoinInfo, pool, contract),
- ]);
+ await Promise.all([fetchReserves(liquidityPool, pool, contract), fetchLp(lpCoinInfo, pool, contract)]);
return pool;
};
- async function registerPool(
- pool: IPoolBase,
- { rewrite = false, isDefault = false, lazy = true },
- ) {
+ async function registerPool(pool: IPoolBase, { rewrite = false, isDefault = false, lazy = true }) {
const { coinX, coinY, curve, networkId, contract } = pool as IPoolInfo;
const isSorted = is_sorted(coinX, coinY);
@@ -248,14 +213,19 @@ export const usePoolsStore = defineStore('poolsStore', () => {
const curveType = ['stable', 'uncorrelated'].includes(curve)
? curve === 'stable'
? getCurve('stable', contract)
- : getCurve('uncorrelated', contract)
+ : getCurve('unstable', contract)
: curve;
const liquidityPool = getPoolStr(sortedX, sortedY, curveType, contract);
let isPoolExist = false;
try {
- const response = await sdk.value.Swap.getLiquidityPoolResource({fromToken: sortedX, toToken: sortedY, curveType: curve as CurveType, version: contract});
+ const response = await sdk.value.Swap.getLiquidityPoolResource({
+ fromToken: sortedX,
+ toToken: sortedY,
+ curveType: curve as CurveType,
+ version: contract,
+ });
if (response && response.liquidityPoolResource) {
isPoolExist = true;
}
@@ -275,9 +245,7 @@ export const usePoolsStore = defineStore('poolsStore', () => {
}
if (isDefault && ['stable', 'uncorrelated'].includes(curve)) {
- predefinedCurves[curve as 'stable' | 'uncorrelated'].add(
- `${sortedX}-${sortedY}-${contract}`,
- );
+ predefinedCurves[curve as 'stable' | 'uncorrelated'].add(`${sortedX}-${sortedY}-${contract}`);
}
const title = getTitleForPool(sortedX, sortedY);
@@ -296,7 +264,6 @@ export const usePoolsStore = defineStore('poolsStore', () => {
contract,
});
-
poolsMap[liquidityPool] = persistedPool;
const poolTitleKey = `${title}-${curve}-${contract}`;
poolsTitleMap[poolTitleKey] = liquidityPool;
@@ -345,35 +312,27 @@ export const usePoolsStore = defineStore('poolsStore', () => {
* @param curve string
* @returns Promise
*/
- const getPool = computed(
- () =>
- async (
- coinX: string,
- coinY: string,
- curve: string,
- contract?: TVersionType,
- ): Promise => {
- const liquidityPool = getPoolStr(coinX, coinY, curve, contract);
- let registeredPool = poolsMap[liquidityPool];
- if (!registeredPool) {
- const { networkId } = mainStore;
- registeredPool = await registerPool(
- {
- coinX,
- coinY,
- curve,
- networkId: networkId.value,
- contract,
- },
- {
- rewrite: true,
- lazy: false,
- },
- ) as IPersistedPool;
- }
- return registeredPool;
- },
- );
+ const getPool = computed(() => async (coinX: string, coinY: string, curve: string, contract?: TVersionType): Promise => {
+ const liquidityPool = getPoolStr(coinX, coinY, curve, contract);
+ let registeredPool = poolsMap[liquidityPool];
+ if (!registeredPool) {
+ const { networkId } = mainStore;
+ registeredPool = (await registerPool(
+ {
+ coinX,
+ coinY,
+ curve,
+ networkId: networkId.value,
+ contract,
+ },
+ {
+ rewrite: true,
+ lazy: false,
+ },
+ )) as IPersistedPool;
+ }
+ return registeredPool;
+ });
const defaultPools = computed(() =>
Object.keys(poolsMap)
@@ -389,21 +348,15 @@ export const usePoolsStore = defineStore('poolsStore', () => {
* @param version - version of pools
* @returns correct curve with correct moduleAddress according to version
*/
- function getCurveType(
- coinX?: string,
- coinY?: string,
- version?: number,
- ): string | false {
+ function getCurveType(coinX?: string, coinY?: string, version?: number): string | false {
if (!coinX || !coinY) return false;
- const [sortedX, sortedY] = is_sorted(coinX, coinY)
- ? [coinX, coinY]
- : [coinY, coinX];
+ const [sortedX, sortedY] = is_sorted(coinX, coinY) ? [coinX, coinY] : [coinY, coinX];
const tokenPair = `${sortedX}-${sortedY}-${version}`;
return predefinedCurves.stable.has(tokenPair)
? getCurve('stable', version)
: predefinedCurves.uncorrelated.has(tokenPair)
- ? getCurve('uncorrelated', version)
- : false;
+ ? getCurve('unstable', version)
+ : false;
}
return {
diff --git a/src/store/useSwapStore.ts b/src/store/useSwapStore.ts
index 8cb8ca0..9f0c71c 100644
--- a/src/store/useSwapStore.ts
+++ b/src/store/useSwapStore.ts
@@ -8,13 +8,12 @@ import { useStore } from '@/store/useStore';
import { is_sorted, d, decimalsMultiplier } from '@/utils/utils';
import { usePoolsStore, useTokensStore } from '@/store';
import { getFromCache } from '@/utils/cache';
-import {DENOMINATOR, VERSION_0_5, VERSION_0, CURVE_STABLE, CURVE_STABLE_V05} from '@/constants/constants';
+import { DENOMINATOR, VERSION_0_5, VERSION_0 } from '@/constants/constants';
import { usePoolExistence } from '@/composables/usePoolExistence';
import { useContractVersion } from '@/composables/useContractVersion';
import { IStoredToken, TVersionType } from '@/types';
import { getCurve, getResourcesAccount, getShortCurveFromFull } from '@/utils/contracts';
-import { PontemWalletName } from "@pontem/aptos-wallet-adapter";
-
+import { PontemWalletName } from '@pontem/aptos-wallet-adapter';
const DEFAULT_SLIPPAGE = 0.005;
@@ -31,7 +30,6 @@ export const useSwapStore = defineStore('swapStore', () => {
amount: undefined,
reserve: 0,
usdEquivalent: undefined,
-
});
const { version } = useContractVersion();
@@ -40,7 +38,7 @@ export const useSwapStore = defineStore('swapStore', () => {
const mainStore = useStore();
const { sdk } = mainStore;
- const curve = ref(getCurve('uncorrelated', version.value));
+ const curve = ref('stable');
const stableSwapType = ref<'high' | 'normal'>('normal');
const poolExistence = usePoolExistence();
@@ -72,8 +70,7 @@ export const useSwapStore = defineStore('swapStore', () => {
});
watch([tokensStore.tokens], () => {
- from.token =
- tokensStore.getToken(from.token)?.type || mainStore.defaultToken.value;
+ from.token = tokensStore.getToken(from.token)?.type || mainStore.defaultToken.value;
to.token =
from.token !== tokensStore.getToken(to.token)?.type
? tokensStore.getToken(to.token)?.type
@@ -83,7 +80,7 @@ export const useSwapStore = defineStore('swapStore', () => {
onMounted(() => resetState());
function resetState() {
- version.value = 0;
+ version.value = VERSION_0;
from.token = mainStore.defaultToken.value;
to.token = undefined;
from.amount = undefined;
@@ -95,11 +92,7 @@ export const useSwapStore = defineStore('swapStore', () => {
to.usdEquivalent = undefined;
}
- function convertToDecimals(
- amt?: number,
- fromToken?: string,
- toToken?: string,
- ) {
+ function convertToDecimals(amt?: number, fromToken?: string, toToken?: string) {
if (!amt || !fromToken || !toToken) {
return amt;
}
@@ -129,7 +122,7 @@ export const useSwapStore = defineStore('swapStore', () => {
}
async function refetchRates(silent = false): Promise {
- if (from.token && to.token) {
+ if (from.token && to.token && curve.value) {
lastInteractiveField.value = interactiveField.value;
if (!silent) {
isUpdatingRate.value = true;
@@ -137,9 +130,7 @@ export const useSwapStore = defineStore('swapStore', () => {
const mode = lastInteractiveField.value;
const isSorted = is_sorted(from.token, to.token);
- const [fromToken, toToken] = isSorted
- ? [from.token, to.token]
- : [to.token, from.token];
+ const [fromToken, toToken] = isSorted ? [from.token, to.token] : [to.token, from.token];
const resourceType = getPoolStr(fromToken, toToken, curve.value, version.value as TVersionType);
@@ -156,7 +147,6 @@ export const useSwapStore = defineStore('swapStore', () => {
fee.value = response.data.fee;
from.reserve = isSorted ? coinXReserve : coinYReserve;
to.reserve = isSorted ? coinYReserve : coinXReserve;
-
} catch (e) {
from.reserve = 0;
to.reserve = 0;
@@ -180,15 +170,12 @@ export const useSwapStore = defineStore('swapStore', () => {
interactiveToken: mode,
curveType: getShortCurveFromFull(curve.value) as 'stable' | 'uncorrelated',
amount: mode === 'from' ? from.amount! : to.amount!,
- version: version.value as unknown as TVersionType
+ version: version.value as unknown as TVersionType,
});
- } catch(_e) {
- }
+ } catch (_e) {}
convertError.value =
- to.amount && to.reserve < to.amount
- ? 'Insufficient funds in Liquidity Pool'
- : undefined;
+ to.amount && to.reserve < to.amount ? 'Insufficient funds in Liquidity Pool' : undefined;
if (d(rate).lessThanOrEqualTo(0) || !isFinite(Number(rate))) {
if (!silent) {
isUpdatingRate.value = false;
@@ -203,24 +190,15 @@ export const useSwapStore = defineStore('swapStore', () => {
from.amount = +Number(Number(rate).toFixed(0));
}
- const toDec = d(to.amount).div(
- decimalsMultiplier(tokensStore.tokens[to.token].decimals),
- );
- const fromDec = d(from.amount).div(
- decimalsMultiplier(tokensStore.tokens[from.token].decimals),
- );
+ const toDec = d(to.amount).div(decimalsMultiplier(tokensStore.tokens[to.token].decimals));
+ const fromDec = d(from.amount).div(decimalsMultiplier(tokensStore.tokens[from.token].decimals));
convertRate.value = +Number(
- toDec
- .div(fromDec)
- .mul(decimalsMultiplier(tokensStore.tokens[to.token].decimals))
- .toFixed(0),
+ toDec.div(fromDec).mul(decimalsMultiplier(tokensStore.tokens[to.token].decimals)).toFixed(0),
);
convertFee.value = (fee.value * 100) / DENOMINATOR;
convertFeeAmount.value =
- from?.amount && from.amount > 0
- ? from.amount * convertFee.value * 0.01
- : 0;
+ from?.amount && from.amount > 0 ? from.amount * convertFee.value * 0.01 : 0;
if (!silent) {
isUpdatingRate.value = false;
}
@@ -232,33 +210,20 @@ export const useSwapStore = defineStore('swapStore', () => {
async function check() {
if (!from?.token || !to?.token || !curve.value) return;
- await poolExistence.check({
- fromCoin: from.token,
- toCoin: to.token,
- curve: getShortCurveFromFull(curve.value) as 'stable' | 'uncorrelated',
- version: version.value as unknown as TVersionType,
- });
+
+ await poolExistence.check(
+ {
+ fromCoin: from.token,
+ toCoin: to.token,
+ curve: curve.value,
+ },
+ version.value,
+ );
}
watchDebounced(
- () => [
- version,
- from.amount,
- from.reserve,
- from.token,
- to.amount,
- to.reserve,
- to.token,
- curve
- ],
- async (_newState,_oldState) => {
- // if we switch tokens to a new value
- if (
- predefinedCurve.value !== false &&
- predefinedCurve.value === getCurve('uncorrelated', version.value)
- ) {
- version.value = VERSION_0;
- }
+ () => [version, from.amount, from.reserve, from.token, to.amount, to.reserve, to.token, curve],
+ async (_changed) => {
await check();
refetchRates(false);
},
@@ -275,33 +240,43 @@ export const useSwapStore = defineStore('swapStore', () => {
const slippagePercent = slippage.value * MULTIPLY;
if (lastInteractiveField.value === 'from' && to.amount !== undefined) {
- return version.value === VERSION_0_5 ||
- curve.value === getCurve('uncorrelated', version.value)
+ return version.value === VERSION_0_5 || curve.value === getCurve('unstable', version.value)
? to.amount - (to.amount * slippagePercent) / MULTIPLY
: to.amount - 1;
- } else if (
- lastInteractiveField.value === 'to' &&
- from.amount !== undefined
- ) {
- return version.value === VERSION_0_5 ||
- curve.value === getCurve('uncorrelated', version.value)
+ } else if (lastInteractiveField.value === 'to' && from.amount !== undefined) {
+ return version.value === VERSION_0_5 || curve.value === getCurve('unstable', version.value)
? from.amount + (from.amount * slippagePercent) / MULTIPLY
: from.amount;
}
return 0;
});
+ /**
+ * Pool is absence
+ */
const isPoolAbsence = computed(
- () =>
+ (): boolean =>
!!from.token &&
!!to.token &&
- !poolExistence.isFetching.value &&
- !poolExistence.poolExists.value,
+ !poolExistence.isFetching(
+ {
+ fromCoin: from.token,
+ toCoin: to.token,
+ curve: curve.value ?? '',
+ },
+ version.value,
+ ) &&
+ !poolExistence.poolExists(
+ {
+ fromCoin: from.token,
+ toCoin: to.token,
+ curve: curve.value ?? '',
+ },
+ version.value,
+ ),
);
- const isBusy = computed(
- () => poolExistence.isFetching || isUpdatingRate.value,
- );
+ const isBusy = computed(() => poolExistence.isFetching || isUpdatingRate.value);
const priceImpact = computed(() => {
if (!from?.amount || !from.reserve || !to.reserve) return 0;
@@ -320,14 +295,11 @@ export const useSwapStore = defineStore('swapStore', () => {
maximumFractionDigits: 2,
});
- const priceImpactFormatted = computed(() =>
- formatter.format(priceImpact.value),
- );
+ const priceImpactFormatted = computed(() => formatter.format(priceImpact.value));
const priceImpactState = computed(() => {
if (+priceImpactFormatted.value <= 10) return 'normal';
- if (+priceImpactFormatted.value >= 10 && +priceImpactFormatted.value < 20)
- return 'warning';
+ if (+priceImpactFormatted.value >= 10 && +priceImpactFormatted.value < 20) return 'warning';
return 'alert';
});
diff --git a/src/styles/components/curveSwitch.scss b/src/styles/components/curveSwitch.scss
new file mode 100644
index 0000000..52cd326
--- /dev/null
+++ b/src/styles/components/curveSwitch.scss
@@ -0,0 +1,50 @@
+.stable-switch-container {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ padding: 8px;
+ gap: 4px;
+ background: #272742;
+ border-radius: 12px;
+ width: 100%;
+
+ &__switch {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+ padding: 4px 10px;
+ gap: 8px;
+ width: 100%;
+ cursor: pointer;
+ transition: all 0.5s linear;
+
+ &.busy {
+ cursor: default;
+ opacity: 0.5;
+ }
+
+ &[disabled='true'] {
+ opacity: 0.5;
+ }
+
+ p {
+ font-family: var(--font-family);
+ font-style: normal;
+ font-weight: 500;
+ font-size: 16px;
+ line-height: 120%;
+ color: #ffffff;
+ margin-block: 0rem;
+ }
+
+ i {
+ opacity: 0.5;
+ }
+ }
+}
+
+.isSelected {
+ background: #4d4d70;
+ border-radius: 12px;
+}
\ No newline at end of file
diff --git a/src/styles/index.scss b/src/styles/index.scss
index 9529501..f130902 100644
--- a/src/styles/index.scss
+++ b/src/styles/index.scss
@@ -16,4 +16,5 @@
@import '../components/ButtonToken/buttonToken';
@import '../components/FrontrunOverlay/frontRunOverlay';
@import '../components/PriceImpactWarningDialog/PriceImpactWarningDialog';
+@import '../styles//components/curveSwitch.scss';
diff --git a/src/types/index.ts b/src/types/index.ts
index 2bac085..44acfab 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -8,7 +8,7 @@ import {
WalletName,
} from '@pontem/aptos-wallet-adapter';
-import { VERSION_0, VERSION_0_5 } from "@/constants/constants";
+import { VERSION_0, VERSION_0_5 } from '@/constants/constants';
export type AptosCoinInfoResource = {
decimals: string;
@@ -42,7 +42,9 @@ export interface IWallet {
options?: any;
}
-export type TCurveType = 'uncorrelated' | 'stable' | 'selectable';
+// export type TCurveType = 'uncorrelated' | 'stable' | 'selectable';
+
+export type TCurveType = 'unstable' | 'stable';
export type TStableSwapType = 'normal' | 'high';
@@ -77,9 +79,7 @@ export interface IPoolExist {
fromCoin: string;
toCoin: string;
curve: string;
- version: TVersionType;
}
-export type TStatusTransaction = "success" | "pending" | "error" | "rejected";
-
+export type TStatusTransaction = 'success' | 'pending' | 'error' | 'rejected';
diff --git a/src/utils/contracts.ts b/src/utils/contracts.ts
index af1ee4b..a52943b 100644
--- a/src/utils/contracts.ts
+++ b/src/utils/contracts.ts
@@ -69,7 +69,7 @@ export function getCurve(type: TCurveType, contract?: number): string {
}
return CURVE_UNCORRELATED_V05;
}
- if (type === 'uncorrelated') {
+ if (type === 'unstable') {
return CURVE_UNCORRELATED;
}
return CURVE_STABLE;
@@ -81,7 +81,7 @@ export function getCurve(type: TCurveType, contract?: number): string {
* @param type full type of curve
* @returns short curve name
*/
-export function getShortCurveFromFull(type: string): TCurveType {
+export function getShortCurveFromFull(type: string): 'stable' | 'uncorrelated' {
if (type === CURVE_STABLE || type === CURVE_STABLE_V05) return 'stable';
if (type === CURVE_UNCORRELATED || type === CURVE_UNCORRELATED_V05) return 'uncorrelated';
throw new Error('Wrong curve type passed');
diff --git a/src/utils/tokens.ts b/src/utils/tokens.ts
index 430647d..9f8c454 100644
--- a/src/utils/tokens.ts
+++ b/src/utils/tokens.ts
@@ -16,6 +16,7 @@ const TITLES: Record = {
wormhole: 'Wormhole',
chainx: 'ChainX',
celer: 'Celer',
+ multichain: 'Multichain',
};
export function titleForToken(token: IPersistedToken) {
diff --git a/yarn.lock b/yarn.lock
index 373d1d4..f3041b9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -307,10 +307,10 @@
react-dom "^18.X.X || 17.X.X"
vue "3.2.40"
-"@pontem/coins-registry@2.1.8":
- version "2.1.8"
- resolved "https://registry.yarnpkg.com/@pontem/coins-registry/-/coins-registry-2.1.8.tgz#730e807d83da00972aadc2b6d93aae5f3455c938"
- integrity sha512-EdFgaS8Pw7MJU2slLC9N5G2UH/gEgLTixT5Ad+BE1y+fqYyxyPLd/xfpbNwSZGwz+gAO3sNVjehoFZZhvbEnHA==
+"@pontem/coins-registry@2.1.19":
+ version "2.1.19"
+ resolved "https://registry.yarnpkg.com/@pontem/coins-registry/-/coins-registry-2.1.19.tgz#b615c72ae9477a6559ddb41102d25b0943f9683e"
+ integrity sha512-OMQXIRvZaOzka4pg2afrNocP4xyFz3iXyL/tOpysBIGZeIF+GCR9lt+zcuXAFleNJWOToE9LLksFNVDQC6atGA==
"@pontem/liquidswap-sdk@0.6.1":
version "0.6.1"