@ledgerhq/coin-casper 1.7.3 → 2.0.0-next.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/.turbo/turbo-build.log +1 -1
- package/.unimportedrc.json +11 -35
- package/CHANGELOG.md +14 -0
- package/jest.config.js +2 -5
- package/lib/api/index.d.ts +8 -6
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.integ.test.js +12 -3
- package/lib/api/index.integ.test.js.map +1 -1
- package/lib/api/index.js +53 -91
- package/lib/api/index.js.map +1 -1
- package/lib/api/index.test.d.ts +2 -0
- package/lib/api/index.test.d.ts.map +1 -0
- package/lib/api/index.test.js +274 -0
- package/lib/api/index.test.js.map +1 -0
- package/lib/api/types.d.ts +2 -67
- package/lib/api/types.d.ts.map +1 -1
- package/lib/bridge/bridgeHelpers/accountShape.d.ts.map +1 -1
- package/lib/bridge/bridgeHelpers/accountShape.js +5 -7
- package/lib/bridge/bridgeHelpers/accountShape.js.map +1 -1
- package/lib/bridge/bridgeHelpers/accountShape.test.d.ts +2 -0
- package/lib/bridge/bridgeHelpers/accountShape.test.d.ts.map +1 -0
- package/lib/bridge/bridgeHelpers/accountShape.test.js +94 -0
- package/lib/bridge/bridgeHelpers/accountShape.test.js.map +1 -0
- package/lib/bridge/bridgeHelpers/addresses.d.ts +3 -9
- package/lib/bridge/bridgeHelpers/addresses.d.ts.map +1 -1
- package/lib/bridge/bridgeHelpers/addresses.js +5 -62
- package/lib/bridge/bridgeHelpers/addresses.js.map +1 -1
- package/lib/bridge/bridgeHelpers/txn.d.ts +2 -2
- package/lib/bridge/bridgeHelpers/txn.d.ts.map +1 -1
- package/lib/bridge/bridgeHelpers/txn.js +9 -11
- package/lib/bridge/bridgeHelpers/txn.js.map +1 -1
- package/lib/bridge/bridgeHelpers/txn.test.d.ts +2 -0
- package/lib/bridge/bridgeHelpers/txn.test.d.ts.map +1 -0
- package/lib/bridge/bridgeHelpers/txn.test.js +306 -0
- package/lib/bridge/bridgeHelpers/txn.test.js.map +1 -0
- package/lib/bridge/broadcast.d.ts.map +1 -1
- package/lib/bridge/broadcast.js +7 -6
- package/lib/bridge/broadcast.js.map +1 -1
- package/lib/bridge/broadcast.test.d.ts +2 -0
- package/lib/bridge/broadcast.test.d.ts.map +1 -0
- package/lib/bridge/broadcast.test.js +72 -0
- package/lib/bridge/broadcast.test.js.map +1 -0
- package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib/bridge/buildOptimisticOperation.js +2 -0
- package/lib/bridge/buildOptimisticOperation.js.map +1 -1
- package/lib/bridge/buildOptimisticOperation.test.d.ts +2 -0
- package/lib/bridge/buildOptimisticOperation.test.d.ts.map +1 -0
- package/lib/bridge/buildOptimisticOperation.test.js +76 -0
- package/lib/bridge/buildOptimisticOperation.test.js.map +1 -0
- package/lib/bridge/createTransaction.test.d.ts +2 -0
- package/lib/bridge/createTransaction.test.d.ts.map +1 -0
- package/lib/bridge/createTransaction.test.js +41 -0
- package/lib/bridge/createTransaction.test.js.map +1 -0
- package/lib/bridge/deviceTransactionConfig.d.ts.map +1 -1
- package/lib/bridge/deviceTransactionConfig.js +13 -0
- package/lib/bridge/deviceTransactionConfig.js.map +1 -1
- package/lib/bridge/deviceTransactionConfig.test.d.ts +2 -0
- package/lib/bridge/deviceTransactionConfig.test.d.ts.map +1 -0
- package/lib/bridge/deviceTransactionConfig.test.js +148 -0
- package/lib/bridge/deviceTransactionConfig.test.js.map +1 -0
- package/lib/bridge/estimateMaxSpendable.test.d.ts +2 -0
- package/lib/bridge/estimateMaxSpendable.test.d.ts.map +1 -0
- package/lib/bridge/estimateMaxSpendable.test.js +133 -0
- package/lib/bridge/estimateMaxSpendable.test.js.map +1 -0
- package/lib/bridge/getTransactionStatus.test.d.ts +2 -0
- package/lib/bridge/getTransactionStatus.test.d.ts.map +1 -0
- package/lib/bridge/getTransactionStatus.test.js +214 -0
- package/lib/bridge/getTransactionStatus.test.js.map +1 -0
- package/lib/bridge/index.d.ts +2 -1
- package/lib/bridge/index.d.ts.map +1 -1
- package/lib/bridge/index.js +3 -1
- package/lib/bridge/index.js.map +1 -1
- package/lib/bridge/prepareTransaction.js +1 -1
- package/lib/bridge/prepareTransaction.js.map +1 -1
- package/lib/bridge/prepareTransaction.test.d.ts +2 -0
- package/lib/bridge/prepareTransaction.test.d.ts.map +1 -0
- package/lib/bridge/prepareTransaction.test.js +159 -0
- package/lib/bridge/prepareTransaction.test.js.map +1 -0
- package/lib/bridge/signOperation.d.ts.map +1 -1
- package/lib/bridge/signOperation.js +14 -12
- package/lib/bridge/signOperation.js.map +1 -1
- package/lib/bridge/transaction.test.d.ts +2 -0
- package/lib/bridge/transaction.test.d.ts.map +1 -0
- package/lib/bridge/transaction.test.js +179 -0
- package/lib/bridge/transaction.test.js.map +1 -0
- package/lib/common-logic/utils.additional.test.d.ts +2 -0
- package/lib/common-logic/utils.additional.test.d.ts.map +1 -0
- package/lib/common-logic/utils.additional.test.js +58 -0
- package/lib/common-logic/utils.additional.test.js.map +1 -0
- package/lib/common-logic/utils.unit.test.js +6 -4
- package/lib/common-logic/utils.unit.test.js.map +1 -1
- package/lib/config.d.ts +10 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +16 -0
- package/lib/config.js.map +1 -0
- package/lib/consts.d.ts +3 -0
- package/lib/consts.d.ts.map +1 -1
- package/lib/consts.js +5 -1
- package/lib/consts.js.map +1 -1
- package/lib/hw-signMessage.test.d.ts +2 -0
- package/lib/hw-signMessage.test.d.ts.map +1 -0
- package/lib/hw-signMessage.test.js +80 -0
- package/lib/hw-signMessage.test.js.map +1 -0
- package/lib/signer/getAddress.js +1 -1
- package/lib/signer/getAddress.js.map +1 -1
- package/lib/signer/getAddress.test.d.ts +2 -0
- package/lib/signer/getAddress.test.d.ts.map +1 -0
- package/lib/signer/getAddress.test.js +133 -0
- package/lib/signer/getAddress.test.js.map +1 -0
- package/lib/test/bot-specs.d.ts.map +1 -1
- package/lib/test/bot-specs.js +1 -0
- package/lib/test/bot-specs.js.map +1 -1
- package/lib/test/fixtures.d.ts +131 -0
- package/lib/test/fixtures.d.ts.map +1 -0
- package/lib/test/fixtures.js +395 -0
- package/lib/test/fixtures.js.map +1 -0
- package/lib/test/index.d.ts +2 -0
- package/lib/test/index.d.ts.map +1 -1
- package/lib/test/index.js +2 -0
- package/lib/test/index.js.map +1 -1
- package/lib/test/speculos-deviceActions.d.ts.map +1 -1
- package/lib/test/speculos-deviceActions.js +4 -3
- package/lib/test/speculos-deviceActions.js.map +1 -1
- package/lib-es/api/index.d.ts +8 -6
- package/lib-es/api/index.d.ts.map +1 -1
- package/lib-es/api/index.integ.test.js +13 -4
- package/lib-es/api/index.integ.test.js.map +1 -1
- package/lib-es/api/index.js +51 -90
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/api/index.test.d.ts +2 -0
- package/lib-es/api/index.test.d.ts.map +1 -0
- package/lib-es/api/index.test.js +269 -0
- package/lib-es/api/index.test.js.map +1 -0
- package/lib-es/api/types.d.ts +2 -67
- package/lib-es/api/types.d.ts.map +1 -1
- package/lib-es/bridge/bridgeHelpers/accountShape.d.ts.map +1 -1
- package/lib-es/bridge/bridgeHelpers/accountShape.js +6 -8
- package/lib-es/bridge/bridgeHelpers/accountShape.js.map +1 -1
- package/lib-es/bridge/bridgeHelpers/accountShape.test.d.ts +2 -0
- package/lib-es/bridge/bridgeHelpers/accountShape.test.d.ts.map +1 -0
- package/lib-es/bridge/bridgeHelpers/accountShape.test.js +89 -0
- package/lib-es/bridge/bridgeHelpers/accountShape.test.js.map +1 -0
- package/lib-es/bridge/bridgeHelpers/addresses.d.ts +3 -9
- package/lib-es/bridge/bridgeHelpers/addresses.d.ts.map +1 -1
- package/lib-es/bridge/bridgeHelpers/addresses.js +5 -60
- package/lib-es/bridge/bridgeHelpers/addresses.js.map +1 -1
- package/lib-es/bridge/bridgeHelpers/txn.d.ts +2 -2
- package/lib-es/bridge/bridgeHelpers/txn.d.ts.map +1 -1
- package/lib-es/bridge/bridgeHelpers/txn.js +10 -12
- package/lib-es/bridge/bridgeHelpers/txn.js.map +1 -1
- package/lib-es/bridge/bridgeHelpers/txn.test.d.ts +2 -0
- package/lib-es/bridge/bridgeHelpers/txn.test.d.ts.map +1 -0
- package/lib-es/bridge/bridgeHelpers/txn.test.js +278 -0
- package/lib-es/bridge/bridgeHelpers/txn.test.js.map +1 -0
- package/lib-es/bridge/broadcast.d.ts.map +1 -1
- package/lib-es/bridge/broadcast.js +8 -7
- package/lib-es/bridge/broadcast.js.map +1 -1
- package/lib-es/bridge/broadcast.test.d.ts +2 -0
- package/lib-es/bridge/broadcast.test.d.ts.map +1 -0
- package/lib-es/bridge/broadcast.test.js +70 -0
- package/lib-es/bridge/broadcast.test.js.map +1 -0
- package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib-es/bridge/buildOptimisticOperation.js +2 -0
- package/lib-es/bridge/buildOptimisticOperation.js.map +1 -1
- package/lib-es/bridge/buildOptimisticOperation.test.d.ts +2 -0
- package/lib-es/bridge/buildOptimisticOperation.test.d.ts.map +1 -0
- package/lib-es/bridge/buildOptimisticOperation.test.js +74 -0
- package/lib-es/bridge/buildOptimisticOperation.test.js.map +1 -0
- package/lib-es/bridge/createTransaction.test.d.ts +2 -0
- package/lib-es/bridge/createTransaction.test.d.ts.map +1 -0
- package/lib-es/bridge/createTransaction.test.js +36 -0
- package/lib-es/bridge/createTransaction.test.js.map +1 -0
- package/lib-es/bridge/deviceTransactionConfig.d.ts.map +1 -1
- package/lib-es/bridge/deviceTransactionConfig.js +13 -0
- package/lib-es/bridge/deviceTransactionConfig.js.map +1 -1
- package/lib-es/bridge/deviceTransactionConfig.test.d.ts +2 -0
- package/lib-es/bridge/deviceTransactionConfig.test.d.ts.map +1 -0
- package/lib-es/bridge/deviceTransactionConfig.test.js +143 -0
- package/lib-es/bridge/deviceTransactionConfig.test.js.map +1 -0
- package/lib-es/bridge/estimateMaxSpendable.test.d.ts +2 -0
- package/lib-es/bridge/estimateMaxSpendable.test.d.ts.map +1 -0
- package/lib-es/bridge/estimateMaxSpendable.test.js +131 -0
- package/lib-es/bridge/estimateMaxSpendable.test.js.map +1 -0
- package/lib-es/bridge/getTransactionStatus.test.d.ts +2 -0
- package/lib-es/bridge/getTransactionStatus.test.d.ts.map +1 -0
- package/lib-es/bridge/getTransactionStatus.test.js +212 -0
- package/lib-es/bridge/getTransactionStatus.test.js.map +1 -0
- package/lib-es/bridge/index.d.ts +2 -1
- package/lib-es/bridge/index.d.ts.map +1 -1
- package/lib-es/bridge/index.js +3 -1
- package/lib-es/bridge/index.js.map +1 -1
- package/lib-es/bridge/prepareTransaction.js +1 -1
- package/lib-es/bridge/prepareTransaction.js.map +1 -1
- package/lib-es/bridge/prepareTransaction.test.d.ts +2 -0
- package/lib-es/bridge/prepareTransaction.test.d.ts.map +1 -0
- package/lib-es/bridge/prepareTransaction.test.js +157 -0
- package/lib-es/bridge/prepareTransaction.test.js.map +1 -0
- package/lib-es/bridge/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/signOperation.js +16 -14
- package/lib-es/bridge/signOperation.js.map +1 -1
- package/lib-es/bridge/transaction.test.d.ts +2 -0
- package/lib-es/bridge/transaction.test.d.ts.map +1 -0
- package/lib-es/bridge/transaction.test.js +154 -0
- package/lib-es/bridge/transaction.test.js.map +1 -0
- package/lib-es/common-logic/utils.additional.test.d.ts +2 -0
- package/lib-es/common-logic/utils.additional.test.d.ts.map +1 -0
- package/lib-es/common-logic/utils.additional.test.js +56 -0
- package/lib-es/common-logic/utils.additional.test.js.map +1 -0
- package/lib-es/common-logic/utils.unit.test.js +7 -5
- package/lib-es/common-logic/utils.unit.test.js.map +1 -1
- package/lib-es/config.d.ts +10 -0
- package/lib-es/config.d.ts.map +1 -0
- package/lib-es/config.js +11 -0
- package/lib-es/config.js.map +1 -0
- package/lib-es/consts.d.ts +3 -0
- package/lib-es/consts.d.ts.map +1 -1
- package/lib-es/consts.js +4 -0
- package/lib-es/consts.js.map +1 -1
- package/lib-es/hw-signMessage.test.d.ts +2 -0
- package/lib-es/hw-signMessage.test.d.ts.map +1 -0
- package/lib-es/hw-signMessage.test.js +78 -0
- package/lib-es/hw-signMessage.test.js.map +1 -0
- package/lib-es/signer/getAddress.js +2 -2
- package/lib-es/signer/getAddress.js.map +1 -1
- package/lib-es/signer/getAddress.test.d.ts +2 -0
- package/lib-es/signer/getAddress.test.d.ts.map +1 -0
- package/lib-es/signer/getAddress.test.js +105 -0
- package/lib-es/signer/getAddress.test.js.map +1 -0
- package/lib-es/test/bot-specs.d.ts.map +1 -1
- package/lib-es/test/bot-specs.js +1 -0
- package/lib-es/test/bot-specs.js.map +1 -1
- package/lib-es/test/fixtures.d.ts +131 -0
- package/lib-es/test/fixtures.d.ts.map +1 -0
- package/lib-es/test/fixtures.js +381 -0
- package/lib-es/test/fixtures.js.map +1 -0
- package/lib-es/test/index.d.ts +2 -0
- package/lib-es/test/index.d.ts.map +1 -1
- package/lib-es/test/index.js +2 -0
- package/lib-es/test/index.js.map +1 -1
- package/lib-es/test/speculos-deviceActions.d.ts.map +1 -1
- package/lib-es/test/speculos-deviceActions.js +5 -4
- package/lib-es/test/speculos-deviceActions.js.map +1 -1
- package/package.json +17 -12
- package/src/api/index.integ.test.ts +14 -4
- package/src/api/index.test.ts +386 -0
- package/src/api/index.ts +59 -117
- package/src/api/types.ts +2 -75
- package/src/bridge/bridgeHelpers/accountShape.test.ts +122 -0
- package/src/bridge/bridgeHelpers/accountShape.ts +7 -9
- package/src/bridge/bridgeHelpers/addresses.ts +6 -73
- package/src/bridge/bridgeHelpers/txn.test.ts +339 -0
- package/src/bridge/bridgeHelpers/txn.ts +18 -18
- package/src/bridge/broadcast.test.ts +89 -0
- package/src/bridge/broadcast.ts +9 -7
- package/src/bridge/buildOptimisticOperation.test.ts +89 -0
- package/src/bridge/buildOptimisticOperation.ts +2 -0
- package/src/bridge/createTransaction.test.ts +43 -0
- package/src/bridge/deviceTransactionConfig.test.ts +171 -0
- package/src/bridge/deviceTransactionConfig.ts +14 -0
- package/src/bridge/estimateMaxSpendable.test.ts +155 -0
- package/src/bridge/getTransactionStatus.test.ts +264 -0
- package/src/bridge/index.ts +8 -1
- package/src/bridge/prepareTransaction.test.ts +174 -0
- package/src/bridge/prepareTransaction.ts +1 -1
- package/src/bridge/signOperation.ts +16 -25
- package/src/bridge/transaction.test.ts +182 -0
- package/src/common-logic/utils.additional.test.ts +75 -0
- package/src/common-logic/utils.unit.test.ts +9 -7
- package/src/config.ts +22 -0
- package/src/consts.ts +5 -0
- package/src/hw-signMessage.test.ts +123 -0
- package/src/signer/getAddress.test.ts +134 -0
- package/src/signer/getAddress.ts +2 -2
- package/src/test/bot-specs.ts +1 -0
- package/src/test/fixtures.ts +448 -0
- package/src/test/index.ts +2 -0
- package/src/test/speculos-deviceActions.ts +6 -4
- package/tsconfig.json +1 -4
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
import { getUnit, mapTxToOps } from "./txn";
|
|
3
|
+
import { casperAccountHashFromPublicKey, isAddressValid } from "./addresses";
|
|
4
|
+
import * as fixtures from "../../test/fixtures";
|
|
5
|
+
import { ITxnHistoryData } from "../../api/types";
|
|
6
|
+
import { createNewTransaction as testCreateNewTransaction } from "./txn";
|
|
7
|
+
|
|
8
|
+
// Import Casper SDK mock for direct access to mocks
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
10
|
+
const mockCasperSDK = require("casper-js-sdk");
|
|
11
|
+
|
|
12
|
+
// Mock the entire Casper SDK
|
|
13
|
+
jest.mock("casper-js-sdk", () => {
|
|
14
|
+
const mockTransaction = { id: "mock-transaction" };
|
|
15
|
+
const mockHelper = {
|
|
16
|
+
createTransferTransaction: jest.fn().mockReturnValue(mockTransaction),
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
CasperNetwork: {
|
|
21
|
+
create: jest.fn().mockResolvedValue(mockHelper),
|
|
22
|
+
},
|
|
23
|
+
PublicKey: {
|
|
24
|
+
fromHex: jest.fn().mockReturnValue({ value: "mocked-public-key" }),
|
|
25
|
+
},
|
|
26
|
+
Transaction: jest.fn().mockImplementation(() => mockTransaction),
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
jest.mock("@ledgerhq/coin-framework/operation", () => ({
|
|
31
|
+
encodeOperationId: jest.fn(
|
|
32
|
+
(accountId: string, hash: string, type: string) => `${accountId}-${hash}-${type}`,
|
|
33
|
+
),
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
jest.mock("./addresses", () => ({
|
|
37
|
+
casperAccountHashFromPublicKey: jest.fn((key: string) => `account-hash-${key}`),
|
|
38
|
+
isAddressValid: jest.fn(),
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
jest.mock("../../api", () => ({
|
|
42
|
+
getCasperNodeRpcClient: jest.fn(),
|
|
43
|
+
}));
|
|
44
|
+
|
|
45
|
+
describe("txn", () => {
|
|
46
|
+
// Reset mocks between tests
|
|
47
|
+
beforeEach(() => {
|
|
48
|
+
jest.clearAllMocks();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe("getUnit", () => {
|
|
52
|
+
test("should return the first unit of casper currency", () => {
|
|
53
|
+
const unit = getUnit();
|
|
54
|
+
expect(unit).toBeDefined();
|
|
55
|
+
expect(unit.name).toBe("CSPR");
|
|
56
|
+
expect(unit.code).toBe("CSPR");
|
|
57
|
+
expect(unit.magnitude).toBe(9);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("mapTxToOps", () => {
|
|
62
|
+
const { mockAccountId } = fixtures.createMockAccountShapeData();
|
|
63
|
+
const fees = new BigNumber("100000000");
|
|
64
|
+
const mockTimestamp = "2023-01-01T12:00:00Z";
|
|
65
|
+
|
|
66
|
+
beforeEach(() => {
|
|
67
|
+
(casperAccountHashFromPublicKey as jest.Mock).mockImplementation(
|
|
68
|
+
(key: string) => `account-hash-${key}`,
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("should map an outgoing transaction to operation", () => {
|
|
73
|
+
// Use a modified version of the fixture tx data
|
|
74
|
+
const fixtureData = fixtures.createMockAccountShapeData();
|
|
75
|
+
const txData: ITxnHistoryData = {
|
|
76
|
+
...fixtureData.mockTxs[0],
|
|
77
|
+
timestamp: mockTimestamp,
|
|
78
|
+
caller_public_key: "owner-public-key",
|
|
79
|
+
args: {
|
|
80
|
+
target: {
|
|
81
|
+
cl_type: "PublicKey",
|
|
82
|
+
parsed: "recipient-public-key",
|
|
83
|
+
},
|
|
84
|
+
amount: {
|
|
85
|
+
parsed: "5000000000",
|
|
86
|
+
cl_type: "U512",
|
|
87
|
+
},
|
|
88
|
+
id: {
|
|
89
|
+
parsed: 12345,
|
|
90
|
+
cl_type: {
|
|
91
|
+
Option: "U64",
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
deploy_hash: "test-deploy-hash",
|
|
96
|
+
status: "success",
|
|
97
|
+
amount: "5000000000",
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// Set up the owner address hash to match the from account hash
|
|
101
|
+
(casperAccountHashFromPublicKey as jest.Mock).mockReturnValueOnce(
|
|
102
|
+
"account-hash-owner-public-key",
|
|
103
|
+
);
|
|
104
|
+
(casperAccountHashFromPublicKey as jest.Mock).mockReturnValueOnce(
|
|
105
|
+
"account-hash-recipient-public-key",
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const mapper = mapTxToOps(mockAccountId, "account-hash-owner-public-key", fees);
|
|
109
|
+
const operations = mapper(txData);
|
|
110
|
+
|
|
111
|
+
expect(operations).toHaveLength(1);
|
|
112
|
+
expect(operations[0]).toEqual({
|
|
113
|
+
id: `${mockAccountId}-${txData.deploy_hash}-OUT`,
|
|
114
|
+
hash: txData.deploy_hash,
|
|
115
|
+
type: "OUT",
|
|
116
|
+
value: new BigNumber("5000000000").plus(fees),
|
|
117
|
+
fee: fees,
|
|
118
|
+
blockHeight: 1,
|
|
119
|
+
hasFailed: false,
|
|
120
|
+
blockHash: null,
|
|
121
|
+
accountId: mockAccountId,
|
|
122
|
+
senders: ["account-hash-owner-public-key"],
|
|
123
|
+
recipients: ["account-hash-recipient-public-key"],
|
|
124
|
+
date: new Date(mockTimestamp),
|
|
125
|
+
extra: {
|
|
126
|
+
transferId: "12345",
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("should map an incoming transaction to operation", () => {
|
|
132
|
+
const recipientAddressHash = "account-hash-owner-public-key";
|
|
133
|
+
// Use a modified version of the fixture tx data
|
|
134
|
+
const fixtureData = fixtures.createMockAccountShapeData();
|
|
135
|
+
const txData: ITxnHistoryData = {
|
|
136
|
+
...fixtureData.mockTxs[0],
|
|
137
|
+
timestamp: mockTimestamp,
|
|
138
|
+
caller_public_key: "sender-public-key",
|
|
139
|
+
args: {
|
|
140
|
+
target: {
|
|
141
|
+
cl_type: "PublicKey",
|
|
142
|
+
parsed: "owner-public-key",
|
|
143
|
+
},
|
|
144
|
+
amount: {
|
|
145
|
+
parsed: "5000000000",
|
|
146
|
+
cl_type: "U512",
|
|
147
|
+
},
|
|
148
|
+
id: {
|
|
149
|
+
parsed: 12345,
|
|
150
|
+
cl_type: {
|
|
151
|
+
Option: "U64",
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
deploy_hash: "test-deploy-hash",
|
|
156
|
+
status: "success",
|
|
157
|
+
amount: "5000000000",
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
(casperAccountHashFromPublicKey as jest.Mock).mockReturnValueOnce(
|
|
161
|
+
"account-hash-sender-public-key",
|
|
162
|
+
);
|
|
163
|
+
(casperAccountHashFromPublicKey as jest.Mock).mockReturnValueOnce(recipientAddressHash);
|
|
164
|
+
|
|
165
|
+
const mapper = mapTxToOps(mockAccountId, recipientAddressHash, fees);
|
|
166
|
+
const operations = mapper(txData);
|
|
167
|
+
|
|
168
|
+
expect(operations).toHaveLength(1);
|
|
169
|
+
expect(operations[0]).toEqual({
|
|
170
|
+
id: `${mockAccountId}-${txData.deploy_hash}-IN`,
|
|
171
|
+
hash: txData.deploy_hash,
|
|
172
|
+
type: "IN",
|
|
173
|
+
value: new BigNumber("5000000000"),
|
|
174
|
+
fee: fees,
|
|
175
|
+
blockHeight: 1,
|
|
176
|
+
hasFailed: false,
|
|
177
|
+
blockHash: null,
|
|
178
|
+
accountId: mockAccountId,
|
|
179
|
+
senders: ["account-hash-sender-public-key"],
|
|
180
|
+
recipients: [recipientAddressHash],
|
|
181
|
+
date: new Date(mockTimestamp),
|
|
182
|
+
extra: {
|
|
183
|
+
transferId: "12345",
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test("should map a failed transaction correctly", () => {
|
|
189
|
+
// Use a modified version of the fixture tx data
|
|
190
|
+
const fixtureData = fixtures.createMockAccountShapeData();
|
|
191
|
+
const txData: ITxnHistoryData = {
|
|
192
|
+
...fixtureData.mockTxs[0],
|
|
193
|
+
timestamp: mockTimestamp,
|
|
194
|
+
caller_public_key: "owner-public-key",
|
|
195
|
+
args: {
|
|
196
|
+
target: {
|
|
197
|
+
cl_type: "PublicKey",
|
|
198
|
+
parsed: "recipient-public-key",
|
|
199
|
+
},
|
|
200
|
+
amount: {
|
|
201
|
+
parsed: "5000000000",
|
|
202
|
+
cl_type: "U512",
|
|
203
|
+
},
|
|
204
|
+
id: {
|
|
205
|
+
parsed: 12345,
|
|
206
|
+
cl_type: {
|
|
207
|
+
Option: "U64",
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
deploy_hash: "test-deploy-hash",
|
|
212
|
+
error_message: "Transaction failed due to insufficient funds",
|
|
213
|
+
status: "failure",
|
|
214
|
+
amount: "5000000000",
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
(casperAccountHashFromPublicKey as jest.Mock).mockReturnValueOnce(
|
|
218
|
+
"account-hash-owner-public-key",
|
|
219
|
+
);
|
|
220
|
+
(casperAccountHashFromPublicKey as jest.Mock).mockReturnValueOnce(
|
|
221
|
+
"account-hash-recipient-public-key",
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
const mapper = mapTxToOps(mockAccountId, "account-hash-owner-public-key", fees);
|
|
225
|
+
const operations = mapper(txData);
|
|
226
|
+
|
|
227
|
+
expect(operations).toHaveLength(1);
|
|
228
|
+
expect(operations[0].hasFailed).toBe(true);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test("should handle target as account hash string directly", () => {
|
|
232
|
+
// Use a modified version of the fixture tx data
|
|
233
|
+
const fixtureData = fixtures.createMockAccountShapeData();
|
|
234
|
+
const txData: ITxnHistoryData = {
|
|
235
|
+
...fixtureData.mockTxs[0],
|
|
236
|
+
timestamp: mockTimestamp,
|
|
237
|
+
caller_public_key: "owner-public-key",
|
|
238
|
+
args: {
|
|
239
|
+
target: {
|
|
240
|
+
cl_type: {
|
|
241
|
+
ByteArray: 32,
|
|
242
|
+
},
|
|
243
|
+
parsed: "account-hash-direct-address",
|
|
244
|
+
},
|
|
245
|
+
amount: {
|
|
246
|
+
parsed: "5000000000",
|
|
247
|
+
cl_type: "U512",
|
|
248
|
+
},
|
|
249
|
+
id: {
|
|
250
|
+
parsed: 12345,
|
|
251
|
+
cl_type: {
|
|
252
|
+
Option: "U64",
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
deploy_hash: "test-deploy-hash",
|
|
257
|
+
status: "success",
|
|
258
|
+
amount: "5000000000",
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
(casperAccountHashFromPublicKey as jest.Mock).mockReturnValueOnce(
|
|
262
|
+
"account-hash-owner-public-key",
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const mapper = mapTxToOps(mockAccountId, "account-hash-owner-public-key", fees);
|
|
266
|
+
const operations = mapper(txData);
|
|
267
|
+
|
|
268
|
+
expect(operations).toHaveLength(1);
|
|
269
|
+
expect(operations[0].recipients).toEqual(["account-hash-direct-address"]);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
test("should catch and log errors when mapping fails", () => {
|
|
273
|
+
const txData = {
|
|
274
|
+
timestamp: mockTimestamp,
|
|
275
|
+
caller_public_key: "owner-public-key",
|
|
276
|
+
args: {
|
|
277
|
+
// Intentionally missing the target field to cause an error
|
|
278
|
+
amount: {
|
|
279
|
+
parsed: "5000000000",
|
|
280
|
+
cl_type: "U512",
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
deploy_hash: "test-deploy-hash",
|
|
284
|
+
block_hash: "block-hash-1",
|
|
285
|
+
execution_type_id: 1,
|
|
286
|
+
cost: "100000",
|
|
287
|
+
payment_amount: "100000000",
|
|
288
|
+
status: "success",
|
|
289
|
+
amount: "5000000000",
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const mapper = mapTxToOps(mockAccountId, "account-hash-owner-public-key", fees);
|
|
293
|
+
const operations = mapper(txData as any);
|
|
294
|
+
|
|
295
|
+
expect(operations).toEqual([]);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe("createNewTransaction", () => {
|
|
300
|
+
const { mockAddress: mockSender } = fixtures.createMockAccountShapeData();
|
|
301
|
+
const mockRecipient = fixtures.TEST_ADDRESSES.RECIPIENT_SECP256K1;
|
|
302
|
+
const mockAmount = new BigNumber("5000000000");
|
|
303
|
+
const mockFees = new BigNumber("100000000");
|
|
304
|
+
const mockTransferId = fixtures.TEST_TRANSFER_IDS.VALID;
|
|
305
|
+
|
|
306
|
+
// Direct access to the mocks from jest.mock
|
|
307
|
+
const mockCreateNetwork = mockCasperSDK.CasperNetwork.create;
|
|
308
|
+
const mockPublicKeyFromHex = mockCasperSDK.PublicKey.fromHex;
|
|
309
|
+
|
|
310
|
+
beforeEach(() => {
|
|
311
|
+
(isAddressValid as jest.Mock).mockReturnValue(true);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
test("should throw error if recipient address is invalid", async () => {
|
|
315
|
+
(isAddressValid as jest.Mock).mockReturnValue(false);
|
|
316
|
+
|
|
317
|
+
await expect(
|
|
318
|
+
testCreateNewTransaction(mockSender, mockRecipient, mockAmount, mockFees),
|
|
319
|
+
).rejects.toThrow();
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
test("should create a new transaction with valid parameters", async () => {
|
|
323
|
+
const expectedTransaction = { id: "mock-transaction" };
|
|
324
|
+
|
|
325
|
+
const result = await testCreateNewTransaction(
|
|
326
|
+
mockSender,
|
|
327
|
+
mockRecipient,
|
|
328
|
+
mockAmount,
|
|
329
|
+
mockFees,
|
|
330
|
+
mockTransferId,
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
expect(result).toEqual(expectedTransaction);
|
|
334
|
+
expect(mockCreateNetwork).toHaveBeenCalled();
|
|
335
|
+
expect(mockPublicKeyFromHex).toHaveBeenCalledWith(mockSender);
|
|
336
|
+
expect(mockPublicKeyFromHex).toHaveBeenCalledWith(mockRecipient);
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
});
|
|
@@ -3,14 +3,15 @@ import { InvalidAddress } from "@ledgerhq/errors";
|
|
|
3
3
|
import { log } from "@ledgerhq/logs";
|
|
4
4
|
import { Unit } from "@ledgerhq/types-cryptoassets";
|
|
5
5
|
import BigNumber from "bignumber.js";
|
|
6
|
-
import {
|
|
6
|
+
import { CasperNetwork, PublicKey, Transaction } from "casper-js-sdk";
|
|
7
7
|
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
8
|
-
import { CASPER_NETWORK } from "../../consts";
|
|
9
|
-
import { casperAccountHashFromPublicKey,
|
|
8
|
+
import { CASPER_DEFAULT_TTL, CASPER_NETWORK } from "../../consts";
|
|
9
|
+
import { casperAccountHashFromPublicKey, isAddressValid } from "./addresses";
|
|
10
10
|
import { ITxnHistoryData } from "../../api/types";
|
|
11
11
|
import { getEstimatedFees } from "./fee";
|
|
12
12
|
import { CasperOperation } from "../../types";
|
|
13
13
|
import invariant from "invariant";
|
|
14
|
+
import { getCasperNodeRpcClient } from "../../api";
|
|
14
15
|
|
|
15
16
|
export const getUnit = (): Unit => getCryptoCurrencyById("casper").units[0];
|
|
16
17
|
|
|
@@ -89,33 +90,32 @@ export function mapTxToOps(
|
|
|
89
90
|
};
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
export const
|
|
93
|
+
export const createNewTransaction = async (
|
|
93
94
|
sender: string,
|
|
94
95
|
recipient: string,
|
|
95
96
|
amount: BigNumber,
|
|
96
97
|
fees: BigNumber,
|
|
97
98
|
transferId?: string,
|
|
98
99
|
network = CASPER_NETWORK,
|
|
99
|
-
):
|
|
100
|
-
log("debug", `Creating new
|
|
100
|
+
): Promise<Transaction> => {
|
|
101
|
+
log("debug", `Creating new Transaction: ${sender}, ${recipient}, ${network}`);
|
|
101
102
|
|
|
102
103
|
if (recipient && !isAddressValid(recipient)) {
|
|
103
104
|
throw InvalidAddress(`Invalid recipient Address ${recipient}`);
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
const
|
|
107
|
+
const client = getCasperNodeRpcClient();
|
|
108
|
+
const helper = await CasperNetwork.create(client);
|
|
107
109
|
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
const tx = helper.createTransferTransaction(
|
|
111
|
+
PublicKey.fromHex(sender),
|
|
112
|
+
PublicKey.fromHex(recipient),
|
|
113
|
+
network,
|
|
114
|
+
amount.toString(),
|
|
115
|
+
fees.toNumber(),
|
|
116
|
+
CASPER_DEFAULT_TTL,
|
|
117
|
+
parseInt(transferId ?? "0"),
|
|
113
118
|
);
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
const deploy = DeployUtil.makeDeploy(deployParams, session, payment);
|
|
117
|
-
const txnRaw = DeployUtil.deployToJson(deploy);
|
|
118
|
-
const txnFromRaw = DeployUtil.deployFromJson(txnRaw).unwrap();
|
|
119
|
-
|
|
120
|
-
return txnFromRaw;
|
|
120
|
+
return tx;
|
|
121
121
|
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Transaction as CasperTransaction, PublicKey } from "casper-js-sdk";
|
|
2
|
+
import { broadcast } from "./broadcast";
|
|
3
|
+
import { broadcastTx } from "../api";
|
|
4
|
+
import {
|
|
5
|
+
createMockAccount,
|
|
6
|
+
createMockTransaction,
|
|
7
|
+
createMockSignedOperation,
|
|
8
|
+
} from "../test/fixtures";
|
|
9
|
+
import { patchOperationWithHash } from "@ledgerhq/coin-framework/lib/operation";
|
|
10
|
+
|
|
11
|
+
// Mock the dependencies
|
|
12
|
+
jest.mock("casper-js-sdk", () => {
|
|
13
|
+
return {
|
|
14
|
+
Transaction: {
|
|
15
|
+
fromJSON: jest.fn().mockReturnValue({
|
|
16
|
+
setSignature: jest.fn(),
|
|
17
|
+
}),
|
|
18
|
+
},
|
|
19
|
+
PublicKey: {
|
|
20
|
+
fromHex: jest.fn().mockReturnValue("mockedPublicKey"),
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
jest.mock("../api", () => ({
|
|
26
|
+
broadcastTx: jest.fn().mockResolvedValue("mockedTxHash"),
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
describe("broadcast", () => {
|
|
30
|
+
// Create test fixtures
|
|
31
|
+
const mockAccount = createMockAccount();
|
|
32
|
+
const mockTransaction = createMockTransaction();
|
|
33
|
+
const mockSignedOperation = createMockSignedOperation(mockAccount, mockTransaction, {
|
|
34
|
+
signature: "deadbeef",
|
|
35
|
+
rawTxJson: { hash: "mockTxHash" },
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
afterEach(() => {
|
|
39
|
+
jest.clearAllMocks();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("should successfully broadcast a transaction", async () => {
|
|
43
|
+
const result = await broadcast({
|
|
44
|
+
account: mockAccount,
|
|
45
|
+
signedOperation: mockSignedOperation,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Assert the transaction was constructed and signed correctly
|
|
49
|
+
expect(CasperTransaction.fromJSON).toHaveBeenCalledWith(mockSignedOperation.rawData.tx);
|
|
50
|
+
expect(PublicKey.fromHex).toHaveBeenCalledWith(mockAccount.freshAddress);
|
|
51
|
+
|
|
52
|
+
// Assert the transaction was broadcast
|
|
53
|
+
expect(broadcastTx).toHaveBeenCalled();
|
|
54
|
+
|
|
55
|
+
// Assert the operation was patched with the hash
|
|
56
|
+
expect(result.hash).toBe("mockedTxHash");
|
|
57
|
+
expect(result).toEqual({
|
|
58
|
+
...patchOperationWithHash(mockSignedOperation.operation, "mockedTxHash"),
|
|
59
|
+
hash: "mockedTxHash",
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("should throw if rawData is missing", async () => {
|
|
64
|
+
// Create a type-safe but invalid signed operation for testing
|
|
65
|
+
const invalidSignedOperation = {
|
|
66
|
+
...mockSignedOperation,
|
|
67
|
+
rawData: null as any, // Force type assertion for test
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
await expect(
|
|
71
|
+
broadcast({
|
|
72
|
+
account: mockAccount,
|
|
73
|
+
signedOperation: invalidSignedOperation,
|
|
74
|
+
}),
|
|
75
|
+
).rejects.toThrow("casper: rawData is required");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("should throw if broadcast fails to return a hash", async () => {
|
|
79
|
+
// Mock broadcastTx to return null (failed broadcast)
|
|
80
|
+
(broadcastTx as jest.Mock).mockResolvedValueOnce(null);
|
|
81
|
+
|
|
82
|
+
await expect(
|
|
83
|
+
broadcast({
|
|
84
|
+
account: mockAccount,
|
|
85
|
+
signedOperation: mockSignedOperation,
|
|
86
|
+
}),
|
|
87
|
+
).rejects.toThrow("casper: failed to broadcast transaction and get transaction hash");
|
|
88
|
+
});
|
|
89
|
+
});
|
package/src/bridge/broadcast.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Transaction as CasperTransaction, PublicKey } from "casper-js-sdk";
|
|
2
2
|
import { AccountBridge } from "@ledgerhq/types-live";
|
|
3
3
|
import { patchOperationWithHash } from "@ledgerhq/coin-framework/operation";
|
|
4
4
|
import { Transaction } from "../types";
|
|
@@ -6,15 +6,17 @@ import { broadcastTx } from "../api";
|
|
|
6
6
|
import invariant from "invariant";
|
|
7
7
|
|
|
8
8
|
export const broadcast: AccountBridge<Transaction>["broadcast"] = async ({
|
|
9
|
-
|
|
9
|
+
account,
|
|
10
|
+
signedOperation: { signature, operation, rawData },
|
|
10
11
|
}) => {
|
|
11
|
-
|
|
12
|
+
invariant(rawData, "casper: rawData is required");
|
|
13
|
+
const tx = CasperTransaction.fromJSON(rawData.tx);
|
|
14
|
+
tx.setSignature(Buffer.from(signature, "hex"), PublicKey.fromHex(account.freshAddress));
|
|
12
15
|
|
|
13
|
-
const
|
|
14
|
-
invariant(
|
|
15
|
-
const { deploy_hash } = resp;
|
|
16
|
+
const hash = await broadcastTx(tx);
|
|
17
|
+
invariant(hash, "casper: failed to broadcast transaction and get transaction hash");
|
|
16
18
|
|
|
17
|
-
const result = patchOperationWithHash(operation,
|
|
19
|
+
const result = patchOperationWithHash(operation, hash);
|
|
18
20
|
|
|
19
21
|
return result;
|
|
20
22
|
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { buildOptimisticOperation } from "./buildOptimisticOperation";
|
|
2
|
+
import { getAddress } from "./bridgeHelpers/addresses";
|
|
3
|
+
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
4
|
+
import { createMockAccount, createMockTransaction, TEST_TRANSFER_IDS } from "../test/fixtures";
|
|
5
|
+
|
|
6
|
+
// Mock dependencies
|
|
7
|
+
jest.mock("./bridgeHelpers/addresses", () => ({
|
|
8
|
+
getAddress: jest.fn(),
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
jest.mock("@ledgerhq/coin-framework/operation", () => ({
|
|
12
|
+
encodeOperationId: jest.fn(),
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
describe("buildOptimisticOperation", () => {
|
|
16
|
+
// Create test fixtures using helper functions
|
|
17
|
+
const mockAccount = createMockAccount();
|
|
18
|
+
const mockTransaction = createMockTransaction();
|
|
19
|
+
|
|
20
|
+
const mockHash = "mockedTransactionHash";
|
|
21
|
+
const mockAddress = "01abcdef1234567890";
|
|
22
|
+
const mockOperationId = "mockOperationId";
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
jest.clearAllMocks();
|
|
26
|
+
(getAddress as jest.Mock).mockReturnValue({ address: mockAddress });
|
|
27
|
+
(encodeOperationId as jest.Mock).mockReturnValue(mockOperationId);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("should build an optimistic operation for an outgoing transaction", () => {
|
|
31
|
+
const operation = buildOptimisticOperation(mockAccount, mockTransaction, mockHash);
|
|
32
|
+
|
|
33
|
+
expect(getAddress).toHaveBeenCalledWith(mockAccount);
|
|
34
|
+
expect(encodeOperationId).toHaveBeenCalledWith(mockAccount.id, mockHash, "OUT");
|
|
35
|
+
|
|
36
|
+
expect(operation).toEqual({
|
|
37
|
+
id: mockOperationId,
|
|
38
|
+
hash: mockHash,
|
|
39
|
+
type: "OUT",
|
|
40
|
+
senders: [mockAddress],
|
|
41
|
+
recipients: [mockTransaction.recipient],
|
|
42
|
+
accountId: mockAccount.id,
|
|
43
|
+
value: mockTransaction.amount.plus(mockTransaction.fees),
|
|
44
|
+
fee: mockTransaction.fees,
|
|
45
|
+
blockHash: null,
|
|
46
|
+
blockHeight: null,
|
|
47
|
+
date: expect.any(Date),
|
|
48
|
+
extra: {
|
|
49
|
+
transferId: mockTransaction.transferId,
|
|
50
|
+
},
|
|
51
|
+
nftOperations: [],
|
|
52
|
+
subOperations: [],
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("should build an optimistic operation with a custom operation type", () => {
|
|
57
|
+
const customType = "IN";
|
|
58
|
+
const operation = buildOptimisticOperation(mockAccount, mockTransaction, mockHash, customType);
|
|
59
|
+
|
|
60
|
+
expect(encodeOperationId).toHaveBeenCalledWith(mockAccount.id, mockHash, customType);
|
|
61
|
+
expect(operation.type).toBe(customType);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("should include transferId in the extra field when present", () => {
|
|
65
|
+
const txWithTransferId = {
|
|
66
|
+
...mockTransaction,
|
|
67
|
+
transferId: TEST_TRANSFER_IDS.VALID,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const operation = buildOptimisticOperation(mockAccount, txWithTransferId, mockHash);
|
|
71
|
+
|
|
72
|
+
expect(operation.extra).toEqual({
|
|
73
|
+
transferId: TEST_TRANSFER_IDS.VALID,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("should handle transaction without transferId", () => {
|
|
78
|
+
const txWithoutTransferId = {
|
|
79
|
+
...mockTransaction,
|
|
80
|
+
transferId: undefined,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const operation = buildOptimisticOperation(mockAccount, txWithoutTransferId, mockHash);
|
|
84
|
+
|
|
85
|
+
expect(operation.extra).toEqual({
|
|
86
|
+
transferId: undefined,
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
import { createTransaction } from "./createTransaction";
|
|
3
|
+
import { Transaction } from "../types";
|
|
4
|
+
import { Account, AccountLike } from "@ledgerhq/types-live";
|
|
5
|
+
|
|
6
|
+
describe("createTransaction", () => {
|
|
7
|
+
it("should create a transaction with default values", () => {
|
|
8
|
+
const transaction = createTransaction({} as AccountLike<Account>);
|
|
9
|
+
const expectedTransaction: Transaction = {
|
|
10
|
+
family: "casper",
|
|
11
|
+
amount: new BigNumber(0),
|
|
12
|
+
fees: new BigNumber(0),
|
|
13
|
+
recipient: "",
|
|
14
|
+
useAllAmount: false,
|
|
15
|
+
};
|
|
16
|
+
expect(transaction).toEqual(expectedTransaction);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("should create a transaction with the correct family", () => {
|
|
20
|
+
const transaction = createTransaction({} as AccountLike<Account>);
|
|
21
|
+
expect(transaction.family).toBe("casper");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should create a transaction with default amount set to zero", () => {
|
|
25
|
+
const transaction = createTransaction({} as AccountLike<Account>);
|
|
26
|
+
expect(transaction.amount.isEqualTo(new BigNumber(0))).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should create a transaction with default fees set to zero", () => {
|
|
30
|
+
const transaction = createTransaction({} as AccountLike<Account>);
|
|
31
|
+
expect(transaction.fees.isEqualTo(new BigNumber(0))).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("should create a transaction with empty recipient", () => {
|
|
35
|
+
const transaction = createTransaction({} as AccountLike<Account>);
|
|
36
|
+
expect(transaction.recipient).toBe("");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("should create a transaction with useAllAmount set to false", () => {
|
|
40
|
+
const transaction = createTransaction({} as AccountLike<Account>);
|
|
41
|
+
expect(transaction.useAllAmount).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
});
|