@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
235 lines (221 loc) • 6.66 kB
text/typescript
import { BigNumber } from "bignumber.js";
import { Observable, of } from "rxjs";
import { getAccountCurrency } from "../../account";
import { formatCurrencyUnit } from "../../currencies";
import { SwapExchangeRateAmountTooHigh, SwapExchangeRateAmountTooLow } from "../../errors";
import type {
ExchangeSwap,
ExchangeRate,
GetMultipleStatus,
GetProviders,
PostSwapAccepted,
PostSwapCancelled,
SwapRequestEvent,
} from "./types";
import type { Transaction } from "../../generated/types";
import type { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
export const mockGetExchangeRates = async (
exchange: ExchangeSwap,
transaction: Transaction,
currencyTo?: TokenCurrency | CryptoCurrency | undefined | null,
): Promise<(ExchangeRate & { expirationDate?: Date })[]> => {
const { fromAccount, toAccount } = exchange;
const amount = transaction.amount;
const unitFrom = getAccountCurrency(fromAccount).units[0];
const unitTo = (currencyTo && currencyTo.units[0]) ?? getAccountCurrency(toAccount).units[0];
const tenPowMagnitude = new BigNumber(10).pow(unitFrom.magnitude);
const amountFrom = amount.div(tenPowMagnitude);
const minAmountFrom = new BigNumber(0.0001);
const maxAmountFrom = new BigNumber(1000);
if (amountFrom.lte(minAmountFrom)) {
throw new SwapExchangeRateAmountTooLow(undefined, {
minAmountFromFormatted: formatCurrencyUnit(
unitFrom,
new BigNumber(minAmountFrom).times(tenPowMagnitude),
{
alwaysShowSign: false,
disableRounding: true,
showCode: true,
},
),
});
}
if (amountFrom.gte(maxAmountFrom)) {
throw new SwapExchangeRateAmountTooHigh(undefined, {
maxAmountFromFormatted: formatCurrencyUnit(
unitFrom,
new BigNumber(maxAmountFrom).times(tenPowMagnitude),
{
alwaysShowSign: false,
disableRounding: true,
showCode: true,
},
),
});
}
//Fake delay to show loading UI
await new Promise(r => setTimeout(r, 800));
const magnitudeAwareRate = new BigNumber(1)
.div(new BigNumber(10).pow(unitFrom.magnitude))
.times(new BigNumber(10).pow(unitTo.magnitude));
//Mock OK, not really magnitude aware
return [
{
rate: new BigNumber("1"),
toAmount: amount.times(magnitudeAwareRate),
magnitudeAwareRate,
rateId: "changellyRateId1",
provider: "changelly",
providerType: "CEX",
expirationDate: new Date(),
tradeMethod: "fixed",
},
{
rate: new BigNumber("1.1"),
toAmount: amount.times(magnitudeAwareRate),
magnitudeAwareRate,
rateId: "changellyRateId2",
provider: "changelly",
providerType: "CEX",
expirationDate: new Date(),
tradeMethod: "float",
},
{
rate: new BigNumber("0.9"),
toAmount: amount.times(magnitudeAwareRate),
magnitudeAwareRate,
rateId: "cicRateId1",
provider: "cic",
providerType: "CEX",
expirationDate: new Date(),
tradeMethod: "float",
},
{
rate: new BigNumber("0.95"),
toAmount: amount.times(magnitudeAwareRate),
magnitudeAwareRate,
rateId: "1inchRateId1",
provider: "oneinch",
providerType: "DEX",
expirationDate: new Date(),
tradeMethod: "float",
providerURL: `https://1inch.com/swap/#/1/unified/swap/eth/usdt&sourceTokenAmount=${transaction.amount}`,
},
];
};
export const mockInitSwap = (
exchange: ExchangeSwap,
exchangeRate: ExchangeRate,
transaction: Transaction,
): Observable<SwapRequestEvent> => {
return of({
type: "init-swap-result",
initSwapResult: {
transaction,
swapId: "mockedSwapId",
magnitudeAwareRate: new BigNumber(50000),
},
});
};
// Need to understand how and why this gets used
export const mockGetProviders: GetProviders = async () => {
//Fake delay to show loading UI
await new Promise(r => setTimeout(r, 800));
return [
{
provider: "changelly",
pairs: [
{ from: "bitcoin", to: "ethereum", tradeMethod: "float" },
{ from: "bitcoin", to: "ethereum", tradeMethod: "fixed" },
{ from: "bitcoin", to: "dogecoin", tradeMethod: "float" },
{ from: "bitcoin", to: "dogecoin", tradeMethod: "fixed" },
{ from: "ethereum", to: "bitcoin", tradeMethod: "float" },
{ from: "ethereum", to: "bitcoin", tradeMethod: "fixed" },
{ from: "ethereum", to: "ethereum/erc20/usd_tether__erc20_", tradeMethod: "float" },
],
},
{
provider: "cic",
pairs: [
{ from: "bitcoin", to: "ethereum", tradeMethod: "float" },
{ from: "bitcoin", to: "ethereum", tradeMethod: "fixed" },
{ from: "ethereum", to: "bitcoin", tradeMethod: "float" },
{ from: "ethereum", to: "bitcoin", tradeMethod: "fixed" },
],
},
];
};
// Providers using V5 schema. For some reason it doesn't work though (still requires V4)
// return {
// currencies: {
// 7: "ethereum/erc20/usd_tether__erc20_",
// 8: "bitcoin",
// 149: "ethereum",
// },
// providers: {
// changelly: [
// {
// methods: ["fixed", "float"],
// pairs: {
// 7: [8, 149],
// 8: [7, 149],
// 149: [7, 8],
// },
// },
// ],
// cic: [
// {
// methods: ["fixed", "float"],
// pairs: {
// 7: [8, 149],
// 8: [7, 149],
// 149: [7, 8],
// },
// },
// ],
// oneinch: [
// {
// methods: ["float"],
// pairs: {
// 7: [149],
// 149: [7],
// },
// },
// ],
// paraswap: [
// {
// methods: ["float"],
// pairs: {
// 7: [149],
// 149: [7],
// },
// },
// ],
// },
// };
export const mockGetStatus: GetMultipleStatus = async statusList => {
//Fake delay to show loading UI
await new Promise(r => setTimeout(r, 800));
return statusList.map(s => ({ ...s, status: "finished" }));
};
export const mockPostSwapAccepted: PostSwapAccepted = async ({
/* eslint-disable @typescript-eslint/no-unused-vars */
provider,
swapId,
transactionId,
/* eslint-enable */
}) => {
//Fake delay to simulate network
await new Promise(r => setTimeout(r, 800));
return null;
};
export const mockPostSwapCancelled: PostSwapCancelled = async ({
/* eslint-disable @typescript-eslint/no-unused-vars */
provider,
swapId,
/* eslint-enable */
}) => {
//Fake delay to simulate network
await new Promise(r => setTimeout(r, 800));
return null;
};