Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use test dataset from cal instead of hardcoded ones #8196

Merged
merged 2 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions libs/ledger-live-common/src/cal/currencies.integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { findCurrencyData } from "./currencies";

describe("findCurrencyData", () => {
it("returns all data in expected format", async () => {
// Given
const currencyId = "arbitrum";

// When
const currencies = await findCurrencyData(currencyId);

// Then
expect(currencies).toEqual({
config: "0345544808457468657265756d0d0345544812000000000000a4b1",
id: currencyId,
signature:
"30450221008ca557e4acc2fa290a6a44c2b0eb5232712ba69b23df93645a320bcff9789fd9022017e6e05582806a9d4b7b2aaaedbcc3471bd26e10ad686e4f313fc0b1068b5d64",
});
});
});
46 changes: 46 additions & 0 deletions libs/ledger-live-common/src/cal/currencies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { getEnv } from "@ledgerhq/live-env";
import network from "@ledgerhq/live-network";

const CAL_BASE_URL = getEnv("CAL_SERVICE_URL");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using getEnv like that means that it won't update if changed in the settings dev tools, not a big deal but something to be aware of

Copy link
Contributor Author

@sprohaszka-ledger sprohaszka-ledger Oct 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can change this var via the dev tools?


type CurrencyDataResponse = {
id: string;
descriptor_exchange_app: {
data: string;
signatures: {
prod: string;
test: string;
};
};
};
export type CurrencyData = {
id: string;
config: string;
signature: string;
};

export async function findCurrencyData(
id: string,
env: "prod" | "test" = "prod",
): Promise<CurrencyData> {
const { data: currencyData } = await network<CurrencyDataResponse[]>({
Copy link
Contributor

@Justkant Justkant Oct 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be interesting to look at integrating typia to validate and type guard the api calls later on
We could just use zod but you still have to declare a schema while with typia you can just use the type as is and get an optimised validator for it at build time

method: "GET",
url: `${CAL_BASE_URL}/v1/currencies`,
params: {
output: "id,descriptor_exchange_app",
id,
},
});
if (!currencyData.length) {
throw new Error(`CAL currencies, missing configuration for ${id}`);
}
if (currencyData.length !== 1) {
throw new Error(`CAL currencies, multiple configurations found for ${id}`);
}

return {
id: currencyData[0].id,
config: currencyData[0].descriptor_exchange_app.data,
signature: currencyData[0].descriptor_exchange_app.signatures[env],
};
}
13 changes: 13 additions & 0 deletions libs/ledger-live-common/src/cal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Crypto Asset List Service
*
* Use only exposed methods below outside of this module.
*/

export { findCurrencyData, type CurrencyData } from "./currencies";
export {
getProvidersCDNData,
getProvidersData,
type PartnerType,
type ExchangeProvider,
} from "./partners";
65 changes: 65 additions & 0 deletions libs/ledger-live-common/src/cal/partners.integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { getProvidersCDNData, getProvidersData } from "./partners";

describe("getProvidersCDNData", () => {
it("returns CEX data in expected format", async () => {
// Given

// When
const partners = await getProvidersCDNData();

// Then
expect(partners["changelly"]).toEqual({
continuesInProviderLiveApp: false,
displayName: "Changelly",
mainUrl: "https://changelly.com/",
needsKYC: false,
supportUrl: "https://support.changelly.com/en/support/home",
termsOfUseUrl: "https://changelly.com/terms-of-use",
type: "CEX",
});
});

it("returns DEX data in expected format", async () => {
// Given

// When
const partners = await getProvidersCDNData();

// Then
expect(partners["paraswap"]).toEqual({
continuesInProviderLiveApp: true,
displayName: "Paraswap",
mainUrl: "https://www.paraswap.io/",
needsKYC: false,
supportUrl: "https://help.paraswap.io/en/",
termsOfUseUrl: "https://files.paraswap.io/tos_v4.pdf",
type: "DEX",
});
});
});

describe("getProvidersData", () => {
it("returns data in expected format", async () => {
// Given

// When
const partners = await getProvidersData("swap");

// Then
expect(partners["changelly"]).toEqual({
name: "Changelly",
publicKey: {
curve: "secp256k1",
data: Buffer.from(
"0480d7c0d3a9183597395f58dda05999328da6f18fabd5cda0aff8e8e3fc633436a2dbf48ecb23d40df7c3c7d3e774b77b4b5df0e9f7e08cf1cdf2dba788eb085b",
"hex",
),
},
signature: Buffer.from(
"3045022100e73339e5071b5d232e8cacecbd7c118c919122a43f8abb8b2062d4bfcd58274e022050b11605d8b7e199f791266146227c43fd11d7645b1d881f705a2f8841d21de5",
"hex",
),
version: 1,
});
});
});
177 changes: 177 additions & 0 deletions libs/ledger-live-common/src/cal/partners.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import {
transformData,
getProvidersData,
type ProvidersDataResponse,
type ExchangeProvider,
} from "./partners";
import network from "@ledgerhq/live-network";

jest.mock("@ledgerhq/live-network");

describe("transformData", () => {
it.each([
[
"prod",
{
providera: {
name: "ProviderA",
publicKey: {
curve: "secp256k1",
data: Buffer.from("1234567890abcdef", "hex"),
},
signature: Buffer.from("a1b2c3", "hex"),
version: 2,
} satisfies ExchangeProvider,
providerb: {
name: "ProviderB",
publicKey: {
curve: "secp256r1",
data: Buffer.from("abcdef1234567890", "hex"),
},
signature: Buffer.from("d4e5f6", "hex"),
version: 2,
} satisfies ExchangeProvider,
},
],
[
"test",
{
providera: {
name: "ProviderA",
publicKey: {
curve: "secp256k1",
data: Buffer.from("1234567890abcdef", "hex"),
},
signature: Buffer.from("d1e2f3", "hex"),
version: 2,
} satisfies ExchangeProvider,
providerb: {
name: "ProviderB",
publicKey: {
curve: "secp256r1",
data: Buffer.from("abcdef1234567890", "hex"),
},
signature: Buffer.from("a9b8c7", "hex"),
version: 2,
} satisfies ExchangeProvider,
},
],
])(
"should transform providers data correctly with %p env",
(env: string, expected: Record<string, ExchangeProvider>) => {
const providersData = [
{
name: "ProviderA",
public_key: "1234567890abcdef",
public_key_curve: "secp256k1",
service_app_version: 2,
descriptor: {
data: "09abcd",
signatures: {
prod: "a1b2c3",
test: "d1e2f3",
},
},
},
{
name: "ProviderB",
public_key: "abcdef1234567890",
public_key_curve: "secp256r1",
service_app_version: 2,
descriptor: {
data: "ef0123",
signatures: {
prod: "d4e5f6",
test: "a9b8c7",
},
},
},
];

const result = transformData(providersData, env as "prod" | "test");
expect(result).toEqual(expected);
},
);

it("should handle empty providers data", () => {
const providersData: ProvidersDataResponse = [];

const expected: Record<string, ExchangeProvider> = {};

const result = transformData(providersData, "prod");
expect(result).toEqual(expected);
});
});

describe("getProvidersData", () => {
it.each([
[
"prod",
{
providera: {
name: "ProviderA",
publicKey: {
curve: "secp256k1",
data: Buffer.from("1234567890abcdef", "hex"),
},
signature: Buffer.from("a1b2c3", "hex"),
version: 2,
} satisfies ExchangeProvider,
},
],
[
"test",
{
providera: {
name: "ProviderA",
publicKey: {
curve: "secp256k1",
data: Buffer.from("1234567890abcdef", "hex"),
},
signature: Buffer.from("d1e2f3", "hex"),
version: 2,
} satisfies ExchangeProvider,
},
],
])(
"should fetch and transform providers data with %p signature",
async (env: string, expected: Record<string, ExchangeProvider>) => {
const mockProvidersData: ProvidersDataResponse = [
{
name: "ProviderA",
public_key: "1234567890abcdef",
public_key_curve: "secp256k1",
service_app_version: 2,
descriptor: {
data: "09abcd",
signatures: {
prod: "a1b2c3",
test: "d1e2f3",
},
},
},
];

(network as jest.Mock).mockResolvedValue({ data: mockProvidersData });

const result = await getProvidersData("swap", env as "prod" | "test");

expect(network).toHaveBeenCalledWith({
method: "GET",
url: "https://crypto-assets-service.api.ledger.com/v1/partners",
params: {
output: "name,public_key,public_key_curve,service_app_version,descriptor",
service_name: "swap",
},
});

expect(result).toEqual(expected);
},
);

it("should handle errors when fetching data", async () => {
(network as jest.Mock).mockRejectedValue(new Error("Network error"));

await expect(getProvidersData("swap")).rejects.toThrow("Network error");
});
});
Loading
Loading