@ledgerhq/coin-hedera 1.15.0-nightly.20251126023856 → 1.15.0-nightly.20251126160702
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/CHANGELOG.md +10 -8
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.js +6 -2
- package/lib/api/index.js.map +1 -1
- package/lib/bridge/broadcast.js +1 -1
- package/lib/bridge/broadcast.js.map +1 -1
- package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib/bridge/buildOptimisticOperation.js +80 -15
- package/lib/bridge/buildOptimisticOperation.js.map +1 -1
- package/lib/bridge/estimateMaxSpendable.js +5 -2
- package/lib/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/getTransactionStatus.js +70 -13
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/index.js +1 -1
- package/lib/bridge/index.js.map +1 -1
- package/lib/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib/bridge/prepareTransaction.js +40 -7
- package/lib/bridge/prepareTransaction.js.map +1 -1
- package/lib/bridge/signOperation.d.ts.map +1 -1
- package/lib/bridge/signOperation.js +19 -2
- package/lib/bridge/signOperation.js.map +1 -1
- package/lib/bridge/synchronisation.d.ts +2 -0
- package/lib/bridge/synchronisation.d.ts.map +1 -1
- package/lib/bridge/synchronisation.js +101 -30
- package/lib/bridge/synchronisation.js.map +1 -1
- package/lib/bridge/utils.d.ts +35 -2
- package/lib/bridge/utils.d.ts.map +1 -1
- package/lib/bridge/utils.js +215 -16
- package/lib/bridge/utils.js.map +1 -1
- package/lib/constants.d.ts +22 -2
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +42 -2
- package/lib/constants.js.map +1 -1
- package/lib/deviceTransactionConfig.d.ts +1 -1
- package/lib/deviceTransactionConfig.d.ts.map +1 -1
- package/lib/deviceTransactionConfig.js +8 -0
- package/lib/deviceTransactionConfig.js.map +1 -1
- package/lib/errors.d.ts +3 -0
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +2 -1
- package/lib/errors.js.map +1 -1
- package/lib/logic/craftTransaction.d.ts +4 -4
- package/lib/logic/craftTransaction.d.ts.map +1 -1
- package/lib/logic/craftTransaction.js +46 -5
- package/lib/logic/craftTransaction.js.map +1 -1
- package/lib/logic/estimateFees.d.ts +2 -4
- package/lib/logic/estimateFees.d.ts.map +1 -1
- package/lib/logic/estimateFees.js +45 -5
- package/lib/logic/estimateFees.js.map +1 -1
- package/lib/logic/listOperations.d.ts.map +1 -1
- package/lib/logic/listOperations.js +7 -3
- package/lib/logic/listOperations.js.map +1 -1
- package/lib/logic/utils.d.ts +24 -2
- package/lib/logic/utils.d.ts.map +1 -1
- package/lib/logic/utils.js +66 -13
- package/lib/logic/utils.js.map +1 -1
- package/lib/network/api.d.ts +12 -1
- package/lib/network/api.d.ts.map +1 -1
- package/lib/network/api.js +91 -19
- package/lib/network/api.js.map +1 -1
- package/lib/network/rpc.d.ts.map +1 -1
- package/lib/network/rpc.js +1 -0
- package/lib/network/rpc.js.map +1 -1
- package/lib/network/thirdweb.d.ts +21 -0
- package/lib/network/thirdweb.d.ts.map +1 -0
- package/lib/network/thirdweb.js +72 -0
- package/lib/network/thirdweb.js.map +1 -0
- package/lib/network/utils.d.ts +4 -1
- package/lib/network/utils.d.ts.map +1 -1
- package/lib/network/utils.js +53 -1
- package/lib/network/utils.js.map +1 -1
- package/lib/test/bridgeDatasetTest.d.ts.map +1 -1
- package/lib/test/bridgeDatasetTest.js +4 -4
- package/lib/test/bridgeDatasetTest.js.map +1 -1
- package/lib/test/fixtures/account.fixture.js +1 -1
- package/lib/test/fixtures/account.fixture.js.map +1 -1
- package/lib/test/fixtures/common.fixture.d.ts +12 -0
- package/lib/test/fixtures/common.fixture.d.ts.map +1 -0
- package/lib/test/fixtures/common.fixture.js +66 -0
- package/lib/test/fixtures/common.fixture.js.map +1 -0
- package/lib/test/fixtures/currency.fixture.d.ts +3 -1
- package/lib/test/fixtures/currency.fixture.d.ts.map +1 -1
- package/lib/test/fixtures/currency.fixture.js +63 -16
- package/lib/test/fixtures/currency.fixture.js.map +1 -1
- package/lib/test/fixtures/mirror.fixture.d.ts +3 -1
- package/lib/test/fixtures/mirror.fixture.d.ts.map +1 -1
- package/lib/test/fixtures/mirror.fixture.js +12 -1
- package/lib/test/fixtures/mirror.fixture.js.map +1 -1
- package/lib/test/fixtures/thirdweb.fixture.d.ts +3 -0
- package/lib/test/fixtures/thirdweb.fixture.d.ts.map +1 -0
- package/lib/test/fixtures/thirdweb.fixture.js +34 -0
- package/lib/test/fixtures/thirdweb.fixture.js.map +1 -0
- package/lib/transaction.d.ts.map +1 -1
- package/lib/transaction.js +2 -0
- package/lib/transaction.js.map +1 -1
- package/lib/types/alpaca.d.ts +5 -1
- package/lib/types/alpaca.d.ts.map +1 -1
- package/lib/types/bridge.d.ts +6 -1
- package/lib/types/bridge.d.ts.map +1 -1
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +2 -0
- package/lib/types/index.js.map +1 -1
- package/lib/types/logic.d.ts +39 -0
- package/lib/types/logic.d.ts.map +1 -0
- package/lib/types/logic.js +3 -0
- package/lib/types/logic.js.map +1 -0
- package/lib/types/mirror.d.ts +29 -0
- package/lib/types/mirror.d.ts.map +1 -1
- package/lib/types/thirdweb.d.ts +34 -0
- package/lib/types/thirdweb.d.ts.map +1 -0
- package/lib/types/thirdweb.js +3 -0
- package/lib/types/thirdweb.js.map +1 -0
- package/lib-es/api/index.d.ts.map +1 -1
- package/lib-es/api/index.js +7 -3
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/bridge/broadcast.js +2 -2
- package/lib-es/bridge/broadcast.js.map +1 -1
- package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib-es/bridge/buildOptimisticOperation.js +83 -18
- package/lib-es/bridge/buildOptimisticOperation.js.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.js +5 -2
- package/lib-es/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib-es/bridge/getTransactionStatus.js +73 -16
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/index.js +2 -2
- package/lib-es/bridge/index.js.map +1 -1
- package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib-es/bridge/prepareTransaction.js +42 -9
- package/lib-es/bridge/prepareTransaction.js.map +1 -1
- package/lib-es/bridge/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/signOperation.js +21 -4
- package/lib-es/bridge/signOperation.js.map +1 -1
- package/lib-es/bridge/synchronisation.d.ts +2 -0
- package/lib-es/bridge/synchronisation.d.ts.map +1 -1
- package/lib-es/bridge/synchronisation.js +97 -27
- package/lib-es/bridge/synchronisation.js.map +1 -1
- package/lib-es/bridge/utils.d.ts +35 -2
- package/lib-es/bridge/utils.d.ts.map +1 -1
- package/lib-es/bridge/utils.js +211 -16
- package/lib-es/bridge/utils.js.map +1 -1
- package/lib-es/constants.d.ts +22 -2
- package/lib-es/constants.d.ts.map +1 -1
- package/lib-es/constants.js +38 -1
- package/lib-es/constants.js.map +1 -1
- package/lib-es/deviceTransactionConfig.d.ts +1 -1
- package/lib-es/deviceTransactionConfig.d.ts.map +1 -1
- package/lib-es/deviceTransactionConfig.js +8 -0
- package/lib-es/deviceTransactionConfig.js.map +1 -1
- package/lib-es/errors.d.ts +3 -0
- package/lib-es/errors.d.ts.map +1 -1
- package/lib-es/errors.js +1 -0
- package/lib-es/errors.js.map +1 -1
- package/lib-es/logic/craftTransaction.d.ts +4 -4
- package/lib-es/logic/craftTransaction.d.ts.map +1 -1
- package/lib-es/logic/craftTransaction.js +48 -7
- package/lib-es/logic/craftTransaction.js.map +1 -1
- package/lib-es/logic/estimateFees.d.ts +2 -4
- package/lib-es/logic/estimateFees.d.ts.map +1 -1
- package/lib-es/logic/estimateFees.js +47 -7
- package/lib-es/logic/estimateFees.js.map +1 -1
- package/lib-es/logic/listOperations.d.ts.map +1 -1
- package/lib-es/logic/listOperations.js +7 -3
- package/lib-es/logic/listOperations.js.map +1 -1
- package/lib-es/logic/utils.d.ts +24 -2
- package/lib-es/logic/utils.d.ts.map +1 -1
- package/lib-es/logic/utils.js +63 -13
- package/lib-es/logic/utils.js.map +1 -1
- package/lib-es/network/api.d.ts +12 -1
- package/lib-es/network/api.d.ts.map +1 -1
- package/lib-es/network/api.js +91 -19
- package/lib-es/network/api.js.map +1 -1
- package/lib-es/network/rpc.d.ts.map +1 -1
- package/lib-es/network/rpc.js +1 -0
- package/lib-es/network/rpc.js.map +1 -1
- package/lib-es/network/thirdweb.d.ts +21 -0
- package/lib-es/network/thirdweb.d.ts.map +1 -0
- package/lib-es/network/thirdweb.js +66 -0
- package/lib-es/network/thirdweb.js.map +1 -0
- package/lib-es/network/utils.d.ts +4 -1
- package/lib-es/network/utils.d.ts.map +1 -1
- package/lib-es/network/utils.js +49 -0
- package/lib-es/network/utils.js.map +1 -1
- package/lib-es/test/bridgeDatasetTest.d.ts.map +1 -1
- package/lib-es/test/bridgeDatasetTest.js +4 -4
- package/lib-es/test/bridgeDatasetTest.js.map +1 -1
- package/lib-es/test/fixtures/account.fixture.js +2 -2
- package/lib-es/test/fixtures/account.fixture.js.map +1 -1
- package/lib-es/test/fixtures/common.fixture.d.ts +12 -0
- package/lib-es/test/fixtures/common.fixture.d.ts.map +1 -0
- package/lib-es/test/fixtures/common.fixture.js +57 -0
- package/lib-es/test/fixtures/common.fixture.js.map +1 -0
- package/lib-es/test/fixtures/currency.fixture.d.ts +3 -1
- package/lib-es/test/fixtures/currency.fixture.d.ts.map +1 -1
- package/lib-es/test/fixtures/currency.fixture.js +59 -14
- package/lib-es/test/fixtures/currency.fixture.js.map +1 -1
- package/lib-es/test/fixtures/mirror.fixture.d.ts +3 -1
- package/lib-es/test/fixtures/mirror.fixture.d.ts.map +1 -1
- package/lib-es/test/fixtures/mirror.fixture.js +9 -0
- package/lib-es/test/fixtures/mirror.fixture.js.map +1 -1
- package/lib-es/test/fixtures/thirdweb.fixture.d.ts +3 -0
- package/lib-es/test/fixtures/thirdweb.fixture.d.ts.map +1 -0
- package/lib-es/test/fixtures/thirdweb.fixture.js +30 -0
- package/lib-es/test/fixtures/thirdweb.fixture.js.map +1 -0
- package/lib-es/transaction.d.ts.map +1 -1
- package/lib-es/transaction.js +2 -0
- package/lib-es/transaction.js.map +1 -1
- package/lib-es/types/alpaca.d.ts +5 -1
- package/lib-es/types/alpaca.d.ts.map +1 -1
- package/lib-es/types/bridge.d.ts +6 -1
- package/lib-es/types/bridge.d.ts.map +1 -1
- package/lib-es/types/index.d.ts +2 -0
- package/lib-es/types/index.d.ts.map +1 -1
- package/lib-es/types/index.js +2 -0
- package/lib-es/types/index.js.map +1 -1
- package/lib-es/types/logic.d.ts +39 -0
- package/lib-es/types/logic.d.ts.map +1 -0
- package/lib-es/types/logic.js +2 -0
- package/lib-es/types/logic.js.map +1 -0
- package/lib-es/types/mirror.d.ts +29 -0
- package/lib-es/types/mirror.d.ts.map +1 -1
- package/lib-es/types/thirdweb.d.ts +34 -0
- package/lib-es/types/thirdweb.d.ts.map +1 -0
- package/lib-es/types/thirdweb.js +2 -0
- package/lib-es/types/thirdweb.js.map +1 -0
- package/package.json +9 -8
- package/src/api/index.integ.test.ts +11 -8
- package/src/api/index.ts +10 -3
- package/src/bridge/broadcast.ts +2 -2
- package/src/bridge/buildOptimisticOperation.integration.test.ts +70 -19
- package/src/bridge/buildOptimisticOperation.ts +98 -20
- package/src/bridge/estimateMaxSpendable.ts +5 -5
- package/src/bridge/getTransactionStatus.test.ts +57 -12
- package/src/bridge/getTransactionStatus.ts +88 -15
- package/src/bridge/index.ts +2 -2
- package/src/bridge/js-estimateMaxSpendable.integration.test.ts +12 -9
- package/src/bridge/prepareTransaction.test.ts +3 -1
- package/src/bridge/prepareTransaction.ts +45 -10
- package/src/bridge/signOperation.ts +23 -5
- package/src/bridge/synchronisation.test.ts +67 -0
- package/src/bridge/synchronisation.ts +114 -34
- package/src/bridge/utils.integration.test.ts +486 -180
- package/src/bridge/utils.test.ts +404 -0
- package/src/bridge/utils.ts +330 -27
- package/src/constants.ts +47 -2
- package/src/deviceTransactionConfig.ts +10 -1
- package/src/errors.ts +3 -0
- package/src/logic/craftTransaction.test.ts +49 -9
- package/src/logic/craftTransaction.ts +76 -11
- package/src/logic/estimateFees.test.ts +180 -31
- package/src/logic/estimateFees.ts +68 -7
- package/src/logic/getAssetFromToken.test.ts +2 -2
- package/src/logic/getBalance.test.ts +18 -57
- package/src/logic/getTokenFromAsset.test.ts +2 -2
- package/src/logic/listOperations.ts +9 -5
- package/src/logic/utils.test.ts +157 -69
- package/src/logic/utils.ts +75 -13
- package/src/network/api.test.ts +211 -3
- package/src/network/api.ts +118 -24
- package/src/network/rpc.test.ts +1 -0
- package/src/network/rpc.ts +1 -0
- package/src/network/thirdweb.test.ts +188 -0
- package/src/network/thirdweb.ts +101 -0
- package/src/network/utils.test.ts +364 -164
- package/src/network/utils.ts +83 -1
- package/src/test/bridgeDatasetTest.ts +4 -5
- package/src/test/fixtures/account.fixture.ts +2 -2
- package/src/test/fixtures/common.fixture.ts +74 -0
- package/src/test/fixtures/currency.fixture.ts +66 -14
- package/src/test/fixtures/mirror.fixture.ts +23 -1
- package/src/test/fixtures/thirdweb.fixture.ts +33 -0
- package/src/transaction.ts +2 -0
- package/src/types/alpaca.ts +8 -1
- package/src/types/bridge.ts +6 -1
- package/src/types/index.ts +2 -0
- package/src/types/logic.ts +44 -0
- package/src/types/mirror.ts +35 -0
- package/src/types/thirdweb.ts +36 -0
package/src/network/api.test.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
1
2
|
import network from "@ledgerhq/live-network";
|
|
2
3
|
import { apiClient } from "./api";
|
|
3
4
|
import { getMockResponse } from "../test/fixtures/network.fixture";
|
|
5
|
+
import type {
|
|
6
|
+
HederaMirrorContractCallResult,
|
|
7
|
+
HederaMirrorNetworkFees,
|
|
8
|
+
HederaMirrorTransaction,
|
|
9
|
+
} from "../types";
|
|
4
10
|
|
|
5
11
|
jest.mock("@ledgerhq/live-network");
|
|
6
12
|
const mockedNetwork = jest.mocked(network);
|
|
@@ -10,7 +16,7 @@ describe("getAccountTransactions", () => {
|
|
|
10
16
|
jest.resetAllMocks();
|
|
11
17
|
});
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
it("should include 'account.id', 'limit=100' and 'order=desc' query params", async () => {
|
|
14
20
|
mockedNetwork.mockResolvedValueOnce(
|
|
15
21
|
getMockResponse({ transactions: [], links: { next: null } }),
|
|
16
22
|
);
|
|
@@ -27,7 +33,7 @@ describe("getAccountTransactions", () => {
|
|
|
27
33
|
expect(requestUrl).toContain("order=desc");
|
|
28
34
|
});
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
it("should keep fetching if fetchAllPages is set and links.next is present", async () => {
|
|
31
37
|
mockedNetwork
|
|
32
38
|
.mockResolvedValueOnce(
|
|
33
39
|
getMockResponse({
|
|
@@ -72,7 +78,7 @@ describe("getAccountTransactions", () => {
|
|
|
72
78
|
expect(mockedNetwork).toHaveBeenCalledTimes(5);
|
|
73
79
|
});
|
|
74
80
|
|
|
75
|
-
|
|
81
|
+
it("should paginate if fetchAllPages is not set", async () => {
|
|
76
82
|
mockedNetwork
|
|
77
83
|
.mockResolvedValueOnce(
|
|
78
84
|
getMockResponse({
|
|
@@ -192,3 +198,205 @@ describe("getAccountTokens", () => {
|
|
|
192
198
|
expect(mockedNetwork).toHaveBeenCalledTimes(2);
|
|
193
199
|
});
|
|
194
200
|
});
|
|
201
|
+
|
|
202
|
+
describe("getNetworkFees", () => {
|
|
203
|
+
beforeEach(() => {
|
|
204
|
+
jest.clearAllMocks();
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it("should call the correct endpoint and return network fees", async () => {
|
|
208
|
+
const mockedResults: HederaMirrorNetworkFees = {
|
|
209
|
+
fees: [{ gas: 39, transaction_type: "ContractCall" }],
|
|
210
|
+
timestamp: "1758733200.632122898",
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
mockedNetwork.mockResolvedValueOnce(getMockResponse(mockedResults));
|
|
214
|
+
|
|
215
|
+
const result = await apiClient.getNetworkFees();
|
|
216
|
+
const requestUrl = mockedNetwork.mock.calls[0][0].url;
|
|
217
|
+
|
|
218
|
+
expect(result).toEqual(mockedResults);
|
|
219
|
+
expect(requestUrl).toContain("/api/v1/network/fees");
|
|
220
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(1);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe("getContractCallResult", () => {
|
|
225
|
+
beforeEach(() => {
|
|
226
|
+
jest.clearAllMocks();
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it("should call the correct endpoint and return results for contract call", async () => {
|
|
230
|
+
const mockedResults: HederaMirrorContractCallResult = {
|
|
231
|
+
contract_id: "0.0.4321",
|
|
232
|
+
block_gas_used: 100,
|
|
233
|
+
gas_consumed: 200,
|
|
234
|
+
gas_limit: 10000,
|
|
235
|
+
gas_used: 150,
|
|
236
|
+
timestamp: "xxxxxxxxx",
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
mockedNetwork.mockResolvedValueOnce(
|
|
240
|
+
getMockResponse({
|
|
241
|
+
contract_id: "0.0.4321",
|
|
242
|
+
block_gas_used: 100,
|
|
243
|
+
gas_consumed: 200,
|
|
244
|
+
gas_limit: 10000,
|
|
245
|
+
gas_used: 150,
|
|
246
|
+
timestamp: "xxxxxxxxx",
|
|
247
|
+
}),
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
const result = await apiClient.getContractCallResult(
|
|
251
|
+
"0xa9059cbb000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000186a0",
|
|
252
|
+
);
|
|
253
|
+
const requestUrl = mockedNetwork.mock.calls[0][0].url;
|
|
254
|
+
|
|
255
|
+
expect(result).toEqual(mockedResults);
|
|
256
|
+
expect(requestUrl).toContain("/api/v1/contracts/results");
|
|
257
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(1);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
describe("findTransactionByContractCall", () => {
|
|
262
|
+
beforeEach(() => {
|
|
263
|
+
jest.clearAllMocks();
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it("should call the correct endpoint and return transaction details", async () => {
|
|
267
|
+
const mockedResults: HederaMirrorTransaction = {
|
|
268
|
+
transfers: [],
|
|
269
|
+
token_transfers: [],
|
|
270
|
+
charged_tx_fee: 100,
|
|
271
|
+
transaction_id: "xxxxxxxxxxxxxx",
|
|
272
|
+
transaction_hash: "xxxxxxxxxxxxx",
|
|
273
|
+
consensus_timestamp: "xxxxxxxxxxxxx",
|
|
274
|
+
result: "xxxxxxxxxxxxx",
|
|
275
|
+
entity_id: "0.0.1234",
|
|
276
|
+
name: "CONTRACTCALL",
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
mockedNetwork.mockResolvedValueOnce(
|
|
280
|
+
getMockResponse({
|
|
281
|
+
transactions: [mockedResults],
|
|
282
|
+
}),
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
const result = await apiClient.findTransactionByContractCall(
|
|
286
|
+
"xxxxxxxxxxxxxxxxxxxx",
|
|
287
|
+
"0.0.1234",
|
|
288
|
+
);
|
|
289
|
+
const requestUrl = mockedNetwork.mock.calls[0][0].url;
|
|
290
|
+
|
|
291
|
+
expect(result).toEqual(mockedResults);
|
|
292
|
+
expect(requestUrl).toContain("/api/v1/transactions?timestamp=");
|
|
293
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(1);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it("should call the correct endpoint and return null for non existing contract calls", async () => {
|
|
297
|
+
mockedNetwork.mockResolvedValueOnce(
|
|
298
|
+
getMockResponse({
|
|
299
|
+
transactions: [
|
|
300
|
+
{
|
|
301
|
+
transfers: [],
|
|
302
|
+
token_transfers: [],
|
|
303
|
+
charged_tx_fee: 100,
|
|
304
|
+
transaction_hash: "xxxxxxxxxxxxx",
|
|
305
|
+
consensus_timestamp: "xxxxxxxxxxxxx",
|
|
306
|
+
result: "xxxxxxxxxxxxx",
|
|
307
|
+
entity_id: "0.0.1234",
|
|
308
|
+
name: "NOT_CONTRACTCALL",
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
transfers: [],
|
|
312
|
+
token_transfers: [],
|
|
313
|
+
charged_tx_fee: 100,
|
|
314
|
+
transaction_hash: "xxxxxxxxxxxxx",
|
|
315
|
+
consensus_timestamp: "xxxxxxxxxxxxx",
|
|
316
|
+
result: "xxxxxxxxxxxxx",
|
|
317
|
+
entity_id: "0.0.1111",
|
|
318
|
+
name: "CONTRACTCALL",
|
|
319
|
+
},
|
|
320
|
+
],
|
|
321
|
+
}),
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
const result = await apiClient.findTransactionByContractCall(
|
|
325
|
+
"xxxxxxxxxxxxxxxxxxxx",
|
|
326
|
+
"0.0.1234",
|
|
327
|
+
);
|
|
328
|
+
const requestUrl = mockedNetwork.mock.calls[0][0].url;
|
|
329
|
+
|
|
330
|
+
expect(result).toEqual(null);
|
|
331
|
+
expect(requestUrl).toContain("/api/v1/transactions?timestamp=");
|
|
332
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(1);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
it("should call the correct endpoint and return null for empty transactions list", async () => {
|
|
336
|
+
mockedNetwork.mockResolvedValueOnce(
|
|
337
|
+
getMockResponse({
|
|
338
|
+
transactions: [],
|
|
339
|
+
}),
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
const result = await apiClient.findTransactionByContractCall(
|
|
343
|
+
"xxxxxxxxxxxxxxxxxxxx",
|
|
344
|
+
"0.0.1234",
|
|
345
|
+
);
|
|
346
|
+
const requestUrl = mockedNetwork.mock.calls[0][0].url;
|
|
347
|
+
|
|
348
|
+
expect(result).toEqual(null);
|
|
349
|
+
expect(requestUrl).toContain("/api/v1/transactions?timestamp=");
|
|
350
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(1);
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
describe("getERC20Balance", () => {
|
|
355
|
+
beforeEach(() => {
|
|
356
|
+
jest.clearAllMocks();
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
it("should call the correct endpoint and return the contract balance", async () => {
|
|
360
|
+
mockedNetwork.mockResolvedValueOnce(
|
|
361
|
+
getMockResponse({
|
|
362
|
+
result: "1000000000",
|
|
363
|
+
}),
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
const result = await apiClient.getERC20Balance(
|
|
367
|
+
"0x0000000000000000000000000000000000000001",
|
|
368
|
+
"0x0000000000000000000000000000000000000002",
|
|
369
|
+
);
|
|
370
|
+
const requestUrl = mockedNetwork.mock.calls[0][0].url;
|
|
371
|
+
|
|
372
|
+
expect(result).toEqual(BigNumber("1000000000"));
|
|
373
|
+
expect(requestUrl).toContain("/api/v1/contracts/call");
|
|
374
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(1);
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
describe("estimateContractCallGas", () => {
|
|
379
|
+
beforeEach(() => {
|
|
380
|
+
jest.clearAllMocks();
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it("should call the correct endpoint and return estimated contract call gas", async () => {
|
|
384
|
+
mockedNetwork.mockResolvedValueOnce(
|
|
385
|
+
getMockResponse({
|
|
386
|
+
result: "1000000000",
|
|
387
|
+
}),
|
|
388
|
+
);
|
|
389
|
+
|
|
390
|
+
const result = await apiClient.estimateContractCallGas(
|
|
391
|
+
"0x0000000000000000000000000000000000000001",
|
|
392
|
+
"0x0000000000000000000000000000000000000002",
|
|
393
|
+
"0xa9059cbb000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000186a0",
|
|
394
|
+
BigInt(1000),
|
|
395
|
+
);
|
|
396
|
+
const requestUrl = mockedNetwork.mock.calls[0][0].url;
|
|
397
|
+
|
|
398
|
+
expect(result).toEqual(BigNumber("1000000000"));
|
|
399
|
+
expect(requestUrl).toContain("/api/v1/contracts/call");
|
|
400
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(1);
|
|
401
|
+
});
|
|
402
|
+
});
|
package/src/network/api.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
import { encodeFunctionData, erc20Abi } from "viem";
|
|
1
3
|
import network from "@ledgerhq/live-network";
|
|
2
4
|
import type { LiveNetworkResponse } from "@ledgerhq/live-network/network";
|
|
3
5
|
import { getEnv } from "@ledgerhq/live-env";
|
|
@@ -10,23 +12,21 @@ import type {
|
|
|
10
12
|
HederaMirrorAccountsResponse,
|
|
11
13
|
HederaMirrorToken,
|
|
12
14
|
HederaMirrorTransaction,
|
|
15
|
+
HederaMirrorNetworkFees,
|
|
16
|
+
HederaMirrorContractCallResult,
|
|
17
|
+
HederaMirrorContractCallBalance,
|
|
18
|
+
HederaMirrorContractCallEstimate,
|
|
13
19
|
} from "../types";
|
|
14
20
|
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
const fetch = <Result>(path: string) => {
|
|
18
|
-
return network<Result>({
|
|
19
|
-
method: "GET",
|
|
20
|
-
url: `${getMirrorApiUrl()}${path}`,
|
|
21
|
-
});
|
|
22
|
-
};
|
|
21
|
+
const API_URL = getEnv("API_HEDERA_MIRROR");
|
|
23
22
|
|
|
24
23
|
async function getAccountsForPublicKey(publicKey: string): Promise<HederaMirrorAccount[]> {
|
|
25
24
|
let res;
|
|
26
25
|
try {
|
|
27
|
-
res = await
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
res = await network<HederaMirrorAccountsResponse>({
|
|
27
|
+
method: "GET",
|
|
28
|
+
url: `${API_URL}/api/v1/accounts?account.publicKey=${publicKey}&balance=true&limit=100`,
|
|
29
|
+
});
|
|
30
30
|
} catch (e: unknown) {
|
|
31
31
|
if (e instanceof LedgerAPI4xx) return [];
|
|
32
32
|
throw e;
|
|
@@ -39,7 +39,10 @@ async function getAccountsForPublicKey(publicKey: string): Promise<HederaMirrorA
|
|
|
39
39
|
|
|
40
40
|
async function getAccount(address: string): Promise<HederaMirrorAccount> {
|
|
41
41
|
try {
|
|
42
|
-
const res = await
|
|
42
|
+
const res = await network<HederaMirrorAccount>({
|
|
43
|
+
method: "GET",
|
|
44
|
+
url: `${API_URL}/api/v1/accounts/${address}`,
|
|
45
|
+
});
|
|
43
46
|
const account = res.data;
|
|
44
47
|
|
|
45
48
|
return account;
|
|
@@ -83,16 +86,19 @@ async function getAccountTransactions({
|
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
let nextCursor: string | null = null;
|
|
86
|
-
let
|
|
89
|
+
let nextPath: string | null = `/api/v1/transactions?${params.toString()}`;
|
|
87
90
|
|
|
88
91
|
// WARNING: don't break the loop when `transactions` array is empty but `links.next` is present
|
|
89
92
|
// the mirror node API enforces a 60-day max time range per query, even if `timestamp` param is set
|
|
90
93
|
// see: https://hedera.com/blog/changes-to-the-hedera-operated-mirror-node
|
|
91
|
-
while (
|
|
92
|
-
const res: LiveNetworkResponse<HederaMirrorTransactionsResponse> = await
|
|
94
|
+
while (nextPath) {
|
|
95
|
+
const res: LiveNetworkResponse<HederaMirrorTransactionsResponse> = await network({
|
|
96
|
+
method: "GET",
|
|
97
|
+
url: `${API_URL}${nextPath}`,
|
|
98
|
+
});
|
|
93
99
|
const newTransactions = res.data.transactions;
|
|
94
100
|
transactions.push(...newTransactions);
|
|
95
|
-
|
|
101
|
+
nextPath = res.data.links.next;
|
|
96
102
|
|
|
97
103
|
// stop fetching if pagination mode is used and we reached the limit
|
|
98
104
|
if (!fetchAllPages && transactions.length >= limit) {
|
|
@@ -106,7 +112,7 @@ async function getAccountTransactions({
|
|
|
106
112
|
}
|
|
107
113
|
|
|
108
114
|
// set the next cursor only if we have more transactions to fetch
|
|
109
|
-
if (!fetchAllPages &&
|
|
115
|
+
if (!fetchAllPages && nextPath) {
|
|
110
116
|
const lastTx = transactions.at(-1);
|
|
111
117
|
nextCursor = lastTx?.consensus_timestamp ?? null;
|
|
112
118
|
}
|
|
@@ -120,13 +126,16 @@ async function getAccountTokens(address: string): Promise<HederaMirrorToken[]> {
|
|
|
120
126
|
limit: "100",
|
|
121
127
|
});
|
|
122
128
|
|
|
123
|
-
let
|
|
129
|
+
let nextPath: string | null = `/api/v1/accounts/${address}/tokens?${params.toString()}`;
|
|
124
130
|
|
|
125
|
-
while (
|
|
126
|
-
const res: LiveNetworkResponse<HederaMirrorAccountTokensResponse> = await
|
|
131
|
+
while (nextPath) {
|
|
132
|
+
const res: LiveNetworkResponse<HederaMirrorAccountTokensResponse> = await network({
|
|
133
|
+
method: "GET",
|
|
134
|
+
url: `${API_URL}${nextPath}`,
|
|
135
|
+
});
|
|
127
136
|
const newTokens = res.data.tokens;
|
|
128
137
|
tokens.push(...newTokens);
|
|
129
|
-
|
|
138
|
+
nextPath = res.data.links.next;
|
|
130
139
|
}
|
|
131
140
|
|
|
132
141
|
return tokens;
|
|
@@ -138,9 +147,10 @@ async function getLatestTransaction(): Promise<HederaMirrorTransaction> {
|
|
|
138
147
|
order: "desc",
|
|
139
148
|
});
|
|
140
149
|
|
|
141
|
-
const res = await
|
|
142
|
-
|
|
143
|
-
|
|
150
|
+
const res = await network<HederaMirrorTransactionsResponse>({
|
|
151
|
+
method: "GET",
|
|
152
|
+
url: `${API_URL}/api/v1/transactions?${params.toString()}`,
|
|
153
|
+
});
|
|
144
154
|
const transaction = res.data.transactions[0];
|
|
145
155
|
|
|
146
156
|
if (!transaction) {
|
|
@@ -150,10 +160,94 @@ async function getLatestTransaction(): Promise<HederaMirrorTransaction> {
|
|
|
150
160
|
return transaction;
|
|
151
161
|
}
|
|
152
162
|
|
|
163
|
+
async function getNetworkFees(): Promise<HederaMirrorNetworkFees> {
|
|
164
|
+
const res = await network<HederaMirrorNetworkFees>({
|
|
165
|
+
method: "GET",
|
|
166
|
+
url: `${API_URL}/api/v1/network/fees`,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return res.data;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async function getContractCallResult(
|
|
173
|
+
transactionHash: string,
|
|
174
|
+
): Promise<HederaMirrorContractCallResult> {
|
|
175
|
+
const res = await network<HederaMirrorContractCallResult>({
|
|
176
|
+
method: "GET",
|
|
177
|
+
url: `${API_URL}/api/v1/contracts/results/${transactionHash}`,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
return res.data;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function findTransactionByContractCall(
|
|
184
|
+
timestamp: string,
|
|
185
|
+
contractId: string,
|
|
186
|
+
): Promise<HederaMirrorTransaction | null> {
|
|
187
|
+
const res = await network<HederaMirrorTransactionsResponse>({
|
|
188
|
+
method: "GET",
|
|
189
|
+
url: `${API_URL}/api/v1/transactions?timestamp=${timestamp}`,
|
|
190
|
+
});
|
|
191
|
+
const transactions = res.data.transactions;
|
|
192
|
+
|
|
193
|
+
return transactions.find(el => el.name === "CONTRACTCALL" && el.entity_id === contractId) ?? null;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async function getERC20Balance(
|
|
197
|
+
accountEvmAddress: string,
|
|
198
|
+
contractEvmAddress: string,
|
|
199
|
+
): Promise<BigNumber> {
|
|
200
|
+
const res = await network<HederaMirrorContractCallBalance>({
|
|
201
|
+
method: "POST",
|
|
202
|
+
url: `${API_URL}/api/v1/contracts/call`,
|
|
203
|
+
data: {
|
|
204
|
+
block: "latest",
|
|
205
|
+
to: contractEvmAddress,
|
|
206
|
+
data: encodeFunctionData({
|
|
207
|
+
abi: erc20Abi,
|
|
208
|
+
functionName: "balanceOf",
|
|
209
|
+
args: [accountEvmAddress as `0x${string}`],
|
|
210
|
+
}),
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
return new BigNumber(res.data.result);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function estimateContractCallGas(
|
|
218
|
+
senderEvmAddress: string,
|
|
219
|
+
recipientEvmAddress: string,
|
|
220
|
+
contractEvmAddress: string,
|
|
221
|
+
amount: bigint,
|
|
222
|
+
): Promise<BigNumber> {
|
|
223
|
+
const res = await network<HederaMirrorContractCallEstimate>({
|
|
224
|
+
method: "POST",
|
|
225
|
+
url: `${API_URL}/api/v1/contracts/call`,
|
|
226
|
+
data: {
|
|
227
|
+
block: "latest",
|
|
228
|
+
estimate: true,
|
|
229
|
+
from: senderEvmAddress,
|
|
230
|
+
to: contractEvmAddress,
|
|
231
|
+
data: encodeFunctionData({
|
|
232
|
+
abi: erc20Abi,
|
|
233
|
+
functionName: "transfer",
|
|
234
|
+
args: [recipientEvmAddress as `0x${string}`, amount],
|
|
235
|
+
}),
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
return new BigNumber(res.data.result);
|
|
240
|
+
}
|
|
241
|
+
|
|
153
242
|
export const apiClient = {
|
|
154
243
|
getAccountsForPublicKey,
|
|
155
244
|
getAccount,
|
|
156
245
|
getAccountTokens,
|
|
157
246
|
getAccountTransactions,
|
|
158
247
|
getLatestTransaction,
|
|
248
|
+
getNetworkFees,
|
|
249
|
+
getContractCallResult,
|
|
250
|
+
findTransactionByContractCall,
|
|
251
|
+
getERC20Balance,
|
|
252
|
+
estimateContractCallGas,
|
|
159
253
|
};
|
package/src/network/rpc.test.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Client, Transaction, TransactionResponse } from "@hashgraph/sdk";
|
|
|
2
2
|
import { rpcClient } from "./rpc";
|
|
3
3
|
|
|
4
4
|
const mockClient = {
|
|
5
|
+
close: jest.fn(),
|
|
5
6
|
setMaxNodesPerTransaction: jest.fn().mockReturnThis(),
|
|
6
7
|
setNetwork: jest.fn().mockReturnThis(),
|
|
7
8
|
} as unknown as Client;
|
package/src/network/rpc.ts
CHANGED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { pad } from "viem";
|
|
2
|
+
import network from "@ledgerhq/live-network";
|
|
3
|
+
import { getMockedThirdwebTransaction } from "../test/fixtures/thirdweb.fixture";
|
|
4
|
+
import { getMockResponse } from "../test/fixtures/common.fixture";
|
|
5
|
+
import { thirdwebClient } from "./thirdweb";
|
|
6
|
+
|
|
7
|
+
jest.mock("@ledgerhq/live-network");
|
|
8
|
+
const mockedNetwork = jest.mocked(network);
|
|
9
|
+
|
|
10
|
+
const mockedERC20Transaction = getMockedThirdwebTransaction();
|
|
11
|
+
const mockedERC20TokenAddress1 = "0x0000000000000000000000000000000000000001";
|
|
12
|
+
const mockedERC20TokenAddress2 = "0x0000000000000000000000000000000000000002";
|
|
13
|
+
const mockedTopic0Address = pad("0x0000000000000000000000000000000000000000");
|
|
14
|
+
const mockedTopic1Address = pad("0x0000000000000000000000000000000000000003");
|
|
15
|
+
|
|
16
|
+
describe("fetchERC20Transactions", () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
jest.clearAllMocks();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("should include 'page', 'limit=1000' and filterTopic query params", async () => {
|
|
22
|
+
mockedNetwork.mockResolvedValueOnce(
|
|
23
|
+
getMockResponse({
|
|
24
|
+
result: {
|
|
25
|
+
events: [],
|
|
26
|
+
pagination: { limit: 1000, page: 1, totalCount: 0 },
|
|
27
|
+
},
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const params = {
|
|
32
|
+
limit: "1000",
|
|
33
|
+
page: "1",
|
|
34
|
+
filterTopic0: mockedTopic0Address,
|
|
35
|
+
filterTopic1: mockedTopic1Address,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
await thirdwebClient.fetchERC20Transactions(mockedERC20TokenAddress1, params);
|
|
39
|
+
|
|
40
|
+
const requestUrl = mockedNetwork.mock.calls[0][0].url;
|
|
41
|
+
expect(requestUrl).toContain("page=1");
|
|
42
|
+
expect(requestUrl).toContain("limit=1000");
|
|
43
|
+
expect(requestUrl).toContain(`filterTopic0=${mockedTopic0Address}`);
|
|
44
|
+
expect(requestUrl).toContain(`filterTopic1=${mockedTopic1Address}`);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should fire only once and return single element", async () => {
|
|
48
|
+
mockedNetwork.mockResolvedValueOnce(
|
|
49
|
+
getMockResponse({
|
|
50
|
+
result: {
|
|
51
|
+
events: [mockedERC20Transaction],
|
|
52
|
+
pagination: { limit: 1000, page: 1, totalCount: 1 },
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const params = {
|
|
58
|
+
limit: "1000",
|
|
59
|
+
page: "1",
|
|
60
|
+
filterTopic0: mockedTopic0Address,
|
|
61
|
+
filterTopic1: mockedTopic1Address,
|
|
62
|
+
};
|
|
63
|
+
const result = await thirdwebClient.fetchERC20Transactions(mockedERC20TokenAddress1, params);
|
|
64
|
+
|
|
65
|
+
expect(result).toHaveLength(1);
|
|
66
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(1);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("should fire only once and return empty array", async () => {
|
|
70
|
+
mockedNetwork.mockResolvedValueOnce(
|
|
71
|
+
getMockResponse({
|
|
72
|
+
result: {
|
|
73
|
+
events: [],
|
|
74
|
+
pagination: { limit: 1000, page: 1, totalCount: 0 },
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const params = {
|
|
80
|
+
limit: "1000",
|
|
81
|
+
page: "1",
|
|
82
|
+
filterTopic0: mockedTopic0Address,
|
|
83
|
+
filterTopic1: mockedTopic1Address,
|
|
84
|
+
};
|
|
85
|
+
const result = await thirdwebClient.fetchERC20Transactions(mockedERC20TokenAddress1, params);
|
|
86
|
+
|
|
87
|
+
expect(result).toHaveLength(0);
|
|
88
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(1);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("should keep fetching until returned events are fewer than requested limit", async () => {
|
|
92
|
+
mockedNetwork
|
|
93
|
+
.mockResolvedValueOnce(
|
|
94
|
+
getMockResponse({
|
|
95
|
+
result: {
|
|
96
|
+
events: [mockedERC20Transaction, mockedERC20Transaction],
|
|
97
|
+
pagination: { limit: 2, page: 1, totalCount: 2 },
|
|
98
|
+
},
|
|
99
|
+
}),
|
|
100
|
+
)
|
|
101
|
+
.mockResolvedValueOnce(
|
|
102
|
+
getMockResponse({
|
|
103
|
+
result: {
|
|
104
|
+
events: [mockedERC20Transaction, mockedERC20Transaction],
|
|
105
|
+
pagination: { limit: 2, page: 2, totalCount: 2 },
|
|
106
|
+
},
|
|
107
|
+
}),
|
|
108
|
+
)
|
|
109
|
+
.mockResolvedValueOnce(
|
|
110
|
+
getMockResponse({
|
|
111
|
+
result: {
|
|
112
|
+
events: [mockedERC20Transaction],
|
|
113
|
+
pagination: { limit: 2, page: 3, totalCount: 2 },
|
|
114
|
+
},
|
|
115
|
+
}),
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const params = {
|
|
119
|
+
limit: "2",
|
|
120
|
+
filterTopic0: mockedTopic0Address,
|
|
121
|
+
filterTopic1: mockedTopic1Address,
|
|
122
|
+
};
|
|
123
|
+
const result = await thirdwebClient.fetchERC20Transactions(mockedERC20TokenAddress1, params);
|
|
124
|
+
|
|
125
|
+
expect(result).toHaveLength(5);
|
|
126
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(3);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe("getERC20TransactionsForAccount", () => {
|
|
131
|
+
beforeEach(() => {
|
|
132
|
+
jest.clearAllMocks();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("should return empty array without balance tokens list", async () => {
|
|
136
|
+
const result = await thirdwebClient.getERC20TransactionsForAccount({
|
|
137
|
+
address: "0.0.1234",
|
|
138
|
+
contractAddresses: [],
|
|
139
|
+
since: null,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
expect(result).toHaveLength(0);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("should return exactly 2 transactions (out & in)", async () => {
|
|
146
|
+
const mockFetcher = jest.fn().mockResolvedValue([mockedERC20Transaction]);
|
|
147
|
+
|
|
148
|
+
const result = await thirdwebClient.getERC20TransactionsForAccount({
|
|
149
|
+
address: "0.0.1234",
|
|
150
|
+
contractAddresses: [mockedERC20TokenAddress1],
|
|
151
|
+
since: null,
|
|
152
|
+
transactionFetcher: mockFetcher,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
expect(result).toHaveLength(2);
|
|
156
|
+
expect(mockFetcher).toHaveBeenCalledTimes(2);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("should return exactly 4 transactions total for 2 tokens (out & in)", async () => {
|
|
160
|
+
const mockFetcher = jest.fn().mockResolvedValue([mockedERC20Transaction]);
|
|
161
|
+
|
|
162
|
+
const result = await thirdwebClient.getERC20TransactionsForAccount({
|
|
163
|
+
address: "0.0.1234",
|
|
164
|
+
contractAddresses: [mockedERC20TokenAddress1, mockedERC20TokenAddress2],
|
|
165
|
+
since: null,
|
|
166
|
+
transactionFetcher: mockFetcher,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
expect(result).toHaveLength(4);
|
|
170
|
+
expect(mockFetcher).toHaveBeenCalledTimes(4);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("should return exactly 4 transactions for single token (out & in)", async () => {
|
|
174
|
+
const mockFetcher = jest
|
|
175
|
+
.fn()
|
|
176
|
+
.mockResolvedValue([mockedERC20Transaction, mockedERC20Transaction]);
|
|
177
|
+
|
|
178
|
+
const result = await thirdwebClient.getERC20TransactionsForAccount({
|
|
179
|
+
address: "0.0.1234",
|
|
180
|
+
contractAddresses: [mockedERC20TokenAddress1],
|
|
181
|
+
since: null,
|
|
182
|
+
transactionFetcher: mockFetcher,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
expect(result).toHaveLength(4);
|
|
186
|
+
expect(mockFetcher).toHaveBeenCalledTimes(2);
|
|
187
|
+
});
|
|
188
|
+
});
|