@ledgerhq/live-common 34.46.0-nightly.4 → 34.46.0-nightly.5
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.
- package/lib/bridge/generic-alpaca/estimateMaxSpendable.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/estimateMaxSpendable.js +6 -4
- package/lib/bridge/generic-alpaca/estimateMaxSpendable.js.map +1 -1
- package/lib/bridge/generic-alpaca/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/getTransactionStatus.js +2 -2
- package/lib/bridge/generic-alpaca/getTransactionStatus.js.map +1 -1
- package/lib/bridge/generic-alpaca/prepareTransaction.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/prepareTransaction.js +12 -12
- package/lib/bridge/generic-alpaca/prepareTransaction.js.map +1 -1
- package/lib/bridge/generic-alpaca/signOperation.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/signOperation.js +3 -4
- package/lib/bridge/generic-alpaca/signOperation.js.map +1 -1
- package/lib/bridge/generic-alpaca/tests/prepareTransaction.test.js +1 -1
- package/lib/bridge/generic-alpaca/tests/prepareTransaction.test.js.map +1 -1
- package/lib/bridge/generic-alpaca/utils.d.ts +0 -1
- package/lib/bridge/generic-alpaca/utils.d.ts.map +1 -1
- package/lib/bridge/generic-alpaca/utils.js +0 -1
- package/lib/bridge/generic-alpaca/utils.js.map +1 -1
- package/lib/currencies/index.d.ts +1 -1
- package/lib/currencies/index.d.ts.map +1 -1
- package/lib/currencies/index.js +1 -2
- package/lib/currencies/index.js.map +1 -1
- package/lib/currencies/sortByMarketcap.test.js +2 -1
- package/lib/currencies/sortByMarketcap.test.js.map +1 -1
- package/lib/e2e/enum/AppInfos.d.ts +1 -1
- package/lib/e2e/enum/AppInfos.d.ts.map +1 -1
- package/lib/e2e/enum/Provider.d.ts.map +1 -1
- package/lib/e2e/enum/Provider.js +2 -2
- package/lib/e2e/enum/Provider.js.map +1 -1
- package/lib/e2e/index.d.ts +2 -0
- package/lib/e2e/index.d.ts.map +1 -1
- package/lib/e2e/speculos.d.ts.map +1 -1
- package/lib/e2e/speculos.js +3 -4
- package/lib/e2e/speculos.js.map +1 -1
- package/lib/e2e/speculosCI.d.ts +4 -0
- package/lib/e2e/speculosCI.d.ts.map +1 -1
- package/lib/e2e/speculosCI.js +16 -6
- package/lib/e2e/speculosCI.js.map +1 -1
- package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
- package/lib/featureFlags/defaultFeatures.js +1 -0
- package/lib/featureFlags/defaultFeatures.js.map +1 -1
- package/lib/featureFlags/useFeature.d.ts +1 -1
- package/lib/featureFlags/useFeature.d.ts.map +1 -1
- package/lib/modularDrawer/data/entities/index.d.ts +68 -0
- package/lib/modularDrawer/data/entities/index.d.ts.map +1 -0
- package/lib/modularDrawer/data/entities/index.js +3 -0
- package/lib/modularDrawer/data/entities/index.js.map +1 -0
- package/lib/modularDrawer/data/state-manager/api.d.ts +152 -0
- package/lib/modularDrawer/data/state-manager/api.d.ts.map +1 -0
- package/lib/modularDrawer/data/state-manager/api.js +45 -0
- package/lib/modularDrawer/data/state-manager/api.js.map +1 -0
- package/lib/modularDrawer/hooks/__test__/useAssetsData.test.d.ts +5 -0
- package/lib/modularDrawer/hooks/__test__/useAssetsData.test.d.ts.map +1 -0
- package/lib/modularDrawer/hooks/__test__/useAssetsData.test.js +120 -0
- package/lib/modularDrawer/hooks/__test__/useAssetsData.test.js.map +1 -0
- package/lib/modularDrawer/hooks/useAssetsData.d.ts +13 -0
- package/lib/modularDrawer/hooks/useAssetsData.d.ts.map +1 -0
- package/lib/modularDrawer/hooks/useAssetsData.js +31 -0
- package/lib/modularDrawer/hooks/useAssetsData.js.map +1 -0
- package/lib-es/bridge/generic-alpaca/estimateMaxSpendable.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/estimateMaxSpendable.js +6 -4
- package/lib-es/bridge/generic-alpaca/estimateMaxSpendable.js.map +1 -1
- package/lib-es/bridge/generic-alpaca/getTransactionStatus.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/getTransactionStatus.js +2 -2
- package/lib-es/bridge/generic-alpaca/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/generic-alpaca/prepareTransaction.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/prepareTransaction.js +12 -12
- package/lib-es/bridge/generic-alpaca/prepareTransaction.js.map +1 -1
- package/lib-es/bridge/generic-alpaca/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/signOperation.js +3 -4
- package/lib-es/bridge/generic-alpaca/signOperation.js.map +1 -1
- package/lib-es/bridge/generic-alpaca/tests/prepareTransaction.test.js +1 -1
- package/lib-es/bridge/generic-alpaca/tests/prepareTransaction.test.js.map +1 -1
- package/lib-es/bridge/generic-alpaca/utils.d.ts +0 -1
- package/lib-es/bridge/generic-alpaca/utils.d.ts.map +1 -1
- package/lib-es/bridge/generic-alpaca/utils.js +0 -1
- package/lib-es/bridge/generic-alpaca/utils.js.map +1 -1
- package/lib-es/currencies/index.d.ts +1 -1
- package/lib-es/currencies/index.d.ts.map +1 -1
- package/lib-es/currencies/index.js +1 -1
- package/lib-es/currencies/index.js.map +1 -1
- package/lib-es/currencies/sortByMarketcap.test.js +2 -1
- package/lib-es/currencies/sortByMarketcap.test.js.map +1 -1
- package/lib-es/e2e/enum/AppInfos.d.ts +1 -1
- package/lib-es/e2e/enum/AppInfos.d.ts.map +1 -1
- package/lib-es/e2e/enum/Provider.d.ts.map +1 -1
- package/lib-es/e2e/enum/Provider.js +2 -2
- package/lib-es/e2e/enum/Provider.js.map +1 -1
- package/lib-es/e2e/index.d.ts +2 -0
- package/lib-es/e2e/index.d.ts.map +1 -1
- package/lib-es/e2e/speculos.d.ts.map +1 -1
- package/lib-es/e2e/speculos.js +3 -4
- package/lib-es/e2e/speculos.js.map +1 -1
- package/lib-es/e2e/speculosCI.d.ts +4 -0
- package/lib-es/e2e/speculosCI.d.ts.map +1 -1
- package/lib-es/e2e/speculosCI.js +14 -5
- package/lib-es/e2e/speculosCI.js.map +1 -1
- package/lib-es/featureFlags/defaultFeatures.d.ts.map +1 -1
- package/lib-es/featureFlags/defaultFeatures.js +1 -0
- package/lib-es/featureFlags/defaultFeatures.js.map +1 -1
- package/lib-es/featureFlags/useFeature.d.ts +1 -1
- package/lib-es/featureFlags/useFeature.d.ts.map +1 -1
- package/lib-es/modularDrawer/data/entities/index.d.ts +68 -0
- package/lib-es/modularDrawer/data/entities/index.d.ts.map +1 -0
- package/lib-es/modularDrawer/data/entities/index.js +2 -0
- package/lib-es/modularDrawer/data/entities/index.js.map +1 -0
- package/lib-es/modularDrawer/data/state-manager/api.d.ts +152 -0
- package/lib-es/modularDrawer/data/state-manager/api.d.ts.map +1 -0
- package/lib-es/modularDrawer/data/state-manager/api.js +42 -0
- package/lib-es/modularDrawer/data/state-manager/api.js.map +1 -0
- package/lib-es/modularDrawer/hooks/__test__/useAssetsData.test.d.ts +5 -0
- package/lib-es/modularDrawer/hooks/__test__/useAssetsData.test.d.ts.map +1 -0
- package/lib-es/modularDrawer/hooks/__test__/useAssetsData.test.js +118 -0
- package/lib-es/modularDrawer/hooks/__test__/useAssetsData.test.js.map +1 -0
- package/lib-es/modularDrawer/hooks/useAssetsData.d.ts +13 -0
- package/lib-es/modularDrawer/hooks/useAssetsData.d.ts.map +1 -0
- package/lib-es/modularDrawer/hooks/useAssetsData.js +27 -0
- package/lib-es/modularDrawer/hooks/useAssetsData.js.map +1 -0
- package/package.json +46 -45
- package/src/bridge/generic-alpaca/estimateMaxSpendable.ts +11 -5
- package/src/bridge/generic-alpaca/getTransactionStatus.ts +2 -1
- package/src/bridge/generic-alpaca/prepareTransaction.ts +20 -16
- package/src/bridge/generic-alpaca/signOperation.ts +3 -2
- package/src/bridge/generic-alpaca/tests/prepareTransaction.test.ts +1 -1
- package/src/bridge/generic-alpaca/utils.ts +0 -2
- package/src/currencies/index.ts +0 -1
- package/src/currencies/sortByMarketcap.test.ts +2 -1
- package/src/e2e/enum/AppInfos.ts +1 -1
- package/src/e2e/enum/Provider.ts +2 -2
- package/src/e2e/speculos.ts +3 -4
- package/src/e2e/speculosCI.ts +18 -6
- package/src/featureFlags/defaultFeatures.ts +1 -0
- package/src/modularDrawer/data/entities/index.ts +79 -0
- package/src/modularDrawer/data/state-manager/api.ts +62 -0
- package/src/modularDrawer/hooks/__test__/useAssetsData.test.ts +139 -0
- package/src/modularDrawer/hooks/useAssetsData.ts +36 -0
package/src/e2e/speculosCI.ts
CHANGED
@@ -21,6 +21,14 @@ function uniqueId(): string {
|
|
21
21
|
return timestamp + randomString;
|
22
22
|
}
|
23
23
|
|
24
|
+
function slugify(name: string): string {
|
25
|
+
return name
|
26
|
+
.toLowerCase()
|
27
|
+
.trim()
|
28
|
+
.replace(/[^a-z0-9]+/g, "-")
|
29
|
+
.replace(/^-+|-+$/g, "");
|
30
|
+
}
|
31
|
+
|
24
32
|
/**
|
25
33
|
* Helper function to make API requests with error handling
|
26
34
|
*/
|
@@ -58,10 +66,14 @@ async function githubApiRequest<T = unknown>({
|
|
58
66
|
}
|
59
67
|
}
|
60
68
|
|
61
|
-
function waitForSpeculosReady(
|
69
|
+
export function waitForSpeculosReady(
|
70
|
+
deviceId: string,
|
71
|
+
{ interval = 2_000, timeout = 150_000 } = {},
|
72
|
+
) {
|
62
73
|
return new Promise((resolve, reject) => {
|
63
74
|
const startTime = Date.now();
|
64
75
|
let currentRequest: ReturnType<typeof https.get> | null = null;
|
76
|
+
const url = getSpeculosAddress(deviceId);
|
65
77
|
|
66
78
|
function cleanup() {
|
67
79
|
if (currentRequest) {
|
@@ -151,22 +163,22 @@ function createStartPayload(deviceParams: DeviceParams, runId: string) {
|
|
151
163
|
export async function createSpeculosDeviceCI(
|
152
164
|
deviceParams: DeviceParams,
|
153
165
|
): Promise<SpeculosDevice | undefined> {
|
166
|
+
const runId = `${slugify(deviceParams.appName)}-${uniqueId()}`;
|
154
167
|
try {
|
155
|
-
const runId = uniqueId();
|
156
|
-
console.warn("Creating remote speculos:", runId);
|
157
168
|
const data = createStartPayload(deviceParams, runId);
|
158
169
|
await githubApiRequest({ urlSuffix: START_WORKFLOW_ID, data });
|
159
|
-
await waitForSpeculosReady(getSpeculosAddress(runId));
|
160
|
-
|
161
170
|
return {
|
162
171
|
id: runId,
|
163
172
|
port: speculosPort,
|
164
173
|
};
|
165
174
|
} catch (e: unknown) {
|
166
|
-
console.error(e);
|
167
175
|
console.warn(
|
168
176
|
`Creating remote speculos ${deviceParams.appName}:${deviceParams.appVersion} failed with ${String(e)}`,
|
169
177
|
);
|
178
|
+
return {
|
179
|
+
id: runId,
|
180
|
+
port: 0,
|
181
|
+
};
|
170
182
|
}
|
171
183
|
}
|
172
184
|
|
@@ -0,0 +1,79 @@
|
|
1
|
+
import type { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
|
2
|
+
import type { ApiAsset } from "@ledgerhq/cryptoassets";
|
3
|
+
import { PartialMarketItemResponse } from "@ledgerhq/live-common/market/utils/types";
|
4
|
+
|
5
|
+
// Types for crypto asset metadata
|
6
|
+
export interface CryptoAssetMeta {
|
7
|
+
/** Asset identifier */
|
8
|
+
id: string;
|
9
|
+
/** Asset ticker symbol */
|
10
|
+
ticker: string;
|
11
|
+
/** Asset display name */
|
12
|
+
name: string;
|
13
|
+
/** Map of network IDs to their corresponding asset IDs */
|
14
|
+
assetsIds: Record<string, string>;
|
15
|
+
}
|
16
|
+
|
17
|
+
// Types for network information
|
18
|
+
export interface NetworkInfo {
|
19
|
+
/** Network identifier */
|
20
|
+
id: string;
|
21
|
+
/** Network display name */
|
22
|
+
name: string;
|
23
|
+
}
|
24
|
+
|
25
|
+
// Types for interest rate data
|
26
|
+
export interface InterestRate {
|
27
|
+
/** Currency identifier */
|
28
|
+
currencyId: string;
|
29
|
+
/** Interest rate value */
|
30
|
+
rate: number;
|
31
|
+
/** Type of rate (NRR, APR, APY, etc.) */
|
32
|
+
type: string;
|
33
|
+
/** Timestamp when the rate was fetched */
|
34
|
+
fetchAt: string;
|
35
|
+
}
|
36
|
+
|
37
|
+
// Types for currency ordering
|
38
|
+
export interface CurrenciesOrder {
|
39
|
+
/** Sorting key (e.g., "marketCap") */
|
40
|
+
key: string;
|
41
|
+
/** Sort order (e.g., "desc") */
|
42
|
+
order: string;
|
43
|
+
/** Ordered list of currency IDs */
|
44
|
+
currenciesIds: string[];
|
45
|
+
/** Ordered list of meta-currency IDs */
|
46
|
+
metaCurrencyIds: string[];
|
47
|
+
}
|
48
|
+
|
49
|
+
// Types for raw API response (before transformation)
|
50
|
+
export interface RawApiResponse {
|
51
|
+
/** Grouped crypto assets by meta-currency */
|
52
|
+
cryptoAssets: Record<string, CryptoAssetMeta>;
|
53
|
+
/** Network information */
|
54
|
+
networks: Record<string, NetworkInfo>;
|
55
|
+
/** Raw crypto currencies and token currencies from API */
|
56
|
+
cryptoOrTokenCurrencies: Record<string, ApiAsset>;
|
57
|
+
/** Interest rates for various currencies */
|
58
|
+
interestRates: Record<string, InterestRate>;
|
59
|
+
/** Market data for currencies */
|
60
|
+
markets: Record<string, PartialMarketItemResponse>;
|
61
|
+
/** Currency ordering information */
|
62
|
+
currenciesOrder: CurrenciesOrder;
|
63
|
+
}
|
64
|
+
|
65
|
+
// Types for transformed API response (after transformation)
|
66
|
+
export interface AssetsData {
|
67
|
+
/** Grouped crypto assets by meta-currency */
|
68
|
+
cryptoAssets: Record<string, CryptoAssetMeta>;
|
69
|
+
/** Network information */
|
70
|
+
networks: Record<string, NetworkInfo>;
|
71
|
+
/** Transformed crypto currencies and token currencies compatible with Ledger Live */
|
72
|
+
cryptoOrTokenCurrencies: Record<string, CryptoOrTokenCurrency>;
|
73
|
+
/** Interest rates for various currencies */
|
74
|
+
interestRates: Record<string, InterestRate>;
|
75
|
+
/** Market data for currencies */
|
76
|
+
markets: Record<string, PartialMarketItemResponse>;
|
77
|
+
/** Currency ordering information */
|
78
|
+
currenciesOrder: CurrenciesOrder;
|
79
|
+
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { createApi, fetchBaseQuery, FetchBaseQueryMeta } from "@reduxjs/toolkit/query/react";
|
2
|
+
import { convertApiAssets } from "@ledgerhq/cryptoassets";
|
3
|
+
import { AssetsData, RawApiResponse } from "../entities";
|
4
|
+
import { getEnv } from "@ledgerhq/live-env";
|
5
|
+
|
6
|
+
export enum AssetsDataTags {
|
7
|
+
Assets = "Assets",
|
8
|
+
}
|
9
|
+
|
10
|
+
export interface GetAssetsDataParams {
|
11
|
+
cursor?: string;
|
12
|
+
search?: string;
|
13
|
+
currencyIds?: string[];
|
14
|
+
}
|
15
|
+
|
16
|
+
export interface AssetsDataWithPagination extends AssetsData {
|
17
|
+
pagination: {
|
18
|
+
nextCursor?: string;
|
19
|
+
};
|
20
|
+
}
|
21
|
+
|
22
|
+
function transformAssetsResponse(
|
23
|
+
response: RawApiResponse,
|
24
|
+
meta?: FetchBaseQueryMeta,
|
25
|
+
): AssetsDataWithPagination {
|
26
|
+
const enrichedCryptoOrTokenCurrencies = convertApiAssets(response.cryptoOrTokenCurrencies);
|
27
|
+
|
28
|
+
const nextCursor = meta?.response?.headers.get("x-ledger-next") || undefined;
|
29
|
+
|
30
|
+
return {
|
31
|
+
...response,
|
32
|
+
cryptoOrTokenCurrencies: enrichedCryptoOrTokenCurrencies,
|
33
|
+
pagination: {
|
34
|
+
nextCursor,
|
35
|
+
},
|
36
|
+
};
|
37
|
+
}
|
38
|
+
|
39
|
+
export const assetsDataApi = createApi({
|
40
|
+
reducerPath: "assetsDataApi",
|
41
|
+
baseQuery: fetchBaseQuery({
|
42
|
+
baseUrl: __DEV__ ? getEnv("DADA_API_STAGING") : getEnv("DADA_API_PROD"),
|
43
|
+
}),
|
44
|
+
tagTypes: [AssetsDataTags.Assets],
|
45
|
+
endpoints: build => ({
|
46
|
+
getAssetsData: build.query<AssetsDataWithPagination, GetAssetsDataParams>({
|
47
|
+
query: ({ cursor, search, currencyIds: _currencyIds }) => ({
|
48
|
+
url: "assets",
|
49
|
+
params: {
|
50
|
+
...(cursor && { cursor }),
|
51
|
+
...(search && { search }),
|
52
|
+
// ...(currencyIds && currencyIds.length > 0 && { currencyIds }),
|
53
|
+
pageSize: 100,
|
54
|
+
},
|
55
|
+
}),
|
56
|
+
providesTags: [AssetsDataTags.Assets],
|
57
|
+
transformResponse: transformAssetsResponse,
|
58
|
+
}),
|
59
|
+
}),
|
60
|
+
});
|
61
|
+
|
62
|
+
export const { useGetAssetsDataQuery } = assetsDataApi;
|
@@ -0,0 +1,139 @@
|
|
1
|
+
/**
|
2
|
+
* @jest-environment jsdom
|
3
|
+
*/
|
4
|
+
|
5
|
+
import { renderHook } from "@testing-library/react";
|
6
|
+
import { useAssetsData } from "../useAssetsData";
|
7
|
+
import { useGetAssetsDataQuery } from "../../data/state-manager/api";
|
8
|
+
|
9
|
+
jest.mock("../../data/state-manager/api", () => ({
|
10
|
+
useGetAssetsDataQuery: jest.fn(),
|
11
|
+
}));
|
12
|
+
|
13
|
+
const mockSetCursor = jest.fn();
|
14
|
+
jest.mock("react", () => ({
|
15
|
+
...jest.requireActual("react"),
|
16
|
+
useState: jest.fn(() => [undefined, mockSetCursor]),
|
17
|
+
useCallback: jest.fn(fn => fn),
|
18
|
+
useMemo: jest.fn(fn => fn()),
|
19
|
+
}));
|
20
|
+
|
21
|
+
const mockUseGetAssetsDataQuery = jest.mocked(useGetAssetsDataQuery);
|
22
|
+
|
23
|
+
describe("useAssetsData", () => {
|
24
|
+
beforeEach(() => {
|
25
|
+
jest.clearAllMocks();
|
26
|
+
});
|
27
|
+
|
28
|
+
it("should return loading state when API is loading", () => {
|
29
|
+
mockUseGetAssetsDataQuery.mockReturnValue({
|
30
|
+
data: undefined,
|
31
|
+
isLoading: true,
|
32
|
+
error: undefined,
|
33
|
+
refetch: jest.fn(),
|
34
|
+
isFetching: false,
|
35
|
+
isSuccess: false,
|
36
|
+
isError: false,
|
37
|
+
currentData: undefined,
|
38
|
+
});
|
39
|
+
|
40
|
+
const { result } = renderHook(() => useAssetsData({}));
|
41
|
+
|
42
|
+
expect(result.current.isLoading).toBe(true);
|
43
|
+
expect(result.current.data).toBe(undefined);
|
44
|
+
expect(result.current.hasMore).toBe(false);
|
45
|
+
});
|
46
|
+
|
47
|
+
it("should return data and hasMore when API returns data", () => {
|
48
|
+
const mockData = {
|
49
|
+
assetsData: [],
|
50
|
+
pagination: { nextCursor: "test-cursor" },
|
51
|
+
};
|
52
|
+
mockUseGetAssetsDataQuery.mockReturnValue({
|
53
|
+
data: mockData,
|
54
|
+
isLoading: false,
|
55
|
+
error: undefined,
|
56
|
+
refetch: jest.fn(),
|
57
|
+
isFetching: false,
|
58
|
+
isSuccess: true,
|
59
|
+
isError: false,
|
60
|
+
currentData: mockData,
|
61
|
+
});
|
62
|
+
|
63
|
+
const { result } = renderHook(() => useAssetsData({}));
|
64
|
+
|
65
|
+
expect(result.current.data).toBe(mockData);
|
66
|
+
expect(result.current.isLoading).toBe(false);
|
67
|
+
expect(result.current.hasMore).toBe(true);
|
68
|
+
});
|
69
|
+
|
70
|
+
it("should return error when API has error", () => {
|
71
|
+
const mockError = new Error("API Error");
|
72
|
+
mockUseGetAssetsDataQuery.mockReturnValue({
|
73
|
+
data: undefined,
|
74
|
+
isLoading: false,
|
75
|
+
error: mockError,
|
76
|
+
refetch: jest.fn(),
|
77
|
+
isFetching: false,
|
78
|
+
isSuccess: false,
|
79
|
+
isError: true,
|
80
|
+
currentData: undefined,
|
81
|
+
});
|
82
|
+
|
83
|
+
const { result } = renderHook(() => useAssetsData({}));
|
84
|
+
|
85
|
+
expect(result.current.error).toBe(mockError);
|
86
|
+
expect(result.current.isLoading).toBe(false);
|
87
|
+
});
|
88
|
+
|
89
|
+
it("should call setCursor when loadNext is called and there's a nextCursor", () => {
|
90
|
+
const nextCursor = "next-cursor-456";
|
91
|
+
mockUseGetAssetsDataQuery.mockReturnValue({
|
92
|
+
data: {
|
93
|
+
assetsData: [],
|
94
|
+
pagination: { nextCursor },
|
95
|
+
},
|
96
|
+
isLoading: false,
|
97
|
+
error: undefined,
|
98
|
+
refetch: jest.fn(),
|
99
|
+
isFetching: false,
|
100
|
+
isSuccess: true,
|
101
|
+
isError: false,
|
102
|
+
currentData: {
|
103
|
+
assetsData: [],
|
104
|
+
pagination: { nextCursor },
|
105
|
+
},
|
106
|
+
});
|
107
|
+
|
108
|
+
const { result } = renderHook(() => useAssetsData({}));
|
109
|
+
|
110
|
+
result.current.loadNext();
|
111
|
+
|
112
|
+
expect(mockSetCursor).toHaveBeenCalledWith(nextCursor);
|
113
|
+
});
|
114
|
+
|
115
|
+
it("should not call setCursor when there's no nextCursor", () => {
|
116
|
+
mockUseGetAssetsDataQuery.mockReturnValue({
|
117
|
+
data: {
|
118
|
+
assetsData: [],
|
119
|
+
pagination: { nextCursor: undefined },
|
120
|
+
},
|
121
|
+
isLoading: false,
|
122
|
+
error: undefined,
|
123
|
+
refetch: jest.fn(),
|
124
|
+
isFetching: false,
|
125
|
+
isSuccess: true,
|
126
|
+
isError: false,
|
127
|
+
currentData: {
|
128
|
+
assetsData: [],
|
129
|
+
pagination: { nextCursor: undefined },
|
130
|
+
},
|
131
|
+
});
|
132
|
+
|
133
|
+
const { result } = renderHook(() => useAssetsData({}));
|
134
|
+
|
135
|
+
result.current.loadNext();
|
136
|
+
|
137
|
+
expect(mockSetCursor).not.toHaveBeenCalled();
|
138
|
+
});
|
139
|
+
});
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { useState, useCallback } from "react";
|
2
|
+
import { useGetAssetsDataQuery } from "../data/state-manager/api";
|
3
|
+
|
4
|
+
export function useAssetsData({
|
5
|
+
search,
|
6
|
+
currencyIds,
|
7
|
+
}: {
|
8
|
+
search?: string;
|
9
|
+
currencyIds?: string[];
|
10
|
+
}) {
|
11
|
+
const [cursor, setCursor] = useState<string | undefined>(undefined);
|
12
|
+
const { data, error, isLoading, isSuccess } = useGetAssetsDataQuery({
|
13
|
+
cursor,
|
14
|
+
search,
|
15
|
+
currencyIds,
|
16
|
+
});
|
17
|
+
|
18
|
+
const loadNext = useCallback(() => {
|
19
|
+
const nextCursor = data?.pagination?.nextCursor;
|
20
|
+
if (nextCursor) {
|
21
|
+
setCursor(nextCursor);
|
22
|
+
}
|
23
|
+
}, [data?.pagination?.nextCursor]);
|
24
|
+
|
25
|
+
const hasMore = Boolean(data?.pagination?.nextCursor);
|
26
|
+
|
27
|
+
return {
|
28
|
+
data,
|
29
|
+
error,
|
30
|
+
isLoading,
|
31
|
+
isSuccess,
|
32
|
+
hasMore,
|
33
|
+
cursor,
|
34
|
+
loadNext,
|
35
|
+
};
|
36
|
+
}
|