@ledgerhq/coin-canton 0.9.0-nightly.1 → 0.9.0-nightly.20251030160608
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 +2 -1
- package/CHANGELOG.md +26 -9
- package/README.md +75 -0
- package/lib/bridge/deviceTransactionConfig.d.ts +1 -1
- package/lib/bridge/deviceTransactionConfig.d.ts.map +1 -1
- package/lib/bridge/deviceTransactionConfig.js +1 -1
- package/lib/bridge/deviceTransactionConfig.js.map +1 -1
- package/lib/bridge/estimateMaxSpendable.d.ts +2 -2
- package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -1
- package/lib/bridge/estimateMaxSpendable.js +2 -3
- package/lib/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib/bridge/getTransactionStatus.d.ts +5 -3
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/getTransactionStatus.js +27 -10
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/index.d.ts +2 -2
- package/lib/bridge/index.d.ts.map +1 -1
- package/lib/bridge/index.js +3 -3
- package/lib/bridge/index.js.map +1 -1
- package/lib/bridge/onboard.d.ts.map +1 -1
- package/lib/bridge/onboard.js +48 -22
- package/lib/bridge/onboard.js.map +1 -1
- package/lib/bridge/prepareTransaction.js +1 -1
- package/lib/bridge/prepareTransaction.js.map +1 -1
- package/lib/bridge/serialization.d.ts +4 -0
- package/lib/bridge/serialization.d.ts.map +1 -0
- package/lib/bridge/serialization.js +36 -0
- package/lib/bridge/serialization.js.map +1 -0
- package/lib/bridge/signOperation.d.ts.map +1 -1
- package/lib/bridge/signOperation.js +11 -4
- package/lib/bridge/signOperation.js.map +1 -1
- package/lib/bridge/sync.d.ts.map +1 -1
- package/lib/bridge/sync.js +14 -6
- package/lib/bridge/sync.js.map +1 -1
- package/lib/bridge/transaction.js +1 -1
- package/lib/bridge/transaction.js.map +1 -1
- package/lib/common-logic/account/getBalance.d.ts +5 -1
- package/lib/common-logic/account/getBalance.d.ts.map +1 -1
- package/lib/common-logic/account/getBalance.js +2 -0
- package/lib/common-logic/account/getBalance.js.map +1 -1
- package/lib/common-logic/index.d.ts +1 -0
- package/lib/common-logic/index.d.ts.map +1 -1
- package/lib/common-logic/index.js +3 -1
- package/lib/common-logic/index.js.map +1 -1
- package/lib/common-logic/transaction/craftTransaction.js +1 -1
- package/lib/common-logic/transaction/craftTransaction.js.map +1 -1
- package/lib/common-logic/transaction/estimateFees.js +1 -1
- package/lib/common-logic/transaction/estimateFees.js.map +1 -1
- package/lib/common-logic/transaction/sign.d.ts +8 -0
- package/lib/common-logic/transaction/sign.d.ts.map +1 -0
- package/lib/common-logic/transaction/sign.js +45 -0
- package/lib/common-logic/transaction/sign.js.map +1 -0
- package/lib/common-logic/transaction/split.d.ts +9 -0
- package/lib/common-logic/transaction/split.d.ts.map +1 -0
- package/lib/common-logic/transaction/split.js +119 -0
- package/lib/common-logic/transaction/split.js.map +1 -0
- package/lib/common-logic/utils.js +2 -2
- package/lib/common-logic/utils.js.map +1 -1
- package/lib/network/gateway.d.ts +6 -1
- package/lib/network/gateway.d.ts.map +1 -1
- package/lib/network/gateway.js +6 -9
- package/lib/network/gateway.js.map +1 -1
- package/lib/test/cantonTestUtils.d.ts +4 -9
- package/lib/test/cantonTestUtils.d.ts.map +1 -1
- package/lib/test/cantonTestUtils.js +736 -27
- package/lib/test/cantonTestUtils.js.map +1 -1
- package/lib/test/fixtures.d.ts +5 -0
- package/lib/test/fixtures.d.ts.map +1 -0
- package/lib/test/fixtures.js +57 -0
- package/lib/test/fixtures.js.map +1 -0
- package/lib/types/bridge.d.ts +14 -2
- package/lib/types/bridge.d.ts.map +1 -1
- package/lib/types/errors.d.ts +6 -0
- package/lib/types/errors.d.ts.map +1 -1
- package/lib/types/errors.js +3 -1
- package/lib/types/errors.js.map +1 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +1 -0
- package/lib/types/index.js.map +1 -1
- package/lib/types/signer.d.ts +15 -2
- package/lib/types/signer.d.ts.map +1 -1
- package/lib/types/transaction-proto.json +1238 -0
- package/lib-es/bridge/deviceTransactionConfig.d.ts +1 -1
- package/lib-es/bridge/deviceTransactionConfig.d.ts.map +1 -1
- package/lib-es/bridge/deviceTransactionConfig.js +1 -1
- package/lib-es/bridge/deviceTransactionConfig.js.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.d.ts +2 -2
- package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.js +2 -3
- package/lib-es/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.d.ts +5 -3
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib-es/bridge/getTransactionStatus.js +27 -10
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/index.d.ts +2 -2
- package/lib-es/bridge/index.d.ts.map +1 -1
- package/lib-es/bridge/index.js +3 -3
- package/lib-es/bridge/index.js.map +1 -1
- package/lib-es/bridge/onboard.d.ts.map +1 -1
- package/lib-es/bridge/onboard.js +49 -23
- package/lib-es/bridge/onboard.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/serialization.d.ts +4 -0
- package/lib-es/bridge/serialization.d.ts.map +1 -0
- package/lib-es/bridge/serialization.js +32 -0
- package/lib-es/bridge/serialization.js.map +1 -0
- package/lib-es/bridge/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/signOperation.js +11 -4
- package/lib-es/bridge/signOperation.js.map +1 -1
- package/lib-es/bridge/sync.d.ts.map +1 -1
- package/lib-es/bridge/sync.js +14 -6
- package/lib-es/bridge/sync.js.map +1 -1
- package/lib-es/bridge/transaction.js +1 -1
- package/lib-es/bridge/transaction.js.map +1 -1
- package/lib-es/common-logic/account/getBalance.d.ts +5 -1
- package/lib-es/common-logic/account/getBalance.d.ts.map +1 -1
- package/lib-es/common-logic/account/getBalance.js +2 -0
- package/lib-es/common-logic/account/getBalance.js.map +1 -1
- package/lib-es/common-logic/index.d.ts +1 -0
- package/lib-es/common-logic/index.d.ts.map +1 -1
- package/lib-es/common-logic/index.js +1 -0
- package/lib-es/common-logic/index.js.map +1 -1
- package/lib-es/common-logic/transaction/craftTransaction.js +1 -1
- package/lib-es/common-logic/transaction/craftTransaction.js.map +1 -1
- package/lib-es/common-logic/transaction/estimateFees.js +1 -1
- package/lib-es/common-logic/transaction/estimateFees.js.map +1 -1
- package/lib-es/common-logic/transaction/sign.d.ts +8 -0
- package/lib-es/common-logic/transaction/sign.d.ts.map +1 -0
- package/lib-es/common-logic/transaction/sign.js +42 -0
- package/lib-es/common-logic/transaction/sign.js.map +1 -0
- package/lib-es/common-logic/transaction/split.d.ts +9 -0
- package/lib-es/common-logic/transaction/split.d.ts.map +1 -0
- package/lib-es/common-logic/transaction/split.js +83 -0
- package/lib-es/common-logic/transaction/split.js.map +1 -0
- package/lib-es/common-logic/utils.js +2 -2
- package/lib-es/common-logic/utils.js.map +1 -1
- package/lib-es/network/gateway.d.ts +6 -1
- package/lib-es/network/gateway.d.ts.map +1 -1
- package/lib-es/network/gateway.js +5 -10
- package/lib-es/network/gateway.js.map +1 -1
- package/lib-es/test/cantonTestUtils.d.ts +4 -9
- package/lib-es/test/cantonTestUtils.d.ts.map +1 -1
- package/lib-es/test/cantonTestUtils.js +697 -21
- package/lib-es/test/cantonTestUtils.js.map +1 -1
- package/lib-es/test/fixtures.d.ts +5 -0
- package/lib-es/test/fixtures.d.ts.map +1 -0
- package/lib-es/test/fixtures.js +49 -0
- package/lib-es/test/fixtures.js.map +1 -0
- package/lib-es/types/bridge.d.ts +14 -2
- package/lib-es/types/bridge.d.ts.map +1 -1
- package/lib-es/types/errors.d.ts +6 -0
- package/lib-es/types/errors.d.ts.map +1 -1
- package/lib-es/types/errors.js +2 -0
- package/lib-es/types/errors.js.map +1 -1
- package/lib-es/types/index.d.ts +1 -0
- package/lib-es/types/index.d.ts.map +1 -1
- package/lib-es/types/index.js +1 -0
- package/lib-es/types/index.js.map +1 -1
- package/lib-es/types/signer.d.ts +15 -2
- package/lib-es/types/signer.d.ts.map +1 -1
- package/lib-es/types/transaction-proto.json +1238 -0
- package/package.json +13 -10
- package/scripts/generate.js +261 -0
- package/src/bridge/deviceTransactionConfig.test.ts +14 -10
- package/src/bridge/deviceTransactionConfig.ts +2 -2
- package/src/bridge/estimateMaxSpendable.ts +6 -8
- package/src/bridge/getTransactionStatus.test.ts +103 -165
- package/src/bridge/getTransactionStatus.ts +43 -11
- package/src/bridge/index.ts +6 -5
- package/src/bridge/onboard.integ.test.ts +8 -51
- package/src/bridge/onboard.ts +58 -33
- package/src/bridge/prepareTransaction.ts +1 -1
- package/src/bridge/serialization.ts +44 -0
- package/src/bridge/signOperation.test.ts +123 -0
- package/src/bridge/signOperation.ts +13 -6
- package/src/bridge/sync.integ.test.ts +157 -132
- package/src/bridge/sync.test.ts +5 -1
- package/src/bridge/sync.ts +18 -7
- package/src/bridge/transaction.ts +1 -1
- package/src/common-logic/account/getBalance.ts +12 -2
- package/src/common-logic/account/getBalance.unit.test.ts +7 -1
- package/src/common-logic/index.ts +1 -0
- package/src/common-logic/transaction/craftTransaction.ts +1 -1
- package/src/common-logic/transaction/estimateFees.test.ts +10 -0
- package/src/common-logic/transaction/estimateFees.ts +1 -1
- package/src/common-logic/transaction/sign.test.ts +389 -0
- package/src/common-logic/transaction/sign.ts +59 -0
- package/src/common-logic/transaction/split.test.ts +50 -0
- package/src/common-logic/transaction/split.ts +101 -0
- package/src/common-logic/utils.test.ts +22 -30
- package/src/common-logic/utils.ts +2 -2
- package/src/network/gateway.integ.test.ts +5 -6
- package/src/network/gateway.ts +13 -10
- package/src/test/cantonTestUtils.ts +789 -24
- package/src/test/fixtures.ts +53 -0
- package/src/test/prepare-transfer-serialized.json +26 -0
- package/src/test/prepare-transfer.json +3298 -0
- package/src/types/bridge.ts +15 -2
- package/src/types/errors.ts +3 -0
- package/src/types/index.ts +1 -0
- package/src/types/signer.ts +21 -3
- package/src/types/transaction-proto.json +1238 -0
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import BigNumber from "bignumber.js";
|
|
2
|
-
import { Account } from "@ledgerhq/types-live";
|
|
3
|
-
import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
|
|
4
1
|
import {
|
|
5
2
|
AmountRequired,
|
|
6
3
|
FeeNotLoaded,
|
|
@@ -12,76 +9,37 @@ import {
|
|
|
12
9
|
NotEnoughSpendableBalance,
|
|
13
10
|
RecipientRequired,
|
|
14
11
|
} from "@ledgerhq/errors";
|
|
15
|
-
import
|
|
16
|
-
import { Transaction } from "../types";
|
|
12
|
+
import BigNumber from "bignumber.js";
|
|
17
13
|
import coinConfig from "../config";
|
|
14
|
+
import { createMockAccount } from "../test/fixtures";
|
|
15
|
+
import { CantonAccount, TooManyUtxosCritical, TooManyUtxosWarning, Transaction } from "../types";
|
|
16
|
+
import {
|
|
17
|
+
getTransactionStatus,
|
|
18
|
+
TO_MANY_UTXOS_CRITICAL_COUNT,
|
|
19
|
+
TO_MANY_UTXOS_WARNING_COUNT,
|
|
20
|
+
} from "./getTransactionStatus";
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
jest.mock("../config", () => ({
|
|
21
|
-
getCoinConfig: jest.fn(),
|
|
22
|
-
}));
|
|
23
|
-
|
|
22
|
+
jest.mock("../config", () => ({ getCoinConfig: jest.fn() }));
|
|
24
23
|
const mockCoinConfig = jest.mocked(coinConfig);
|
|
25
24
|
|
|
26
25
|
describe("getTransactionStatus", () => {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
const mockAccount: CantonAccount = {
|
|
27
|
+
...createMockAccount({
|
|
28
|
+
balance: new BigNumber(1000),
|
|
29
|
+
spendableBalance: new BigNumber(1000),
|
|
30
|
+
freshAddress: "test::33333333333333333333333333333333333333333333333333333333333333333333",
|
|
31
|
+
}),
|
|
32
|
+
cantonResources: {
|
|
33
|
+
instrumentUtxoCounts: {
|
|
34
|
+
Amulet: 5,
|
|
36
35
|
},
|
|
37
|
-
],
|
|
38
|
-
ticker: "CANTON",
|
|
39
|
-
scheme: "canton",
|
|
40
|
-
color: "#000000",
|
|
41
|
-
type: "CryptoCurrency",
|
|
42
|
-
managerAppName: "Canton",
|
|
43
|
-
coinType: 0,
|
|
44
|
-
disableCountervalue: false,
|
|
45
|
-
delisted: false,
|
|
46
|
-
keywords: ["canton"],
|
|
47
|
-
explorerViews: [],
|
|
48
|
-
terminated: {
|
|
49
|
-
link: "",
|
|
50
36
|
},
|
|
51
37
|
};
|
|
52
38
|
|
|
53
|
-
const mockAccount: Account = {
|
|
54
|
-
id: "test-account-id",
|
|
55
|
-
seedIdentifier: "test-seed-identifier",
|
|
56
|
-
currency: mockCurrency,
|
|
57
|
-
balance: new BigNumber(1000), // 1000 units
|
|
58
|
-
spendableBalance: new BigNumber(1000),
|
|
59
|
-
freshAddress: "test::123",
|
|
60
|
-
freshAddressPath: "44'/60'/0'/0/0",
|
|
61
|
-
index: 0,
|
|
62
|
-
derivationMode: "canton",
|
|
63
|
-
used: true,
|
|
64
|
-
operations: [],
|
|
65
|
-
pendingOperations: [],
|
|
66
|
-
lastSyncDate: new Date(),
|
|
67
|
-
creationDate: new Date(),
|
|
68
|
-
operationsCount: 0,
|
|
69
|
-
blockHeight: 100,
|
|
70
|
-
balanceHistoryCache: {
|
|
71
|
-
HOUR: { latestDate: null, balances: [] },
|
|
72
|
-
DAY: { latestDate: null, balances: [] },
|
|
73
|
-
WEEK: { latestDate: null, balances: [] },
|
|
74
|
-
},
|
|
75
|
-
swapHistory: [],
|
|
76
|
-
nfts: [],
|
|
77
|
-
subAccounts: [],
|
|
78
|
-
type: "Account",
|
|
79
|
-
};
|
|
80
|
-
|
|
81
39
|
beforeEach(() => {
|
|
82
40
|
jest.clearAllMocks();
|
|
83
41
|
mockCoinConfig.getCoinConfig.mockReturnValue({
|
|
84
|
-
minReserve: 100,
|
|
42
|
+
minReserve: 100,
|
|
85
43
|
networkType: "mainnet",
|
|
86
44
|
status: { type: "active" },
|
|
87
45
|
nativeInstrumentId: "Amulet",
|
|
@@ -89,11 +47,11 @@ describe("getTransactionStatus", () => {
|
|
|
89
47
|
});
|
|
90
48
|
|
|
91
49
|
describe("fee validation", () => {
|
|
92
|
-
it("should return FeeNotLoaded error when fee is
|
|
50
|
+
it("should return FeeNotLoaded error when fee is null", async () => {
|
|
93
51
|
const transaction: Transaction = {
|
|
94
52
|
family: "canton",
|
|
95
53
|
amount: new BigNumber(100),
|
|
96
|
-
recipient: "valid::
|
|
54
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
97
55
|
fee: null,
|
|
98
56
|
tokenId: "",
|
|
99
57
|
};
|
|
@@ -104,27 +62,27 @@ describe("getTransactionStatus", () => {
|
|
|
104
62
|
expect(result.warnings).toEqual({});
|
|
105
63
|
});
|
|
106
64
|
|
|
107
|
-
it("should return
|
|
65
|
+
it("should return FeeNotLoaded error when fee is undefined", async () => {
|
|
108
66
|
const transaction: Transaction = {
|
|
109
67
|
family: "canton",
|
|
110
68
|
amount: new BigNumber(100),
|
|
111
|
-
recipient: "valid::
|
|
112
|
-
fee:
|
|
69
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
70
|
+
fee: undefined,
|
|
113
71
|
tokenId: "",
|
|
114
72
|
};
|
|
115
73
|
|
|
116
74
|
const result = await getTransactionStatus(mockAccount, transaction);
|
|
117
75
|
|
|
118
|
-
expect(result.errors.fee).toBeInstanceOf(
|
|
76
|
+
expect(result.errors.fee).toBeInstanceOf(FeeNotLoaded);
|
|
119
77
|
expect(result.warnings).toEqual({});
|
|
120
78
|
});
|
|
121
79
|
|
|
122
80
|
it("should add FeeTooHigh warning when fee is more than 10 times the amount", async () => {
|
|
123
81
|
const transaction: Transaction = {
|
|
124
82
|
family: "canton",
|
|
125
|
-
amount: new BigNumber(100),
|
|
126
|
-
recipient: "valid::
|
|
127
|
-
fee: new BigNumber(1500),
|
|
83
|
+
amount: new BigNumber(100),
|
|
84
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
85
|
+
fee: new BigNumber(1500),
|
|
128
86
|
tokenId: "",
|
|
129
87
|
};
|
|
130
88
|
|
|
@@ -138,8 +96,8 @@ describe("getTransactionStatus", () => {
|
|
|
138
96
|
const transaction: Transaction = {
|
|
139
97
|
family: "canton",
|
|
140
98
|
amount: new BigNumber(100),
|
|
141
|
-
recipient: "valid::
|
|
142
|
-
fee: new BigNumber(10),
|
|
99
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
100
|
+
fee: new BigNumber(10),
|
|
143
101
|
tokenId: "",
|
|
144
102
|
};
|
|
145
103
|
|
|
@@ -154,8 +112,10 @@ describe("getTransactionStatus", () => {
|
|
|
154
112
|
it("should return NotEnoughSpendableBalance error when total spent exceeds balance minus reserve", async () => {
|
|
155
113
|
const transaction: Transaction = {
|
|
156
114
|
family: "canton",
|
|
157
|
-
amount:
|
|
158
|
-
|
|
115
|
+
amount: mockAccount.balance
|
|
116
|
+
.minus(new BigNumber(mockCoinConfig.getCoinConfig().minReserve))
|
|
117
|
+
.plus(1),
|
|
118
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
159
119
|
fee: new BigNumber(10),
|
|
160
120
|
tokenId: "",
|
|
161
121
|
};
|
|
@@ -168,8 +128,8 @@ describe("getTransactionStatus", () => {
|
|
|
168
128
|
it("should return NotEnoughBalanceBecauseDestinationNotCreated error when amount is below reserve", async () => {
|
|
169
129
|
const transaction: Transaction = {
|
|
170
130
|
family: "canton",
|
|
171
|
-
amount: new BigNumber(
|
|
172
|
-
recipient: "valid::
|
|
131
|
+
amount: new BigNumber(mockCoinConfig.getCoinConfig().minReserve).minus(1),
|
|
132
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
173
133
|
fee: new BigNumber(10),
|
|
174
134
|
tokenId: "",
|
|
175
135
|
};
|
|
@@ -182,8 +142,8 @@ describe("getTransactionStatus", () => {
|
|
|
182
142
|
it("should pass balance validation when transaction is within limits", async () => {
|
|
183
143
|
const transaction: Transaction = {
|
|
184
144
|
family: "canton",
|
|
185
|
-
amount:
|
|
186
|
-
recipient: "valid::
|
|
145
|
+
amount: mockAccount.balance.multipliedBy(0.5),
|
|
146
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
187
147
|
fee: new BigNumber(10),
|
|
188
148
|
tokenId: "",
|
|
189
149
|
};
|
|
@@ -209,18 +169,18 @@ describe("getTransactionStatus", () => {
|
|
|
209
169
|
expect(result.errors.recipient).toBeInstanceOf(RecipientRequired);
|
|
210
170
|
});
|
|
211
171
|
|
|
212
|
-
it("should return
|
|
172
|
+
it("should not return error when sending to self", async () => {
|
|
213
173
|
const transaction: Transaction = {
|
|
214
174
|
family: "canton",
|
|
215
175
|
amount: new BigNumber(100),
|
|
216
|
-
recipient:
|
|
176
|
+
recipient: mockAccount.freshAddress,
|
|
217
177
|
fee: new BigNumber(10),
|
|
218
178
|
tokenId: "",
|
|
219
179
|
};
|
|
220
180
|
|
|
221
181
|
const result = await getTransactionStatus(mockAccount, transaction);
|
|
222
182
|
|
|
223
|
-
expect(result.errors.recipient).
|
|
183
|
+
expect(result.errors.recipient).toBeUndefined();
|
|
224
184
|
});
|
|
225
185
|
|
|
226
186
|
it("should return InvalidAddress error when recipient is invalid", async () => {
|
|
@@ -241,7 +201,7 @@ describe("getTransactionStatus", () => {
|
|
|
241
201
|
const transaction: Transaction = {
|
|
242
202
|
family: "canton",
|
|
243
203
|
amount: new BigNumber(100),
|
|
244
|
-
recipient: "valid::
|
|
204
|
+
recipient: "valid::22222222222222222222222222222222222222222222222222222222222222222222",
|
|
245
205
|
fee: new BigNumber(10),
|
|
246
206
|
tokenId: "",
|
|
247
207
|
};
|
|
@@ -254,16 +214,8 @@ describe("getTransactionStatus", () => {
|
|
|
254
214
|
|
|
255
215
|
describe("amount validation", () => {
|
|
256
216
|
it("should return AmountRequired error when amount is zero", async () => {
|
|
257
|
-
// Create a scenario where there are no other amount errors
|
|
258
|
-
// Use a high balance and amount above reserve to avoid other amount errors
|
|
259
|
-
const accountWithHighBalance = {
|
|
260
|
-
...mockAccount,
|
|
261
|
-
balance: new BigNumber(10000), // High balance to avoid balance errors
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
// Set a high reserve to avoid the NotEnoughBalanceBecauseDestinationNotCreated error
|
|
265
217
|
mockCoinConfig.getCoinConfig.mockReturnValue({
|
|
266
|
-
minReserve: 0,
|
|
218
|
+
minReserve: 0,
|
|
267
219
|
networkType: "mainnet",
|
|
268
220
|
status: { type: "active" },
|
|
269
221
|
nativeInstrumentId: "Amulet",
|
|
@@ -272,12 +224,12 @@ describe("getTransactionStatus", () => {
|
|
|
272
224
|
const transaction: Transaction = {
|
|
273
225
|
family: "canton",
|
|
274
226
|
amount: new BigNumber(0),
|
|
275
|
-
recipient: "valid::
|
|
227
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
276
228
|
fee: new BigNumber(10),
|
|
277
229
|
tokenId: "",
|
|
278
230
|
};
|
|
279
231
|
|
|
280
|
-
const result = await getTransactionStatus(
|
|
232
|
+
const result = await getTransactionStatus(mockAccount, transaction);
|
|
281
233
|
|
|
282
234
|
expect(result.errors.amount).toBeInstanceOf(AmountRequired);
|
|
283
235
|
});
|
|
@@ -286,7 +238,7 @@ describe("getTransactionStatus", () => {
|
|
|
286
238
|
const transaction: Transaction = {
|
|
287
239
|
family: "canton",
|
|
288
240
|
amount: new BigNumber(100),
|
|
289
|
-
recipient: "valid::
|
|
241
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
290
242
|
fee: new BigNumber(10),
|
|
291
243
|
tokenId: "",
|
|
292
244
|
};
|
|
@@ -302,7 +254,7 @@ describe("getTransactionStatus", () => {
|
|
|
302
254
|
const transaction: Transaction = {
|
|
303
255
|
family: "canton",
|
|
304
256
|
amount: new BigNumber(100),
|
|
305
|
-
recipient: "valid::
|
|
257
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
306
258
|
fee: new BigNumber(10),
|
|
307
259
|
tokenId: "",
|
|
308
260
|
};
|
|
@@ -318,7 +270,7 @@ describe("getTransactionStatus", () => {
|
|
|
318
270
|
const transaction: Transaction = {
|
|
319
271
|
family: "canton",
|
|
320
272
|
amount: new BigNumber(100),
|
|
321
|
-
recipient: "valid::
|
|
273
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
322
274
|
fee: new BigNumber(10),
|
|
323
275
|
tokenId: "",
|
|
324
276
|
};
|
|
@@ -330,117 +282,103 @@ describe("getTransactionStatus", () => {
|
|
|
330
282
|
});
|
|
331
283
|
});
|
|
332
284
|
|
|
333
|
-
describe("
|
|
334
|
-
it("should
|
|
335
|
-
const
|
|
285
|
+
describe("UTXO count validation", () => {
|
|
286
|
+
it("should show critical warning when UTXO count exceeds TO_MANY_UTXOS_CRITICAL_COUNT", async () => {
|
|
287
|
+
const accountWithTooManyUtxos = {
|
|
336
288
|
...mockAccount,
|
|
337
|
-
|
|
289
|
+
cantonResources: {
|
|
290
|
+
instrumentUtxoCounts: {
|
|
291
|
+
Amulet: TO_MANY_UTXOS_CRITICAL_COUNT + 1,
|
|
292
|
+
},
|
|
293
|
+
},
|
|
338
294
|
};
|
|
339
295
|
|
|
340
296
|
const transaction: Transaction = {
|
|
341
297
|
family: "canton",
|
|
342
298
|
amount: new BigNumber(50),
|
|
343
|
-
recipient: "valid::
|
|
299
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
344
300
|
fee: new BigNumber(10),
|
|
345
|
-
tokenId: "",
|
|
301
|
+
tokenId: "Amulet",
|
|
346
302
|
};
|
|
347
303
|
|
|
348
|
-
const result = await getTransactionStatus(
|
|
304
|
+
const result = await getTransactionStatus(accountWithTooManyUtxos, transaction);
|
|
349
305
|
|
|
350
|
-
expect(result.
|
|
306
|
+
expect(result.warnings.tooManyUtxos).toBeDefined();
|
|
307
|
+
expect(result.warnings.tooManyUtxos).toBeInstanceOf(TooManyUtxosCritical);
|
|
351
308
|
});
|
|
352
309
|
|
|
353
|
-
it("should
|
|
354
|
-
const
|
|
310
|
+
it("should show warning when UTXO count exceeds TO_MANY_UTXOS_WARNING_COUNT", async () => {
|
|
311
|
+
const accountWithManyUtxos = {
|
|
355
312
|
...mockAccount,
|
|
356
|
-
|
|
313
|
+
cantonResources: {
|
|
314
|
+
instrumentUtxoCounts: {
|
|
315
|
+
Amulet: TO_MANY_UTXOS_WARNING_COUNT + 1,
|
|
316
|
+
},
|
|
317
|
+
},
|
|
357
318
|
};
|
|
358
319
|
|
|
359
320
|
const transaction: Transaction = {
|
|
360
321
|
family: "canton",
|
|
361
322
|
amount: new BigNumber(50),
|
|
362
|
-
recipient: "valid::
|
|
323
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
363
324
|
fee: new BigNumber(10),
|
|
364
|
-
tokenId: "",
|
|
325
|
+
tokenId: "Amulet",
|
|
365
326
|
};
|
|
366
327
|
|
|
367
|
-
const result = await getTransactionStatus(
|
|
328
|
+
const result = await getTransactionStatus(accountWithManyUtxos, transaction);
|
|
368
329
|
|
|
369
|
-
expect(result.
|
|
330
|
+
expect(result.warnings.tooManyUtxos).toBeDefined();
|
|
331
|
+
expect(result.warnings.tooManyUtxos).toBeInstanceOf(TooManyUtxosWarning);
|
|
332
|
+
expect(result.warnings.tooManyUtxos?.message).toContain(
|
|
333
|
+
"families.canton.tooManyUtxos.warning",
|
|
334
|
+
);
|
|
370
335
|
});
|
|
371
336
|
|
|
372
|
-
it("should
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
const transaction: Transaction = {
|
|
381
|
-
family: "canton",
|
|
382
|
-
amount: new BigNumber(50),
|
|
383
|
-
recipient: "valid::123",
|
|
384
|
-
fee: new BigNumber(10),
|
|
385
|
-
tokenId: "",
|
|
337
|
+
it("should not show warning or error when UTXO count is less than TO_MANY_UTXOS_WARNING_COUNT", async () => {
|
|
338
|
+
const accountWithFewUtxos = {
|
|
339
|
+
...mockAccount,
|
|
340
|
+
cantonResources: {
|
|
341
|
+
instrumentUtxoCounts: {
|
|
342
|
+
Amulet: TO_MANY_UTXOS_WARNING_COUNT - 1,
|
|
343
|
+
},
|
|
344
|
+
},
|
|
386
345
|
};
|
|
387
346
|
|
|
388
|
-
const result = await getTransactionStatus(mockAccount, transaction);
|
|
389
|
-
|
|
390
|
-
expect(result.errors.amount).toBeUndefined();
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
it("should handle undefined reserve amount", async () => {
|
|
394
|
-
mockCoinConfig.getCoinConfig.mockReturnValue({
|
|
395
|
-
networkType: "mainnet",
|
|
396
|
-
status: { type: "active" },
|
|
397
|
-
nativeInstrumentId: "Amulet",
|
|
398
|
-
});
|
|
399
|
-
|
|
400
347
|
const transaction: Transaction = {
|
|
401
348
|
family: "canton",
|
|
402
349
|
amount: new BigNumber(50),
|
|
403
|
-
recipient: "valid::
|
|
350
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
404
351
|
fee: new BigNumber(10),
|
|
405
|
-
tokenId: "",
|
|
352
|
+
tokenId: "Amulet", // Use the same tokenId as in cantonResources
|
|
406
353
|
};
|
|
407
354
|
|
|
408
|
-
const result = await getTransactionStatus(
|
|
355
|
+
const result = await getTransactionStatus(accountWithFewUtxos, transaction);
|
|
409
356
|
|
|
410
|
-
expect(result.
|
|
357
|
+
expect(result.warnings.tooManyUtxos).toBeUndefined();
|
|
411
358
|
});
|
|
412
|
-
});
|
|
413
359
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
360
|
+
it("should not show warning or error for abandon seed address transactions", async () => {
|
|
361
|
+
const accountWithManyUtxos = {
|
|
362
|
+
...mockAccount,
|
|
363
|
+
cantonResources: {
|
|
364
|
+
instrumentUtxoCounts: {
|
|
365
|
+
Amulet: 25,
|
|
366
|
+
},
|
|
367
|
+
},
|
|
422
368
|
};
|
|
423
369
|
|
|
424
|
-
const result = await getTransactionStatus(mockAccount, transaction);
|
|
425
|
-
|
|
426
|
-
expect(result.errors.amount).toBeInstanceOf(AmountRequired);
|
|
427
|
-
expect(result.errors.recipient).toBeInstanceOf(RecipientRequired);
|
|
428
|
-
expect(result.errors.fee).toBeInstanceOf(FeeNotLoaded);
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
it("should return both errors and warnings", async () => {
|
|
432
370
|
const transaction: Transaction = {
|
|
433
371
|
family: "canton",
|
|
434
|
-
amount: new BigNumber(
|
|
435
|
-
recipient: "
|
|
436
|
-
fee: new BigNumber(
|
|
437
|
-
tokenId: "",
|
|
372
|
+
amount: new BigNumber(50),
|
|
373
|
+
recipient: "abandon::ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
|
374
|
+
fee: new BigNumber(10),
|
|
375
|
+
tokenId: "Amulet",
|
|
438
376
|
};
|
|
439
377
|
|
|
440
|
-
const result = await getTransactionStatus(
|
|
378
|
+
const result = await getTransactionStatus(accountWithManyUtxos, transaction);
|
|
441
379
|
|
|
442
|
-
expect(result.warnings.
|
|
443
|
-
expect(result.errors.
|
|
380
|
+
expect(result.warnings.tooManyUtxos).toBeUndefined();
|
|
381
|
+
expect(result.errors.utxoCount).toBeUndefined();
|
|
444
382
|
});
|
|
445
383
|
});
|
|
446
384
|
});
|
|
@@ -4,21 +4,30 @@ import {
|
|
|
4
4
|
FeeRequired,
|
|
5
5
|
FeeTooHigh,
|
|
6
6
|
InvalidAddress,
|
|
7
|
-
InvalidAddressBecauseDestinationIsAlsoSource,
|
|
8
7
|
NotEnoughBalanceBecauseDestinationNotCreated,
|
|
9
8
|
NotEnoughSpendableBalance,
|
|
10
9
|
RecipientRequired,
|
|
11
10
|
} from "@ledgerhq/errors";
|
|
12
11
|
import BigNumber from "bignumber.js";
|
|
13
|
-
import {
|
|
12
|
+
import { AccountBridge } from "@ledgerhq/types-live";
|
|
14
13
|
import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies/index";
|
|
15
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
Transaction,
|
|
16
|
+
TransactionStatus,
|
|
17
|
+
CantonAccount,
|
|
18
|
+
TooManyUtxosCritical,
|
|
19
|
+
TooManyUtxosWarning,
|
|
20
|
+
} from "../types";
|
|
16
21
|
import { isRecipientValid } from "../common-logic/utils";
|
|
17
22
|
import coinConfig from "../config";
|
|
23
|
+
import { getAbandonSeedAddress } from "@ledgerhq/cryptoassets/abandonseed";
|
|
24
|
+
|
|
25
|
+
export const TO_MANY_UTXOS_CRITICAL_COUNT = 24;
|
|
26
|
+
export const TO_MANY_UTXOS_WARNING_COUNT = 10;
|
|
18
27
|
|
|
19
28
|
export const getTransactionStatus: AccountBridge<
|
|
20
29
|
Transaction,
|
|
21
|
-
|
|
30
|
+
CantonAccount,
|
|
22
31
|
TransactionStatus
|
|
23
32
|
>["getTransactionStatus"] = async (account, transaction) => {
|
|
24
33
|
const errors: Record<string, Error> = {};
|
|
@@ -35,12 +44,9 @@ export const getTransactionStatus: AccountBridge<
|
|
|
35
44
|
warnings.feeTooHigh = new FeeTooHigh();
|
|
36
45
|
}
|
|
37
46
|
|
|
38
|
-
if (
|
|
47
|
+
if (transaction.fee === null || transaction.fee === undefined) {
|
|
39
48
|
// if the fee is not loaded, we can't do much
|
|
40
49
|
errors.fee = new FeeNotLoaded();
|
|
41
|
-
} else if (transaction.fee.eq(0)) {
|
|
42
|
-
// On some chains, 0 fee could still work so this is optional
|
|
43
|
-
errors.fee = new FeeRequired();
|
|
44
50
|
} else if (totalSpent.gt(account.balance.minus(reserveAmount))) {
|
|
45
51
|
// if the total spent is greater than the balance minus the reserve amount, tx is invalid
|
|
46
52
|
errors.amount = new NotEnoughSpendableBalance("", {
|
|
@@ -63,9 +69,6 @@ export const getTransactionStatus: AccountBridge<
|
|
|
63
69
|
|
|
64
70
|
if (!transaction.recipient) {
|
|
65
71
|
errors.recipient = new RecipientRequired("");
|
|
66
|
-
} else if (account.freshAddress === transaction.recipient) {
|
|
67
|
-
// we want to prevent user from sending to themselves (even if it's technically feasible)
|
|
68
|
-
errors.recipient = new InvalidAddressBecauseDestinationIsAlsoSource();
|
|
69
72
|
} else if (!isRecipientValid(transaction.recipient)) {
|
|
70
73
|
// We want to prevent user from sending to an invalid address
|
|
71
74
|
errors.recipient = new InvalidAddress("", {
|
|
@@ -78,6 +81,8 @@ export const getTransactionStatus: AccountBridge<
|
|
|
78
81
|
errors.amount = new AmountRequired();
|
|
79
82
|
}
|
|
80
83
|
|
|
84
|
+
validateUtxoCount(account, transaction, warnings);
|
|
85
|
+
|
|
81
86
|
return {
|
|
82
87
|
errors,
|
|
83
88
|
warnings,
|
|
@@ -86,3 +91,30 @@ export const getTransactionStatus: AccountBridge<
|
|
|
86
91
|
totalSpent,
|
|
87
92
|
};
|
|
88
93
|
};
|
|
94
|
+
|
|
95
|
+
function validateUtxoCount(
|
|
96
|
+
account: CantonAccount,
|
|
97
|
+
transaction: Transaction,
|
|
98
|
+
warnings: Record<string, Error>,
|
|
99
|
+
): void {
|
|
100
|
+
const abandonSeedAddress = getAbandonSeedAddress(account.currency.id);
|
|
101
|
+
const isAbandonSeedAddress = transaction.recipient?.includes(abandonSeedAddress);
|
|
102
|
+
|
|
103
|
+
// UTXO count validation - only validate if recipient is valid and not equal to sender
|
|
104
|
+
// Skip validation for abandon seed addresses
|
|
105
|
+
if (
|
|
106
|
+
account?.cantonResources?.instrumentUtxoCounts &&
|
|
107
|
+
transaction.recipient &&
|
|
108
|
+
isRecipientValid(transaction.recipient) &&
|
|
109
|
+
account.xpub !== transaction.recipient &&
|
|
110
|
+
!isAbandonSeedAddress
|
|
111
|
+
) {
|
|
112
|
+
const { instrumentUtxoCounts } = account.cantonResources;
|
|
113
|
+
const instrumentUtxoCount = instrumentUtxoCounts[transaction.tokenId] || 0;
|
|
114
|
+
if (instrumentUtxoCount > TO_MANY_UTXOS_CRITICAL_COUNT) {
|
|
115
|
+
warnings.tooManyUtxos = new TooManyUtxosCritical();
|
|
116
|
+
} else if (instrumentUtxoCount > TO_MANY_UTXOS_WARNING_COUNT) {
|
|
117
|
+
warnings.tooManyUtxos = new TooManyUtxosWarning("families.canton.tooManyUtxos.warning");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
package/src/bridge/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { SignerContext } from "@ledgerhq/coin-framework/signer";
|
|
|
10
10
|
import type { AccountBridge } from "@ledgerhq/types-live";
|
|
11
11
|
import cantonCoinConfig, { type CantonCoinConfig } from "../config";
|
|
12
12
|
import resolver from "../signer";
|
|
13
|
-
import { CantonCurrencyBridge, CantonSigner } from "../types";
|
|
13
|
+
import { CantonCurrencyBridge, CantonSigner, CantonAccount } from "../types";
|
|
14
14
|
import type { Transaction } from "../types";
|
|
15
15
|
import { broadcast } from "./broadcast";
|
|
16
16
|
import { createTransaction } from "./createTransaction";
|
|
@@ -21,6 +21,7 @@ import { buildSignOperation } from "./signOperation";
|
|
|
21
21
|
import { makeGetAccountShape } from "./sync";
|
|
22
22
|
import { updateTransaction } from "./updateTransaction";
|
|
23
23
|
import { buildOnboardAccount, buildAuthorizePreapproval } from "./onboard";
|
|
24
|
+
import { assignToAccountRaw, assignFromAccountRaw } from "./serialization";
|
|
24
25
|
|
|
25
26
|
export function createBridges(
|
|
26
27
|
signerContext: SignerContext<CantonSigner>,
|
|
@@ -49,13 +50,11 @@ export function createBridges(
|
|
|
49
50
|
|
|
50
51
|
const signOperation = buildSignOperation(signerContext);
|
|
51
52
|
const sync = makeSync({ getAccountShape: makeGetAccountShape(signerContext) });
|
|
52
|
-
|
|
53
|
-
const accountBridge: AccountBridge<Transaction> = {
|
|
53
|
+
|
|
54
|
+
const accountBridge: AccountBridge<Transaction, CantonAccount> = {
|
|
54
55
|
broadcast,
|
|
55
56
|
createTransaction,
|
|
56
57
|
updateTransaction,
|
|
57
|
-
// NOTE: use updateTransaction: defaultUpdateTransaction<Transaction>,
|
|
58
|
-
// if you don't need to update the transaction patch object
|
|
59
58
|
prepareTransaction,
|
|
60
59
|
getTransactionStatus,
|
|
61
60
|
estimateMaxSpendable,
|
|
@@ -65,6 +64,8 @@ export function createBridges(
|
|
|
65
64
|
signRawOperation: () => {
|
|
66
65
|
throw new Error("signRawOperation is not supported");
|
|
67
66
|
},
|
|
67
|
+
assignToAccountRaw,
|
|
68
|
+
assignFromAccountRaw,
|
|
68
69
|
getSerializedAddressParameters,
|
|
69
70
|
};
|
|
70
71
|
|
|
@@ -1,45 +1,22 @@
|
|
|
1
|
-
import BigNumber from "bignumber.js";
|
|
2
|
-
import { firstValueFrom, toArray } from "rxjs";
|
|
3
1
|
import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
2
|
+
import { firstValueFrom, toArray } from "rxjs";
|
|
3
|
+
import coinConfig from "../config";
|
|
4
|
+
import { createMockSigner, generateMockKeyPair } from "../test/cantonTestUtils";
|
|
5
|
+
import { createMockAccount, createMockCantonCurrency } from "../test/fixtures";
|
|
6
6
|
import {
|
|
7
7
|
AuthorizeStatus,
|
|
8
|
-
OnboardStatus,
|
|
9
8
|
CantonAuthorizeProgress,
|
|
10
9
|
CantonAuthorizeResult,
|
|
11
10
|
CantonOnboardProgress,
|
|
12
11
|
CantonOnboardResult,
|
|
12
|
+
OnboardStatus,
|
|
13
13
|
} from "../types/onboard";
|
|
14
|
-
import
|
|
15
|
-
import { buildOnboardAccount, isAccountOnboarded, buildAuthorizePreapproval } from "./onboard";
|
|
14
|
+
import { buildAuthorizePreapproval, buildOnboardAccount, isAccountOnboarded } from "./onboard";
|
|
16
15
|
|
|
17
16
|
describe("onboard (devnet)", () => {
|
|
18
17
|
const mockDeviceId = "test-device-id";
|
|
19
|
-
const mockCurrency =
|
|
20
|
-
|
|
21
|
-
} as unknown as CryptoCurrency;
|
|
22
|
-
const mockAccount = {
|
|
23
|
-
type: "Account" as const,
|
|
24
|
-
id: "js:2:canton_network:canton_3f5c9d9a:canton",
|
|
25
|
-
seedIdentifier: "canton_3f5c9d9a",
|
|
26
|
-
derivationMode: "canton" as const,
|
|
27
|
-
index: 0,
|
|
28
|
-
freshAddress: "canton_3f5c9d9a",
|
|
29
|
-
freshAddressPath: "44'/6767'/0'/0'/0'",
|
|
30
|
-
used: false,
|
|
31
|
-
balance: BigNumber(10000),
|
|
32
|
-
spendableBalance: BigNumber(10000),
|
|
33
|
-
creationDate: new Date(),
|
|
34
|
-
blockHeight: 1,
|
|
35
|
-
currency: mockCurrency,
|
|
36
|
-
operationsCount: 0,
|
|
37
|
-
operations: [],
|
|
38
|
-
pendingOperations: [],
|
|
39
|
-
lastSyncDate: new Date(),
|
|
40
|
-
balanceHistoryCache: emptyHistoryCache,
|
|
41
|
-
swapHistory: [],
|
|
42
|
-
};
|
|
18
|
+
const mockCurrency = createMockCantonCurrency();
|
|
19
|
+
const mockAccount = createMockAccount();
|
|
43
20
|
|
|
44
21
|
let onboardedAccount: {
|
|
45
22
|
keyPair: ReturnType<typeof generateMockKeyPair>;
|
|
@@ -221,25 +198,5 @@ describe("onboard (devnet)", () => {
|
|
|
221
198
|
expect(finalResult.isApproved).toBe(true);
|
|
222
199
|
expect(typeof finalResult.isApproved).toBe("boolean");
|
|
223
200
|
}, 30000);
|
|
224
|
-
|
|
225
|
-
it("should handle invalid party ID gracefully", async () => {
|
|
226
|
-
// GIVEN
|
|
227
|
-
const keyPair = generateMockKeyPair();
|
|
228
|
-
const mockSigner = createMockSigner(keyPair);
|
|
229
|
-
const mockSignerContext = jest.fn().mockImplementation((deviceId, callback) => {
|
|
230
|
-
return callback(mockSigner);
|
|
231
|
-
});
|
|
232
|
-
const preapprovalObservable = buildAuthorizePreapproval(mockSignerContext);
|
|
233
|
-
|
|
234
|
-
// WHEN & THEN
|
|
235
|
-
try {
|
|
236
|
-
await firstValueFrom(
|
|
237
|
-
preapprovalObservable(mockCurrency, mockDeviceId, mockAccount, "invalid-party-id-123"),
|
|
238
|
-
);
|
|
239
|
-
expect(true).toBe(true);
|
|
240
|
-
} catch (error) {
|
|
241
|
-
expect(error).toBeDefined();
|
|
242
|
-
}
|
|
243
|
-
}, 30000);
|
|
244
201
|
});
|
|
245
202
|
});
|