@ledgerhq/coin-vechain 3.0.0 → 4.0.0
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/.unimportedrc.json +2 -1
- package/CHANGELOG.md +42 -2699
- package/lib/api/index.d.ts +2 -2
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.js +25 -22
- package/lib/api/index.js.map +1 -1
- package/lib/bridge/broadcast.d.ts.map +1 -1
- package/lib/bridge/broadcast.js +2 -1
- package/lib/bridge/broadcast.js.map +1 -1
- package/lib/bridge/createTransaction.js +1 -1
- package/lib/bridge/createTransaction.js.map +1 -1
- package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -1
- package/lib/bridge/estimateMaxSpendable.js +2 -1
- package/lib/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/getTransactionStatus.js +2 -1
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib/bridge/prepareTransaction.js +4 -2
- package/lib/bridge/prepareTransaction.js.map +1 -1
- package/lib/bridge/synchronisation.d.ts.map +1 -1
- package/lib/bridge/synchronisation.js +6 -4
- package/lib/bridge/synchronisation.js.map +1 -1
- package/lib/common-logic/calculateGasFees.d.ts +2 -1
- package/lib/common-logic/calculateGasFees.d.ts.map +1 -1
- package/lib/common-logic/calculateGasFees.js +3 -3
- package/lib/common-logic/calculateGasFees.js.map +1 -1
- package/lib/common-logic/calculateTransactionInfo.d.ts +2 -1
- package/lib/common-logic/calculateTransactionInfo.d.ts.map +1 -1
- package/lib/common-logic/calculateTransactionInfo.js +2 -2
- package/lib/common-logic/calculateTransactionInfo.js.map +1 -1
- package/lib/common-logic/estimateGas.d.ts +2 -1
- package/lib/common-logic/estimateGas.d.ts.map +1 -1
- package/lib/common-logic/estimateGas.js +2 -2
- package/lib/common-logic/estimateGas.js.map +1 -1
- package/lib/common-logic/getThorClient.d.ts +2 -1
- package/lib/common-logic/getThorClient.d.ts.map +1 -1
- package/lib/common-logic/getThorClient.js +2 -2
- package/lib/common-logic/getThorClient.js.map +1 -1
- package/lib/common-logic/mapTransfersToOperations.d.ts +3 -2
- package/lib/common-logic/mapTransfersToOperations.d.ts.map +1 -1
- package/lib/common-logic/mapTransfersToOperations.js +4 -4
- package/lib/common-logic/mapTransfersToOperations.js.map +1 -1
- package/lib/config.d.ts +10 -4
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +9 -5
- package/lib/config.js.map +1 -1
- package/lib/logic/account/getBalance.d.ts +2 -1
- package/lib/logic/account/getBalance.d.ts.map +1 -1
- package/lib/logic/account/getBalance.js +3 -2
- package/lib/logic/account/getBalance.js.map +1 -1
- package/lib/logic/history/getBlock.d.ts +2 -1
- package/lib/logic/history/getBlock.d.ts.map +1 -1
- package/lib/logic/history/getBlock.js +3 -2
- package/lib/logic/history/getBlock.js.map +1 -1
- package/lib/logic/history/getBlockInfo.d.ts +2 -1
- package/lib/logic/history/getBlockInfo.d.ts.map +1 -1
- package/lib/logic/history/getBlockInfo.js +3 -2
- package/lib/logic/history/getBlockInfo.js.map +1 -1
- package/lib/logic/history/lastBlock.d.ts +2 -1
- package/lib/logic/history/lastBlock.d.ts.map +1 -1
- package/lib/logic/history/lastBlock.js +4 -3
- package/lib/logic/history/lastBlock.js.map +1 -1
- package/lib/logic/history/listOperations.d.ts +2 -1
- package/lib/logic/history/listOperations.d.ts.map +1 -1
- package/lib/logic/history/listOperations.js +5 -4
- package/lib/logic/history/listOperations.js.map +1 -1
- package/lib/logic/transaction/broadcast.d.ts +2 -1
- package/lib/logic/transaction/broadcast.d.ts.map +1 -1
- package/lib/logic/transaction/broadcast.js +3 -2
- package/lib/logic/transaction/broadcast.js.map +1 -1
- package/lib/logic/transaction/combine.d.ts +1 -1
- package/lib/logic/transaction/combine.d.ts.map +1 -1
- package/lib/logic/transaction/combine.js +4 -1
- package/lib/logic/transaction/combine.js.map +1 -1
- package/lib/logic/transaction/craftTransaction.d.ts +2 -1
- package/lib/logic/transaction/craftTransaction.d.ts.map +1 -1
- package/lib/logic/transaction/craftTransaction.js +11 -10
- package/lib/logic/transaction/craftTransaction.js.map +1 -1
- package/lib/logic/transaction/estimateFees.d.ts +2 -1
- package/lib/logic/transaction/estimateFees.d.ts.map +1 -1
- package/lib/logic/transaction/estimateFees.js +2 -2
- package/lib/logic/transaction/estimateFees.js.map +1 -1
- package/lib/network/getBlock.d.ts +2 -1
- package/lib/network/getBlock.d.ts.map +1 -1
- package/lib/network/getBlock.js +2 -2
- package/lib/network/getBlock.js.map +1 -1
- package/lib/network/getFees.d.ts +2 -1
- package/lib/network/getFees.d.ts.map +1 -1
- package/lib/network/getFees.js +2 -2
- package/lib/network/getFees.js.map +1 -1
- package/lib/network/sdk.d.ts +7 -6
- package/lib/network/sdk.d.ts.map +1 -1
- package/lib/network/sdk.js +18 -18
- package/lib/network/sdk.js.map +1 -1
- package/lib/test/context.d.ts +6 -0
- package/lib/test/context.d.ts.map +1 -0
- package/lib/test/context.js +15 -0
- package/lib/test/context.js.map +1 -0
- package/lib-es/api/index.d.ts +2 -2
- package/lib-es/api/index.d.ts.map +1 -1
- package/lib-es/api/index.js +25 -22
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/bridge/broadcast.d.ts.map +1 -1
- package/lib-es/bridge/broadcast.js +2 -1
- package/lib-es/bridge/broadcast.js.map +1 -1
- package/lib-es/bridge/createTransaction.js +2 -2
- package/lib-es/bridge/createTransaction.js.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.js +2 -1
- 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 +2 -1
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib-es/bridge/prepareTransaction.js +4 -2
- package/lib-es/bridge/prepareTransaction.js.map +1 -1
- package/lib-es/bridge/synchronisation.d.ts.map +1 -1
- package/lib-es/bridge/synchronisation.js +6 -4
- package/lib-es/bridge/synchronisation.js.map +1 -1
- package/lib-es/common-logic/calculateGasFees.d.ts +2 -1
- package/lib-es/common-logic/calculateGasFees.d.ts.map +1 -1
- package/lib-es/common-logic/calculateGasFees.js +3 -3
- package/lib-es/common-logic/calculateGasFees.js.map +1 -1
- package/lib-es/common-logic/calculateTransactionInfo.d.ts +2 -1
- package/lib-es/common-logic/calculateTransactionInfo.d.ts.map +1 -1
- package/lib-es/common-logic/calculateTransactionInfo.js +2 -2
- package/lib-es/common-logic/calculateTransactionInfo.js.map +1 -1
- package/lib-es/common-logic/estimateGas.d.ts +2 -1
- package/lib-es/common-logic/estimateGas.d.ts.map +1 -1
- package/lib-es/common-logic/estimateGas.js +2 -2
- package/lib-es/common-logic/estimateGas.js.map +1 -1
- package/lib-es/common-logic/getThorClient.d.ts +2 -1
- package/lib-es/common-logic/getThorClient.d.ts.map +1 -1
- package/lib-es/common-logic/getThorClient.js +2 -2
- package/lib-es/common-logic/getThorClient.js.map +1 -1
- package/lib-es/common-logic/mapTransfersToOperations.d.ts +3 -2
- package/lib-es/common-logic/mapTransfersToOperations.d.ts.map +1 -1
- package/lib-es/common-logic/mapTransfersToOperations.js +4 -4
- package/lib-es/common-logic/mapTransfersToOperations.js.map +1 -1
- package/lib-es/config.d.ts +10 -4
- package/lib-es/config.d.ts.map +1 -1
- package/lib-es/config.js +9 -5
- package/lib-es/config.js.map +1 -1
- package/lib-es/logic/account/getBalance.d.ts +2 -1
- package/lib-es/logic/account/getBalance.d.ts.map +1 -1
- package/lib-es/logic/account/getBalance.js +3 -2
- package/lib-es/logic/account/getBalance.js.map +1 -1
- package/lib-es/logic/history/getBlock.d.ts +2 -1
- package/lib-es/logic/history/getBlock.d.ts.map +1 -1
- package/lib-es/logic/history/getBlock.js +3 -2
- package/lib-es/logic/history/getBlock.js.map +1 -1
- package/lib-es/logic/history/getBlockInfo.d.ts +2 -1
- package/lib-es/logic/history/getBlockInfo.d.ts.map +1 -1
- package/lib-es/logic/history/getBlockInfo.js +3 -2
- package/lib-es/logic/history/getBlockInfo.js.map +1 -1
- package/lib-es/logic/history/lastBlock.d.ts +2 -1
- package/lib-es/logic/history/lastBlock.d.ts.map +1 -1
- package/lib-es/logic/history/lastBlock.js +4 -3
- package/lib-es/logic/history/lastBlock.js.map +1 -1
- package/lib-es/logic/history/listOperations.d.ts +2 -1
- package/lib-es/logic/history/listOperations.d.ts.map +1 -1
- package/lib-es/logic/history/listOperations.js +5 -4
- package/lib-es/logic/history/listOperations.js.map +1 -1
- package/lib-es/logic/transaction/broadcast.d.ts +2 -1
- package/lib-es/logic/transaction/broadcast.d.ts.map +1 -1
- package/lib-es/logic/transaction/broadcast.js +3 -2
- package/lib-es/logic/transaction/broadcast.js.map +1 -1
- package/lib-es/logic/transaction/combine.d.ts +1 -1
- package/lib-es/logic/transaction/combine.d.ts.map +1 -1
- package/lib-es/logic/transaction/combine.js +4 -1
- package/lib-es/logic/transaction/combine.js.map +1 -1
- package/lib-es/logic/transaction/craftTransaction.d.ts +2 -1
- package/lib-es/logic/transaction/craftTransaction.d.ts.map +1 -1
- package/lib-es/logic/transaction/craftTransaction.js +11 -10
- package/lib-es/logic/transaction/craftTransaction.js.map +1 -1
- package/lib-es/logic/transaction/estimateFees.d.ts +2 -1
- package/lib-es/logic/transaction/estimateFees.d.ts.map +1 -1
- package/lib-es/logic/transaction/estimateFees.js +2 -2
- package/lib-es/logic/transaction/estimateFees.js.map +1 -1
- package/lib-es/network/getBlock.d.ts +2 -1
- package/lib-es/network/getBlock.d.ts.map +1 -1
- package/lib-es/network/getBlock.js +2 -2
- package/lib-es/network/getBlock.js.map +1 -1
- package/lib-es/network/getFees.d.ts +2 -1
- package/lib-es/network/getFees.d.ts.map +1 -1
- package/lib-es/network/getFees.js +2 -2
- package/lib-es/network/getFees.js.map +1 -1
- package/lib-es/network/sdk.d.ts +7 -6
- package/lib-es/network/sdk.d.ts.map +1 -1
- package/lib-es/network/sdk.js +18 -18
- package/lib-es/network/sdk.js.map +1 -1
- package/lib-es/test/context.d.ts +6 -0
- package/lib-es/test/context.d.ts.map +1 -0
- package/lib-es/test/context.js +11 -0
- package/lib-es/test/context.js.map +1 -0
- package/package.json +6 -6
- package/src/api/index.integ.test.ts +21 -24
- package/src/api/index.ts +74 -27
- package/src/api/index.unit.test.ts +68 -48
- package/src/bridge/broadcast.integ.test.ts +2 -1
- package/src/bridge/broadcast.test.ts +1 -1
- package/src/bridge/broadcast.ts +2 -1
- package/src/bridge/createTransaction.ts +2 -2
- package/src/bridge/estimateMaxSpendable.test.ts +19 -3
- package/src/bridge/estimateMaxSpendable.ts +2 -0
- package/src/bridge/getTransactionStatus.test.ts +11 -6
- package/src/bridge/getTransactionStatus.ts +2 -0
- package/src/bridge/prepareTransaction.test.ts +5 -1
- package/src/bridge/prepareTransaction.ts +4 -2
- package/src/bridge/synchronisation.ts +7 -3
- package/src/common-logic/calculateGasFees.test.ts +101 -27
- package/src/common-logic/calculateGasFees.ts +4 -2
- package/src/common-logic/calculateTransactionInfo.test.ts +71 -16
- package/src/common-logic/calculateTransactionInfo.ts +3 -1
- package/src/common-logic/estimateGas.test.ts +13 -10
- package/src/common-logic/estimateGas.ts +3 -1
- package/src/common-logic/getThorClient.test.ts +7 -7
- package/src/common-logic/getThorClient.ts +3 -3
- package/src/common-logic/mapTransfersToOperations.test.ts +48 -13
- package/src/common-logic/mapTransfersToOperations.ts +5 -2
- package/src/config.test.ts +3 -3
- package/src/config.ts +13 -6
- package/src/logic/account/getBalance.ts +4 -2
- package/src/logic/account/getBalance.unit.test.ts +6 -4
- package/src/logic/history/getBlock.ts +4 -2
- package/src/logic/history/getBlock.unit.test.ts +8 -5
- package/src/logic/history/getBlockInfo.ts +4 -2
- package/src/logic/history/getBlockInfo.unit.test.ts +6 -3
- package/src/logic/history/lastBlock.ts +5 -3
- package/src/logic/history/lastBlock.unit.test.ts +6 -3
- package/src/logic/history/listOperations.ts +6 -3
- package/src/logic/history/listOperations.unit.test.ts +10 -6
- package/src/logic/transaction/broadcast.msw.test.ts +7 -2
- package/src/logic/transaction/broadcast.ts +8 -2
- package/src/logic/transaction/broadcast.unit.test.ts +6 -3
- package/src/logic/transaction/combine.ts +6 -2
- package/src/logic/transaction/combine.unit.test.ts +3 -3
- package/src/logic/transaction/craftTransaction.ts +16 -9
- package/src/logic/transaction/craftTransaction.unit.test.ts +29 -28
- package/src/logic/transaction/estimateFees.ts +3 -0
- package/src/logic/transaction/estimateFees.unit.test.ts +15 -12
- package/src/network/getBlock.ts +3 -2
- package/src/network/getBlock.unit.test.ts +11 -6
- package/src/network/getFees.ts +6 -3
- package/src/network/sdk.integ.test.ts +8 -1
- package/src/network/sdk.test.ts +18 -7
- package/src/network/sdk.ts +25 -15
- package/src/test/context.ts +15 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getThorClient } from "./getThorClient";
|
|
2
2
|
import { ThorClient } from "@vechain/sdk-network";
|
|
3
|
-
import {
|
|
3
|
+
import type { VechainCurrencyConfig } from "../config";
|
|
4
4
|
|
|
5
5
|
// Mock the ThorClient
|
|
6
6
|
jest.mock("@vechain/sdk-network", () => ({
|
|
@@ -10,14 +10,14 @@ jest.mock("@vechain/sdk-network", () => ({
|
|
|
10
10
|
}));
|
|
11
11
|
|
|
12
12
|
const NODE_URL = "https://testnet.veblocks.net";
|
|
13
|
+
// The endpoint comes from the coin config, threaded in explicitly.
|
|
14
|
+
const config: VechainCurrencyConfig = { status: { type: "active" }, node: { url: NODE_URL } };
|
|
13
15
|
|
|
14
16
|
const mockedThorClient = jest.mocked(ThorClient);
|
|
15
17
|
|
|
16
18
|
describe("getThorClient", () => {
|
|
17
19
|
beforeEach(() => {
|
|
18
20
|
jest.clearAllMocks();
|
|
19
|
-
// The endpoint comes from the coin config, not from the environment.
|
|
20
|
-
setCoinConfig(() => ({ status: { type: "active" }, node: { url: NODE_URL } }));
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
it("should create a ThorClient instance with the configured node url", () => {
|
|
@@ -26,7 +26,7 @@ describe("getThorClient", () => {
|
|
|
26
26
|
};
|
|
27
27
|
mockedThorClient.at.mockReturnValue(mockClient as any);
|
|
28
28
|
|
|
29
|
-
const result = getThorClient();
|
|
29
|
+
const result = getThorClient(config);
|
|
30
30
|
|
|
31
31
|
expect(mockedThorClient.at).toHaveBeenCalledWith(NODE_URL);
|
|
32
32
|
expect(result).toBe(mockClient);
|
|
@@ -40,7 +40,7 @@ describe("getThorClient", () => {
|
|
|
40
40
|
};
|
|
41
41
|
mockedThorClient.at.mockReturnValue(mockClient as any);
|
|
42
42
|
|
|
43
|
-
const result = getThorClient();
|
|
43
|
+
const result = getThorClient(config);
|
|
44
44
|
|
|
45
45
|
expect(result).toEqual(mockClient);
|
|
46
46
|
});
|
|
@@ -49,7 +49,7 @@ describe("getThorClient", () => {
|
|
|
49
49
|
const mockClient = {};
|
|
50
50
|
mockedThorClient.at.mockReturnValue(mockClient as any);
|
|
51
51
|
|
|
52
|
-
getThorClient();
|
|
52
|
+
getThorClient(config);
|
|
53
53
|
|
|
54
54
|
expect(mockedThorClient.at).toHaveBeenCalledTimes(1);
|
|
55
55
|
});
|
|
@@ -58,7 +58,7 @@ describe("getThorClient", () => {
|
|
|
58
58
|
const mockClient = {};
|
|
59
59
|
mockedThorClient.at.mockReturnValue(mockClient as any);
|
|
60
60
|
|
|
61
|
-
getThorClient();
|
|
61
|
+
getThorClient(config);
|
|
62
62
|
|
|
63
63
|
expect(mockedThorClient.at).toHaveBeenCalledWith("https://testnet.veblocks.net");
|
|
64
64
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ThorClient } from "@vechain/sdk-network";
|
|
2
|
-
import { getNodeUrl } from "../config";
|
|
2
|
+
import { getNodeUrl, type VechainCurrencyConfig } from "../config";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Returns a ThorClient instance configured with the VeChain node URL
|
|
6
6
|
* @returns {ThorClient} Configured ThorClient instance for interacting with the VeChain network
|
|
7
7
|
*/
|
|
8
|
-
export const getThorClient = (): ThorClient => {
|
|
9
|
-
return ThorClient.at(getNodeUrl());
|
|
8
|
+
export const getThorClient = (config: VechainCurrencyConfig): ThorClient => {
|
|
9
|
+
return ThorClient.at(getNodeUrl(config));
|
|
10
10
|
};
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
mapTokenTransfersToOperations,
|
|
26
26
|
} from "./mapTransfersToOperations";
|
|
27
27
|
import { getFees } from "../network/getFees";
|
|
28
|
+
import { mockVechainConfig } from "../test/context";
|
|
28
29
|
|
|
29
30
|
const { ABIEvent, Hex, VIP180_ABI } = jest.requireMock("@vechain/sdk-core");
|
|
30
31
|
|
|
@@ -76,6 +77,7 @@ describe("mapVetTransfersToOperations", () => {
|
|
|
76
77
|
|
|
77
78
|
it("should map incoming VET transfers to operations", async () => {
|
|
78
79
|
const result = await mapVetTransfersToOperations(
|
|
80
|
+
mockVechainConfig,
|
|
79
81
|
[mockTransferLogs[0]],
|
|
80
82
|
mockAccountId,
|
|
81
83
|
mockAddr,
|
|
@@ -100,6 +102,7 @@ describe("mapVetTransfersToOperations", () => {
|
|
|
100
102
|
|
|
101
103
|
it("should map outgoing VET transfers to operations", async () => {
|
|
102
104
|
const result = await mapVetTransfersToOperations(
|
|
105
|
+
mockVechainConfig,
|
|
103
106
|
[mockTransferLogs[1]],
|
|
104
107
|
mockAccountId,
|
|
105
108
|
mockAddr,
|
|
@@ -123,7 +126,12 @@ describe("mapVetTransfersToOperations", () => {
|
|
|
123
126
|
});
|
|
124
127
|
|
|
125
128
|
it("should handle multiple transfers", async () => {
|
|
126
|
-
const result = await mapVetTransfersToOperations(
|
|
129
|
+
const result = await mapVetTransfersToOperations(
|
|
130
|
+
mockVechainConfig,
|
|
131
|
+
mockTransferLogs,
|
|
132
|
+
mockAccountId,
|
|
133
|
+
mockAddr,
|
|
134
|
+
);
|
|
127
135
|
|
|
128
136
|
expect(result).toHaveLength(2);
|
|
129
137
|
expect(result[0].type).toBe("IN");
|
|
@@ -131,11 +139,11 @@ describe("mapVetTransfersToOperations", () => {
|
|
|
131
139
|
});
|
|
132
140
|
|
|
133
141
|
it("should call getFees for each transfer", async () => {
|
|
134
|
-
await mapVetTransfersToOperations(mockTransferLogs, mockAccountId, mockAddr);
|
|
142
|
+
await mapVetTransfersToOperations(mockVechainConfig, mockTransferLogs, mockAccountId, mockAddr);
|
|
135
143
|
|
|
136
144
|
expect(mockedGetFees).toHaveBeenCalledTimes(2);
|
|
137
|
-
expect(mockedGetFees).toHaveBeenCalledWith("0xtx123");
|
|
138
|
-
expect(mockedGetFees).toHaveBeenCalledWith("0xtx456");
|
|
145
|
+
expect(mockedGetFees).toHaveBeenCalledWith(mockVechainConfig, "0xtx123");
|
|
146
|
+
expect(mockedGetFees).toHaveBeenCalledWith(mockVechainConfig, "0xtx456");
|
|
139
147
|
});
|
|
140
148
|
|
|
141
149
|
it("should handle case-insensitive address comparison", async () => {
|
|
@@ -146,6 +154,7 @@ describe("mapVetTransfersToOperations", () => {
|
|
|
146
154
|
};
|
|
147
155
|
|
|
148
156
|
const result = await mapVetTransfersToOperations(
|
|
157
|
+
mockVechainConfig,
|
|
149
158
|
[transferWithUpperCase],
|
|
150
159
|
mockAccountId,
|
|
151
160
|
mockAddr,
|
|
@@ -162,6 +171,7 @@ describe("mapVetTransfersToOperations", () => {
|
|
|
162
171
|
};
|
|
163
172
|
|
|
164
173
|
const result = await mapVetTransfersToOperations(
|
|
174
|
+
mockVechainConfig,
|
|
165
175
|
[transferWithMixedCase],
|
|
166
176
|
mockAccountId,
|
|
167
177
|
mockAddr,
|
|
@@ -216,7 +226,12 @@ describe("mapTokenTransfersToOperations", () => {
|
|
|
216
226
|
});
|
|
217
227
|
|
|
218
228
|
it("should map incoming token transfers to operations", async () => {
|
|
219
|
-
const result = await mapTokenTransfersToOperations(
|
|
229
|
+
const result = await mapTokenTransfersToOperations(
|
|
230
|
+
mockVechainConfig,
|
|
231
|
+
mockEventLogs,
|
|
232
|
+
mockAccountId,
|
|
233
|
+
mockAddr,
|
|
234
|
+
);
|
|
220
235
|
|
|
221
236
|
expect(result).toHaveLength(1);
|
|
222
237
|
expect(result[0]).toEqual({
|
|
@@ -246,14 +261,19 @@ describe("mapTokenTransfersToOperations", () => {
|
|
|
246
261
|
};
|
|
247
262
|
mockedABIEvent.parseLog.mockReturnValue(outgoingEvent);
|
|
248
263
|
|
|
249
|
-
const result = await mapTokenTransfersToOperations(
|
|
264
|
+
const result = await mapTokenTransfersToOperations(
|
|
265
|
+
mockVechainConfig,
|
|
266
|
+
mockEventLogs,
|
|
267
|
+
mockAccountId,
|
|
268
|
+
mockAddr,
|
|
269
|
+
);
|
|
250
270
|
|
|
251
271
|
expect(result[0].type).toBe("OUT");
|
|
252
272
|
expect(result[0].value).toEqual(new BigNumber("2000000000000000000"));
|
|
253
273
|
});
|
|
254
274
|
|
|
255
275
|
it("should decode event logs correctly", async () => {
|
|
256
|
-
await mapTokenTransfersToOperations(mockEventLogs, mockAccountId, mockAddr);
|
|
276
|
+
await mapTokenTransfersToOperations(mockVechainConfig, mockEventLogs, mockAccountId, mockAddr);
|
|
257
277
|
|
|
258
278
|
expect(mockedHex.of).toHaveBeenCalledWith(mockEventLogs[0].data);
|
|
259
279
|
expect(mockedHex.of).toHaveBeenCalledWith(mockEventLogs[0].topics[0]);
|
|
@@ -280,16 +300,21 @@ describe("mapTokenTransfersToOperations", () => {
|
|
|
280
300
|
};
|
|
281
301
|
mockedABIEvent.parseLog.mockReturnValue(largeValueEvent);
|
|
282
302
|
|
|
283
|
-
const result = await mapTokenTransfersToOperations(
|
|
303
|
+
const result = await mapTokenTransfersToOperations(
|
|
304
|
+
mockVechainConfig,
|
|
305
|
+
mockEventLogs,
|
|
306
|
+
mockAccountId,
|
|
307
|
+
mockAddr,
|
|
308
|
+
);
|
|
284
309
|
|
|
285
310
|
expect(result[0].value).toEqual(new BigNumber("123456789012345678901234567890"));
|
|
286
311
|
});
|
|
287
312
|
|
|
288
313
|
it("should call getFees for each event", async () => {
|
|
289
|
-
await mapTokenTransfersToOperations(mockEventLogs, mockAccountId, mockAddr);
|
|
314
|
+
await mapTokenTransfersToOperations(mockVechainConfig, mockEventLogs, mockAccountId, mockAddr);
|
|
290
315
|
|
|
291
316
|
expect(mockedGetFees).toHaveBeenCalledTimes(1);
|
|
292
|
-
expect(mockedGetFees).toHaveBeenCalledWith("0xtx789");
|
|
317
|
+
expect(mockedGetFees).toHaveBeenCalledWith(mockVechainConfig, "0xtx789");
|
|
293
318
|
});
|
|
294
319
|
|
|
295
320
|
it("should handle multiple events", async () => {
|
|
@@ -301,7 +326,7 @@ describe("mapTokenTransfersToOperations", () => {
|
|
|
301
326
|
},
|
|
302
327
|
];
|
|
303
328
|
|
|
304
|
-
await mapTokenTransfersToOperations(multipleEvents, mockAccountId, mockAddr);
|
|
329
|
+
await mapTokenTransfersToOperations(mockVechainConfig, multipleEvents, mockAccountId, mockAddr);
|
|
305
330
|
|
|
306
331
|
expect(mockedGetFees).toHaveBeenCalledTimes(2);
|
|
307
332
|
expect(mockedABIEvent.parseLog).toHaveBeenCalledTimes(2);
|
|
@@ -318,7 +343,12 @@ describe("mapTokenTransfersToOperations", () => {
|
|
|
318
343
|
};
|
|
319
344
|
mockedABIEvent.parseLog.mockReturnValue(upperCaseEvent);
|
|
320
345
|
|
|
321
|
-
const result = await mapTokenTransfersToOperations(
|
|
346
|
+
const result = await mapTokenTransfersToOperations(
|
|
347
|
+
mockVechainConfig,
|
|
348
|
+
mockEventLogs,
|
|
349
|
+
mockAccountId,
|
|
350
|
+
mockAddr,
|
|
351
|
+
);
|
|
322
352
|
|
|
323
353
|
expect(result[0].type).toBe("IN");
|
|
324
354
|
});
|
|
@@ -334,7 +364,12 @@ describe("mapTokenTransfersToOperations", () => {
|
|
|
334
364
|
};
|
|
335
365
|
mockedABIEvent.parseLog.mockReturnValue(mixedCaseEvent);
|
|
336
366
|
|
|
337
|
-
const result = await mapTokenTransfersToOperations(
|
|
367
|
+
const result = await mapTokenTransfersToOperations(
|
|
368
|
+
mockVechainConfig,
|
|
369
|
+
mockEventLogs,
|
|
370
|
+
mockAccountId,
|
|
371
|
+
mockAddr,
|
|
372
|
+
);
|
|
338
373
|
|
|
339
374
|
expect(result[0].senders[0]).toBe("0x5034aa590125b64023a0262112b98d72e3c8e40e");
|
|
340
375
|
expect(result[0].recipients[0]).toBe("0x742d35cc6634c0532925a3b8d0b251d8c1743ec4");
|
|
@@ -4,15 +4,17 @@ import { EventLog, TransferLog } from "../types";
|
|
|
4
4
|
import { encodeOperationId } from "@ledgerhq/ledger-wallet-framework/operation";
|
|
5
5
|
import { getFees } from "../network/getFees";
|
|
6
6
|
import { ABIEvent, Hex, VIP180_ABI } from "@vechain/sdk-core";
|
|
7
|
+
import type { VechainCurrencyConfig } from "../config";
|
|
7
8
|
|
|
8
9
|
export const mapVetTransfersToOperations = async (
|
|
10
|
+
config: VechainCurrencyConfig,
|
|
9
11
|
txs: TransferLog[],
|
|
10
12
|
accountId: string,
|
|
11
13
|
addr: string,
|
|
12
14
|
): Promise<Operation[]> => {
|
|
13
15
|
return Promise.all(
|
|
14
16
|
txs.map(async tx => {
|
|
15
|
-
const fees = await getFees(tx.meta.txID);
|
|
17
|
+
const fees = await getFees(config, tx.meta.txID);
|
|
16
18
|
return {
|
|
17
19
|
id: encodeOperationId(
|
|
18
20
|
accountId,
|
|
@@ -36,6 +38,7 @@ export const mapVetTransfersToOperations = async (
|
|
|
36
38
|
};
|
|
37
39
|
|
|
38
40
|
export const mapTokenTransfersToOperations = async (
|
|
41
|
+
config: VechainCurrencyConfig,
|
|
39
42
|
events: EventLog[],
|
|
40
43
|
accountId: string,
|
|
41
44
|
addr: string,
|
|
@@ -57,7 +60,7 @@ export const mapTokenTransfersToOperations = async (
|
|
|
57
60
|
const to = decoded.args.to;
|
|
58
61
|
const value = decoded.args.value;
|
|
59
62
|
const type = to.toLowerCase() === addr.toLowerCase() ? "IN" : "OUT";
|
|
60
|
-
const fees = await getFees(event.meta.txID);
|
|
63
|
+
const fees = await getFees(config, event.meta.txID);
|
|
61
64
|
return {
|
|
62
65
|
id: encodeOperationId(accountId, event.meta.txID, type),
|
|
63
66
|
hash: event.meta.txID,
|
package/src/config.test.ts
CHANGED
|
@@ -49,7 +49,7 @@ describe("getChainTag", () => {
|
|
|
49
49
|
chainTag: 39,
|
|
50
50
|
}));
|
|
51
51
|
|
|
52
|
-
expect(getChainTag()).toBe(39);
|
|
52
|
+
expect(getChainTag(getCoinConfig())).toBe(39);
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
it("falls back to mainnet when the currency config omits a chainTag", () => {
|
|
@@ -58,7 +58,7 @@ describe("getChainTag", () => {
|
|
|
58
58
|
node: { url: "https://vechain.coin.ledger.com" },
|
|
59
59
|
}));
|
|
60
60
|
|
|
61
|
-
expect(getChainTag()).toBe(MAINNET_CHAIN_TAG);
|
|
61
|
+
expect(getChainTag(getCoinConfig())).toBe(MAINNET_CHAIN_TAG);
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
it.each([-1, 256, 74.5, NaN])(
|
|
@@ -70,7 +70,7 @@ describe("getChainTag", () => {
|
|
|
70
70
|
chainTag: invalid,
|
|
71
71
|
}));
|
|
72
72
|
|
|
73
|
-
expect(getChainTag()).toBe(MAINNET_CHAIN_TAG);
|
|
73
|
+
expect(getChainTag(getCoinConfig())).toBe(MAINNET_CHAIN_TAG);
|
|
74
74
|
},
|
|
75
75
|
);
|
|
76
76
|
});
|
package/src/config.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CurrencyConfig, CoinConfig } from "@ledgerhq/coin-module-framework/config";
|
|
1
|
+
import { CurrencyConfig, CoinConfig, type Context } from "@ledgerhq/coin-module-framework/config";
|
|
2
2
|
import { MissingCoinConfig } from "@ledgerhq/coin-module-framework/errors";
|
|
3
3
|
import { MAINNET_CHAIN_TAG } from "./types";
|
|
4
4
|
|
|
@@ -15,6 +15,9 @@ export type VechainCurrencyConfig = CurrencyConfig & {
|
|
|
15
15
|
|
|
16
16
|
export type VechainCoinConfig = () => VechainCurrencyConfig;
|
|
17
17
|
|
|
18
|
+
/** The {@link Context} threaded through the coin-vechain API layer (ADR-019). */
|
|
19
|
+
export type VechainContext = Context<VechainCurrencyConfig>;
|
|
20
|
+
|
|
18
21
|
let coinConfig: CoinConfig<VechainCurrencyConfig> | undefined;
|
|
19
22
|
|
|
20
23
|
export function setCoinConfig(config: CoinConfig<VechainCurrencyConfig>): void {
|
|
@@ -29,9 +32,13 @@ export function getCoinConfig(): VechainCurrencyConfig {
|
|
|
29
32
|
return coinConfig();
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Thor REST endpoint. Config is threaded in explicitly by every caller: the Alpaca (`createApi`)
|
|
37
|
+
* path resolves it from `context.config()`, and the classic bridge resolves it once from the
|
|
38
|
+
* {@link getCoinConfig} singleton at its entry points and passes it down.
|
|
39
|
+
*/
|
|
40
|
+
export function getNodeUrl(config: VechainCurrencyConfig): string {
|
|
41
|
+
const { node } = config;
|
|
35
42
|
|
|
36
43
|
if (!node?.url) {
|
|
37
44
|
throw new Error("vechain: node.url is missing from the coin config");
|
|
@@ -40,8 +47,8 @@ export function getNodeUrl(): string {
|
|
|
40
47
|
return node.url;
|
|
41
48
|
}
|
|
42
49
|
|
|
43
|
-
export function getChainTag(): number {
|
|
44
|
-
const { chainTag } =
|
|
50
|
+
export function getChainTag(config: VechainCurrencyConfig): number {
|
|
51
|
+
const { chainTag } = config;
|
|
45
52
|
return typeof chainTag === "number" &&
|
|
46
53
|
Number.isInteger(chainTag) &&
|
|
47
54
|
chainTag >= 0 &&
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AssetInfo, Balance } from "@ledgerhq/coin-module-framework/api/index";
|
|
2
2
|
import { VTHO_ADDRESS } from "@vechain/sdk-core";
|
|
3
|
+
import type { VechainContext } from "../../config";
|
|
3
4
|
import { getAccount } from "../../network";
|
|
4
5
|
|
|
5
6
|
export const NATIVE_ASSET: AssetInfo = { type: "native", name: "VET" };
|
|
@@ -14,8 +15,9 @@ export const vthoAsset = (address: string): AssetInfo => ({
|
|
|
14
15
|
});
|
|
15
16
|
|
|
16
17
|
// VET + VTHO balances from Thor's /accounts/{address} (both returned in one call); 0 if absent.
|
|
17
|
-
export async function getBalance(address: string): Promise<Balance[]> {
|
|
18
|
-
const
|
|
18
|
+
export async function getBalance(context: VechainContext, address: string): Promise<Balance[]> {
|
|
19
|
+
const config = await context.config();
|
|
20
|
+
const { balance, energy } = await getAccount(config, address);
|
|
19
21
|
|
|
20
22
|
return [
|
|
21
23
|
{ value: BigInt(balance || "0"), asset: NATIVE_ASSET },
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { getAccount } from "../../network";
|
|
2
|
+
import { createMockVechainContext, mockVechainConfig } from "../../test/context";
|
|
2
3
|
import { getBalance, NATIVE_ASSET, vthoAsset } from "./getBalance";
|
|
3
4
|
|
|
4
5
|
jest.mock("../../network", () => ({ getAccount: jest.fn() }));
|
|
5
6
|
|
|
6
7
|
const ADDRESS = "0x0fe6688548f0C303932bB197B0A96034f1d74dba";
|
|
8
|
+
const context = createMockVechainContext();
|
|
7
9
|
|
|
8
10
|
describe("getBalance", () => {
|
|
9
11
|
afterEach(() => {
|
|
@@ -17,9 +19,9 @@ describe("getBalance", () => {
|
|
|
17
19
|
hasCode: false,
|
|
18
20
|
});
|
|
19
21
|
|
|
20
|
-
const balances = await getBalance(ADDRESS);
|
|
22
|
+
const balances = await getBalance(context, ADDRESS);
|
|
21
23
|
|
|
22
|
-
expect(getAccount).toHaveBeenCalledWith(ADDRESS);
|
|
24
|
+
expect(getAccount).toHaveBeenCalledWith(mockVechainConfig, ADDRESS);
|
|
23
25
|
expect(balances).toEqual([
|
|
24
26
|
{ value: BigInt("0x1bc16d674ec80000"), asset: NATIVE_ASSET },
|
|
25
27
|
{ value: BigInt("0xde0b6b3a7640000"), asset: vthoAsset(ADDRESS) },
|
|
@@ -29,7 +31,7 @@ describe("getBalance", () => {
|
|
|
29
31
|
it("defaults both balances to 0 for a pristine account", async () => {
|
|
30
32
|
jest.mocked(getAccount).mockResolvedValueOnce({ balance: "", energy: "", hasCode: false });
|
|
31
33
|
|
|
32
|
-
const balances = await getBalance(ADDRESS);
|
|
34
|
+
const balances = await getBalance(context, ADDRESS);
|
|
33
35
|
|
|
34
36
|
expect(balances).toEqual([
|
|
35
37
|
{ value: 0n, asset: NATIVE_ASSET },
|
|
@@ -42,7 +44,7 @@ describe("getBalance", () => {
|
|
|
42
44
|
.mocked(getAccount)
|
|
43
45
|
.mockResolvedValueOnce({ balance: "0x1", energy: "0x2", hasCode: false });
|
|
44
46
|
|
|
45
|
-
const [nativeBalance, tokenBalance] = await getBalance(ADDRESS);
|
|
47
|
+
const [nativeBalance, tokenBalance] = await getBalance(context, ADDRESS);
|
|
46
48
|
|
|
47
49
|
expect(nativeBalance.asset.type).toBe("native");
|
|
48
50
|
expect(tokenBalance.asset.type).not.toBe("native");
|
|
@@ -3,14 +3,16 @@ import type {
|
|
|
3
3
|
BlockOperation,
|
|
4
4
|
BlockTransaction,
|
|
5
5
|
} from "@ledgerhq/coin-module-framework/api/index";
|
|
6
|
+
import type { VechainContext } from "../../config";
|
|
6
7
|
import { getBlock as getBlockFromNetwork } from "../../network";
|
|
7
8
|
import type { ApiResponseBlockTransaction } from "../../types";
|
|
8
9
|
import { toBlockInfo } from "./getBlockInfo";
|
|
9
10
|
|
|
10
11
|
// Full expanded block; block info is derived from it (no separate fetch). Only native VET transfers
|
|
11
12
|
// map to operations; VTHO (VIP-180) movements are ABI-encoded events, not decoded here.
|
|
12
|
-
export async function getBlock(height: number): Promise<Block> {
|
|
13
|
-
const
|
|
13
|
+
export async function getBlock(context: VechainContext, height: number): Promise<Block> {
|
|
14
|
+
const config = await context.config();
|
|
15
|
+
const block = await getBlockFromNetwork(config, height, true);
|
|
14
16
|
|
|
15
17
|
if (!block) {
|
|
16
18
|
throw new Error(`vechain: no block at height ${height}`);
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { getBlock as getBlockFromNetwork } from "../../network";
|
|
2
|
+
import { createMockVechainContext, mockVechainConfig } from "../../test/context";
|
|
2
3
|
import { getBlock } from "./getBlock";
|
|
3
4
|
|
|
4
5
|
jest.mock("../../network", () => ({ getBlock: jest.fn() }));
|
|
5
6
|
|
|
7
|
+
const context = createMockVechainContext();
|
|
8
|
+
|
|
6
9
|
describe("getBlock", () => {
|
|
7
10
|
afterEach(() => {
|
|
8
11
|
jest.clearAllMocks();
|
|
@@ -31,10 +34,10 @@ describe("getBlock", () => {
|
|
|
31
34
|
],
|
|
32
35
|
});
|
|
33
36
|
|
|
34
|
-
const block = await getBlock(10);
|
|
37
|
+
const block = await getBlock(context, 10);
|
|
35
38
|
|
|
36
39
|
expect(getBlockFromNetwork).toHaveBeenCalledTimes(1);
|
|
37
|
-
expect(getBlockFromNetwork).toHaveBeenCalledWith(10, true);
|
|
40
|
+
expect(getBlockFromNetwork).toHaveBeenCalledWith(mockVechainConfig, 10, true);
|
|
38
41
|
expect(block.info).toEqual({
|
|
39
42
|
height: 10,
|
|
40
43
|
hash: "0xabc",
|
|
@@ -69,7 +72,7 @@ describe("getBlock", () => {
|
|
|
69
72
|
],
|
|
70
73
|
});
|
|
71
74
|
|
|
72
|
-
const block = await getBlock(10);
|
|
75
|
+
const block = await getBlock(context, 10);
|
|
73
76
|
|
|
74
77
|
expect(block.transactions[0].failed).toBe(true);
|
|
75
78
|
expect(block.transactions[0].operations).toEqual([]);
|
|
@@ -78,7 +81,7 @@ describe("getBlock", () => {
|
|
|
78
81
|
it("throws when there is no block at the given height", async () => {
|
|
79
82
|
jest.mocked(getBlockFromNetwork).mockResolvedValueOnce(null);
|
|
80
83
|
|
|
81
|
-
await expect(getBlock(1)).rejects.toThrow("vechain: no block at height 1");
|
|
84
|
+
await expect(getBlock(context, 1)).rejects.toThrow("vechain: no block at height 1");
|
|
82
85
|
});
|
|
83
86
|
|
|
84
87
|
it("uses the VIP-191 gasPayer as feesPayer when a tx is fee-delegated", async () => {
|
|
@@ -99,7 +102,7 @@ describe("getBlock", () => {
|
|
|
99
102
|
],
|
|
100
103
|
});
|
|
101
104
|
|
|
102
|
-
const block = await getBlock(10);
|
|
105
|
+
const block = await getBlock(context, 10);
|
|
103
106
|
|
|
104
107
|
expect(block.transactions[0].feesPayer).toBe("0xdelegate");
|
|
105
108
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BlockInfo } from "@ledgerhq/coin-module-framework/api/index";
|
|
2
|
+
import type { VechainContext } from "../../config";
|
|
2
3
|
import { getBlock as getBlockFromNetwork } from "../../network";
|
|
3
4
|
import type { ApiResponseBlock } from "../../types";
|
|
4
5
|
|
|
@@ -13,8 +14,9 @@ export function toBlockInfo(block: ApiResponseBlock): BlockInfo {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
/** Block metadata (height/hash/time) at a given block height, via Thor `GET /blocks/{height}`. */
|
|
16
|
-
export async function getBlockInfo(height: number): Promise<BlockInfo> {
|
|
17
|
-
const
|
|
17
|
+
export async function getBlockInfo(context: VechainContext, height: number): Promise<BlockInfo> {
|
|
18
|
+
const config = await context.config();
|
|
19
|
+
const block = await getBlockFromNetwork(config, height, false);
|
|
18
20
|
|
|
19
21
|
if (!block) {
|
|
20
22
|
throw new Error(`vechain: no block at height ${height}`);
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { getBlock as getBlockFromNetwork } from "../../network";
|
|
2
|
+
import { createMockVechainContext, mockVechainConfig } from "../../test/context";
|
|
2
3
|
import { getBlockInfo } from "./getBlockInfo";
|
|
3
4
|
|
|
4
5
|
jest.mock("../../network", () => ({ getBlock: jest.fn() }));
|
|
5
6
|
|
|
7
|
+
const context = createMockVechainContext();
|
|
8
|
+
|
|
6
9
|
describe("getBlockInfo", () => {
|
|
7
10
|
afterEach(() => {
|
|
8
11
|
jest.clearAllMocks();
|
|
@@ -16,15 +19,15 @@ describe("getBlockInfo", () => {
|
|
|
16
19
|
transactions: [],
|
|
17
20
|
});
|
|
18
21
|
|
|
19
|
-
const info = await getBlockInfo(42);
|
|
22
|
+
const info = await getBlockInfo(context, 42);
|
|
20
23
|
|
|
21
|
-
expect(getBlockFromNetwork).toHaveBeenCalledWith(42);
|
|
24
|
+
expect(getBlockFromNetwork).toHaveBeenCalledWith(mockVechainConfig, 42, false);
|
|
22
25
|
expect(info).toEqual({ height: 42, hash: "0xabc", time: new Date(1_700_000_000 * 1000) });
|
|
23
26
|
});
|
|
24
27
|
|
|
25
28
|
it("throws when there is no block at the given height", async () => {
|
|
26
29
|
jest.mocked(getBlockFromNetwork).mockResolvedValueOnce(null);
|
|
27
30
|
|
|
28
|
-
await expect(getBlockInfo(999)).rejects.toThrow("vechain: no block at height 999");
|
|
31
|
+
await expect(getBlockInfo(context, 999)).rejects.toThrow("vechain: no block at height 999");
|
|
29
32
|
});
|
|
30
33
|
});
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { BlockInfo } from "@ledgerhq/coin-module-framework/api/index";
|
|
2
|
+
import type { VechainContext } from "../../config";
|
|
2
3
|
import { getLastBlockHeight } from "../../network";
|
|
3
4
|
import { getBlockInfo } from "./getBlockInfo";
|
|
4
5
|
|
|
5
6
|
// Latest block; /blocks/best exposes only the height, so hash/time come from getBlockInfo.
|
|
6
|
-
export async function lastBlock(): Promise<BlockInfo> {
|
|
7
|
-
const
|
|
8
|
-
|
|
7
|
+
export async function lastBlock(context: VechainContext): Promise<BlockInfo> {
|
|
8
|
+
const config = await context.config();
|
|
9
|
+
const height = await getLastBlockHeight(config);
|
|
10
|
+
return getBlockInfo(context, height);
|
|
9
11
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { getLastBlockHeight } from "../../network";
|
|
2
|
+
import { createMockVechainContext } from "../../test/context";
|
|
2
3
|
import { getBlockInfo } from "./getBlockInfo";
|
|
3
4
|
import { lastBlock } from "./lastBlock";
|
|
4
5
|
|
|
5
6
|
jest.mock("../../network", () => ({ getLastBlockHeight: jest.fn() }));
|
|
6
7
|
jest.mock("./getBlockInfo", () => ({ getBlockInfo: jest.fn() }));
|
|
7
8
|
|
|
9
|
+
const context = createMockVechainContext();
|
|
10
|
+
|
|
8
11
|
describe("lastBlock", () => {
|
|
9
12
|
afterEach(() => {
|
|
10
13
|
jest.clearAllMocks();
|
|
@@ -15,16 +18,16 @@ describe("lastBlock", () => {
|
|
|
15
18
|
const info = { height: 123, hash: "0xabc", time: new Date() };
|
|
16
19
|
jest.mocked(getBlockInfo).mockResolvedValueOnce(info);
|
|
17
20
|
|
|
18
|
-
const result = await lastBlock();
|
|
21
|
+
const result = await lastBlock(context);
|
|
19
22
|
|
|
20
|
-
expect(getBlockInfo).toHaveBeenCalledWith(123);
|
|
23
|
+
expect(getBlockInfo).toHaveBeenCalledWith(context, 123);
|
|
21
24
|
expect(result).toBe(info);
|
|
22
25
|
});
|
|
23
26
|
|
|
24
27
|
it("propagates an error from the height lookup", async () => {
|
|
25
28
|
jest.mocked(getLastBlockHeight).mockRejectedValueOnce(new Error("network down"));
|
|
26
29
|
|
|
27
|
-
await expect(lastBlock()).rejects.toThrow("network down");
|
|
30
|
+
await expect(lastBlock(context)).rejects.toThrow("network down");
|
|
28
31
|
expect(getBlockInfo).not.toHaveBeenCalled();
|
|
29
32
|
});
|
|
30
33
|
});
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
} from "@ledgerhq/coin-module-framework/api/index";
|
|
8
8
|
import type { Operation as LegacyOperation } from "@ledgerhq/types-live";
|
|
9
9
|
import { VTHO_ADDRESS } from "@vechain/sdk-core";
|
|
10
|
+
import type { VechainContext } from "../../config";
|
|
10
11
|
import { getLastBlockHeight, getOperations, getTokenOperations } from "../../network";
|
|
11
12
|
import { NATIVE_ASSET, vthoAsset } from "../account/getBalance";
|
|
12
13
|
|
|
@@ -37,19 +38,21 @@ function parseCursor(options: ListOperationsOptions): number {
|
|
|
37
38
|
|
|
38
39
|
// Merged VET + VTHO operations; `next` is one block past the current head for incremental resume.
|
|
39
40
|
export async function listOperations(
|
|
41
|
+
context: VechainContext,
|
|
40
42
|
address: string,
|
|
41
43
|
options: ListOperationsOptions,
|
|
42
44
|
): Promise<Page<Operation<MemoNotSupported>>> {
|
|
45
|
+
const config = await context.config();
|
|
43
46
|
const startAt = parseCursor(options);
|
|
44
|
-
const stopAt = await getLastBlockHeight();
|
|
47
|
+
const stopAt = await getLastBlockHeight(config);
|
|
45
48
|
|
|
46
49
|
if (startAt > stopAt) {
|
|
47
50
|
return { items: [], next: String(startAt) };
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
const [vetOps, vthoOps] = await Promise.all([
|
|
51
|
-
getOperations(address, address, startAt, stopAt),
|
|
52
|
-
getTokenOperations(address, address, VTHO_ADDRESS, startAt, stopAt),
|
|
54
|
+
getOperations(config, address, address, startAt, stopAt),
|
|
55
|
+
getTokenOperations(config, address, address, VTHO_ADDRESS, startAt, stopAt),
|
|
53
56
|
]);
|
|
54
57
|
|
|
55
58
|
const items = [
|