@ledgerhq/hw-app-canton 0.6.0 → 0.7.0-nightly.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/lib-es/Canton.js CHANGED
@@ -1,15 +1,13 @@
1
- import { UserRefusedAddress, UserRefusedOnDevice } from "@ledgerhq/errors";
1
+ import { TransportStatusError } from "@ledgerhq/errors";
2
2
  import BIPPath from "bip32-path";
3
3
  const CLA = 0xe0;
4
4
  const P1_NON_CONFIRM = 0x00;
5
5
  const P1_CONFIRM = 0x01;
6
- // P2 indicating no information.
6
+ const P1_SIGN_UNTYPED_VERSIONED_MESSAGE = 0x01;
7
+ const P1_SIGN_PREPARED_TRANSACTION = 0x02;
7
8
  const P2_NONE = 0x00;
8
- // P2 indicating first APDU in a large request.
9
9
  const P2_FIRST = 0x01;
10
- // P2 indicating that this is not the last APDU in a large request.
11
10
  const P2_MORE = 0x02;
12
- // P2 indicating that this is the last APDU of a message in a multi message request.
13
11
  const P2_MSG_END = 0x04;
14
12
  const INS = {
15
13
  GET_VERSION: 0x03,
@@ -23,6 +21,7 @@ const STATUS = {
23
21
  };
24
22
  const ED25519_SIGNATURE_HEX_LENGTH = 128; // hex characters (64 bytes)
25
23
  const CANTON_SIGNATURE_HEX_LENGTH = 132; // hex characters (66 bytes with framing)
24
+ const MAX_APDU_DATA_LENGTH = 255;
26
25
  /**
27
26
  * Canton BOLOS API
28
27
  */
@@ -44,7 +43,8 @@ export default class Canton {
44
43
  const serializedPath = this.serializePath(bipPath);
45
44
  const p1 = display ? P1_CONFIRM : P1_NON_CONFIRM;
46
45
  const response = await this.transport.send(CLA, INS.GET_ADDR, p1, P2_NONE, serializedPath);
47
- const responseData = this.handleTransportResponse(response, "address");
46
+ this.checkTransportResponse(response);
47
+ const responseData = this.extractResponseData(response);
48
48
  const { publicKey } = this.extractPublicKeyAndChainCode(responseData);
49
49
  const address = "canton_" + this.publicKeyToAddress(publicKey);
50
50
  return {
@@ -54,23 +54,148 @@ export default class Canton {
54
54
  };
55
55
  }
56
56
  /**
57
- * Sign a Canton transaction.
57
+ * Sign a Canton transaction
58
+ * using the appropriate signing method based on transaction type.
58
59
  *
59
60
  * @param path a path in BIP-32 format
60
- * @param txHash the transaction hash to sign
61
+ * @param data either prepared transaction components, untyped versioned message, or txHash string (backwards compatibility)
61
62
  * @return the signature
62
63
  */
63
- async signTransaction(path, txHash) {
64
+ async signTransaction(path, data) {
65
+ // Backwards compatibility: handle txHash string format
66
+ if (typeof data === "string") {
67
+ return this.signTxHash(path, data);
68
+ }
69
+ if ("damlTransaction" in data) {
70
+ return this.signPreparedTransaction(path, data);
71
+ }
72
+ else {
73
+ return this.signUntypedVersionedMessage(path, data);
74
+ }
75
+ }
76
+ /**
77
+ * Sign a transaction hash (backwards compatibility)
78
+ * @private
79
+ */
80
+ async signTxHash(path, txHash) {
64
81
  // 1. Send the derivation path
65
82
  const bipPath = BIPPath.fromString(path).toPathArray();
66
83
  const serializedPath = this.serializePath(bipPath);
67
- const pathResponse = await this.transport.send(CLA, INS.SIGN, P1_NON_CONFIRM, P2_FIRST | P2_MORE, serializedPath);
68
- this.handleTransportResponse(pathResponse, "transaction");
69
- // 2. Send the transaction hash
70
- const response = await this.transport.send(CLA, INS.SIGN, P1_NON_CONFIRM, P2_MSG_END, Buffer.from(txHash, "hex"));
71
- const responseData = this.handleTransportResponse(response, "transaction");
72
- const rawSignature = responseData.toString("hex");
73
- return this.cleanSignatureFormat(rawSignature);
84
+ const pathResponse = await this.transport.send(CLA, INS.SIGN, P1_SIGN_UNTYPED_VERSIONED_MESSAGE, P2_FIRST | P2_MORE, serializedPath);
85
+ this.checkTransportResponse(pathResponse);
86
+ // 2. Send the transaction hash as a single transaction
87
+ const transactionBuffer = Buffer.from(txHash, "hex");
88
+ const response = await this.transport.send(CLA, INS.SIGN, P1_SIGN_UNTYPED_VERSIONED_MESSAGE, P2_MSG_END, transactionBuffer);
89
+ this.checkTransportResponse(response);
90
+ const responseData = this.extractResponseData(response);
91
+ return this.cleanSignatureFormat(responseData);
92
+ }
93
+ /**
94
+ * Sign a prepared Canton transaction
95
+ * @private
96
+ */
97
+ async signPreparedTransaction(path, components) {
98
+ let responseData = null;
99
+ // 1. Send the derivation path
100
+ const bipPath = BIPPath.fromString(path).toPathArray();
101
+ const serializedPath = this.serializePath(bipPath);
102
+ const pathResponse = await this.transport.send(CLA, INS.SIGN, P1_SIGN_PREPARED_TRANSACTION, P2_FIRST | P2_MORE, serializedPath);
103
+ this.checkTransportResponse(pathResponse);
104
+ // 2. Send the DAML transaction
105
+ await this.sendChunkedData({
106
+ ins: INS.SIGN,
107
+ p1: P1_SIGN_PREPARED_TRANSACTION,
108
+ payload: Buffer.from(components.damlTransaction),
109
+ isFinal: false,
110
+ });
111
+ // 3. Send each node
112
+ for (const [i, node] of components.nodes.entries()) {
113
+ this.validateUint8Array(node, `Node at index ${i}`);
114
+ await this.sendChunkedData({
115
+ ins: INS.SIGN,
116
+ p1: P1_SIGN_PREPARED_TRANSACTION,
117
+ payload: Buffer.from(node),
118
+ isFinal: false,
119
+ });
120
+ }
121
+ // 4. Send the metadata
122
+ const isFinal = components.inputContracts.length === 0;
123
+ const result = await this.sendChunkedData({
124
+ ins: INS.SIGN,
125
+ p1: P1_SIGN_PREPARED_TRANSACTION,
126
+ payload: Buffer.from(components.metadata),
127
+ isFinal,
128
+ });
129
+ if (isFinal) {
130
+ responseData = result;
131
+ }
132
+ // 5. Send each input contract - last one should return data
133
+ for (const [i, inputContract] of components.inputContracts.entries()) {
134
+ this.validateUint8Array(inputContract, `Input contract at index ${i}`);
135
+ const isFinal = i === components.inputContracts.length - 1;
136
+ const result = await this.sendChunkedData({
137
+ ins: INS.SIGN,
138
+ p1: P1_SIGN_PREPARED_TRANSACTION,
139
+ payload: Buffer.from(inputContract),
140
+ isFinal,
141
+ });
142
+ if (isFinal) {
143
+ responseData = result;
144
+ }
145
+ }
146
+ if (!responseData) {
147
+ throw new Error("No response data received from device");
148
+ }
149
+ return this.cleanSignatureFormat(responseData);
150
+ }
151
+ /**
152
+ * Sign topology transactions for Canton onboarding
153
+ * @private
154
+ */
155
+ async signUntypedVersionedMessage(path, data) {
156
+ const { transactions } = data;
157
+ if (!transactions || transactions.length === 0) {
158
+ throw new TypeError("At least one transaction is required");
159
+ }
160
+ // 1. Send the derivation path
161
+ const bipPath = BIPPath.fromString(path).toPathArray();
162
+ const serializedPath = this.serializePath(bipPath);
163
+ const pathResponse = await this.transport.send(CLA, INS.SIGN, P1_SIGN_UNTYPED_VERSIONED_MESSAGE, P2_FIRST | P2_MORE, serializedPath);
164
+ this.checkTransportResponse(pathResponse);
165
+ // 2. Send each transaction using chunking for large data
166
+ for (const [i, transaction] of transactions.entries()) {
167
+ if (!transaction) {
168
+ throw new TypeError(`Transaction at index ${i} is undefined or null`);
169
+ }
170
+ const transactionBuffer = Buffer.from(transaction, "hex");
171
+ const isLastTransaction = i === transactions.length - 1;
172
+ if (transactionBuffer.length <= MAX_APDU_DATA_LENGTH) {
173
+ // Small transaction - send directly
174
+ const p2 = isLastTransaction ? P2_MSG_END : P2_MORE | P2_MSG_END;
175
+ const response = await this.transport.send(CLA, INS.SIGN, P1_SIGN_UNTYPED_VERSIONED_MESSAGE, p2, transactionBuffer);
176
+ if (isLastTransaction) {
177
+ this.checkTransportResponse(response);
178
+ const responseData = this.extractResponseData(response);
179
+ return this.cleanSignatureFormat(responseData);
180
+ }
181
+ else {
182
+ this.checkTransportResponse(response);
183
+ }
184
+ }
185
+ else {
186
+ // Large transaction - use chunking
187
+ const responseData = await this.sendChunkedData({
188
+ ins: INS.SIGN,
189
+ p1: P1_SIGN_UNTYPED_VERSIONED_MESSAGE,
190
+ payload: transactionBuffer,
191
+ isFinal: isLastTransaction,
192
+ });
193
+ if (isLastTransaction && responseData) {
194
+ return this.cleanSignatureFormat(responseData);
195
+ }
196
+ }
197
+ }
198
+ throw new TypeError("No transactions provided");
74
199
  }
75
200
  /**
76
201
  * Get the app configuration.
@@ -78,46 +203,100 @@ export default class Canton {
78
203
  */
79
204
  async getAppConfiguration() {
80
205
  const response = await this.transport.send(CLA, INS.GET_VERSION, P1_NON_CONFIRM, P2_NONE, Buffer.alloc(0));
81
- const responseData = this.handleTransportResponse(response, "version");
206
+ this.checkTransportResponse(response);
207
+ const responseData = this.extractResponseData(response);
82
208
  const { major, minor, patch } = this.extractVersion(responseData);
83
209
  return {
84
210
  version: `${major}.${minor}.${patch}`,
85
211
  };
86
212
  }
213
+ /**
214
+ * Validate Uint8Array with descriptive error message
215
+ * @private
216
+ */
217
+ validateUint8Array(value, context) {
218
+ if (!value) {
219
+ throw new TypeError(`${context} is undefined or null`);
220
+ }
221
+ if (!(value instanceof Uint8Array)) {
222
+ throw new TypeError(`${context} is not a Uint8Array: ${typeof value}`);
223
+ }
224
+ }
225
+ /**
226
+ * Unified chunking strategy for sending data to device
227
+ * @private
228
+ */
229
+ async sendChunkedData({ ins, p1, payload, isFinal = false, }) {
230
+ const chunks = this.createChunks(payload);
231
+ let responseData = null;
232
+ for (let i = 0; i < chunks.length; i++) {
233
+ const isLastChunk = i === chunks.length - 1;
234
+ let p2 = P2_MORE;
235
+ if (isLastChunk) {
236
+ p2 = isFinal ? P2_MSG_END : P2_MORE | P2_MSG_END;
237
+ }
238
+ const response = await this.transport.send(CLA, ins, p1, p2, chunks[i]);
239
+ if (isFinal && isLastChunk) {
240
+ this.checkTransportResponse(response);
241
+ responseData = this.extractResponseData(response);
242
+ }
243
+ else {
244
+ this.checkTransportResponse(response);
245
+ }
246
+ }
247
+ return responseData;
248
+ }
249
+ /**
250
+ * Create optimized chunks from payload
251
+ * @private
252
+ */
253
+ createChunks(payload) {
254
+ if (payload.length <= MAX_APDU_DATA_LENGTH) {
255
+ return [payload];
256
+ }
257
+ const totalChunks = Math.ceil(payload.length / MAX_APDU_DATA_LENGTH);
258
+ const chunks = new Array(totalChunks);
259
+ let offset = 0;
260
+ for (let i = 0; i < totalChunks; i++) {
261
+ const chunkSize = Math.min(MAX_APDU_DATA_LENGTH, payload.length - offset);
262
+ chunks[i] = payload.slice(offset, offset + chunkSize);
263
+ offset += chunkSize;
264
+ }
265
+ return chunks;
266
+ }
87
267
  /**
88
268
  * Converts 65-byte Canton format to 64-byte Ed25519:
89
269
  * [40][64_bytes_signature][00] (132 hex chars)
90
270
  * @private
91
271
  */
92
272
  cleanSignatureFormat(signature) {
93
- if (signature.length === ED25519_SIGNATURE_HEX_LENGTH) {
94
- return signature;
273
+ const signatureHex = signature.toString("hex");
274
+ if (signatureHex.length === ED25519_SIGNATURE_HEX_LENGTH) {
275
+ return signatureHex;
95
276
  }
96
- if (signature.length === CANTON_SIGNATURE_HEX_LENGTH) {
97
- const cleanedSignature = signature.slice(2, -2);
277
+ if (signatureHex.length === CANTON_SIGNATURE_HEX_LENGTH) {
278
+ const cleanedSignature = signatureHex.slice(2, -2);
98
279
  return cleanedSignature;
99
280
  }
100
- console.warn(`[Canton]: Unknown signature format (${signature.length} chars)`);
101
- return signature;
281
+ return signatureHex;
102
282
  }
103
283
  /**
104
- * Helper method to handle transport response and check for errors
284
+ * Check transport response for errors and throw appropriate exceptions
105
285
  * @private
106
286
  */
107
- handleTransportResponse(response, errorType) {
287
+ checkTransportResponse(response) {
108
288
  const statusCode = response.readUInt16BE(response.length - 2);
109
- const responseData = response.slice(0, response.length - 2);
110
- if (statusCode === STATUS.USER_CANCEL) {
111
- switch (errorType) {
112
- case "address":
113
- throw new UserRefusedAddress();
114
- case "transaction":
115
- throw new UserRefusedOnDevice();
116
- default:
117
- throw new Error();
118
- }
289
+ if (statusCode !== STATUS.OK) {
290
+ throw new TransportStatusError(statusCode);
119
291
  }
120
- return responseData;
292
+ }
293
+ /**
294
+ * Extract response data from transport response
295
+ * APDU responses have format: [data][status_code(2_bytes)]
296
+ * @private
297
+ */
298
+ extractResponseData(response) {
299
+ return response.slice(0, -2);
121
300
  }
122
301
  /**
123
302
  * Serialize a BIP path to a data buffer for Canton BOLOS
@@ -172,9 +351,9 @@ export default class Canton {
172
351
  */
173
352
  extractVersion(data) {
174
353
  return {
175
- major: parseInt(data.subarray(0, 1).toString("hex"), 16),
176
- minor: parseInt(data.subarray(1, 2).toString("hex"), 16),
177
- patch: parseInt(data.subarray(2, 3).toString("hex"), 16),
354
+ major: Number.parseInt(data.subarray(0, 1).toString("hex"), 16),
355
+ minor: Number.parseInt(data.subarray(1, 2).toString("hex"), 16),
356
+ patch: Number.parseInt(data.subarray(2, 3).toString("hex"), 16),
178
357
  };
179
358
  }
180
359
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Canton.js","sourceRoot":"","sources":["../src/Canton.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Canton.js","sourceRoot":"","sources":["../src/Canton.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/hw-app-canton",
3
- "version": "0.6.0",
3
+ "version": "0.7.0-nightly.0",
4
4
  "description": "Ledger Hardware Wallet Canton Application API",
5
5
  "keywords": [
6
6
  "Ledger",
@@ -26,8 +26,8 @@
26
26
  "license": "Apache-2.0",
27
27
  "dependencies": {
28
28
  "bip32-path": "^0.4.2",
29
- "@ledgerhq/errors": "^6.26.0",
30
- "@ledgerhq/hw-transport": "6.31.12"
29
+ "@ledgerhq/errors": "^6.27.0-nightly.0",
30
+ "@ledgerhq/hw-transport": "6.31.13-nightly.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/jest": "^29.5.10",
@@ -38,8 +38,8 @@
38
38
  "source-map-support": "^0.5.21",
39
39
  "ts-jest": "^29.1.1",
40
40
  "ts-node": "^10.4.0",
41
- "@ledgerhq/hw-transport-mocker": "^6.29.12",
42
- "@ledgerhq/hw-transport-node-speculos-http": "^6.30.2"
41
+ "@ledgerhq/hw-transport-mocker": "^6.29.13-nightly.0",
42
+ "@ledgerhq/hw-transport-node-speculos-http": "^6.31.0-nightly.1"
43
43
  },
44
44
  "scripts": {
45
45
  "clean": "rimraf lib lib-es",
@@ -1,6 +1,9 @@
1
1
  import { openTransportReplayer, RecordStore } from "@ledgerhq/hw-transport-mocker";
2
+ import { TransportStatusError } from "@ledgerhq/errors";
2
3
  import Canton from "./Canton";
3
4
 
5
+ const PATH = "44'/6767'/0'/0'/0'";
6
+
4
7
  describe("Canton", () => {
5
8
  describe("decorateAppAPIMethods", () => {
6
9
  it("should properly decorate transport methods", async () => {
@@ -30,12 +33,12 @@ describe("Canton", () => {
30
33
  const canton = new Canton(transport);
31
34
 
32
35
  // WHEN
33
- const result = await canton.getAddress("44'/6767'/0'/0'/0'");
36
+ const result = await canton.getAddress(PATH);
34
37
 
35
38
  // THEN
36
39
  expect(result).toEqual({
37
40
  address: "canton_402f2e68",
38
- path: "44'/6767'/0'/0'/0'",
41
+ path: PATH,
39
42
  publicKey: "c59f7f29374d24506dd6490a5db472cf00958e195e146f3dc9c97f96d5c51097",
40
43
  });
41
44
  });
@@ -51,12 +54,12 @@ describe("Canton", () => {
51
54
  const canton = new Canton(transport);
52
55
 
53
56
  // WHEN
54
- const result = await canton.getAddress("44'/6767'/0'/0'/0'", true);
57
+ const result = await canton.getAddress(PATH, true);
55
58
 
56
59
  // THEN
57
60
  expect(result).toEqual({
58
61
  address: "canton_402f2e68",
59
- path: "44'/6767'/0'/0'/0'",
62
+ path: PATH,
60
63
  publicKey: "c59f7f29374d24506dd6490a5db472cf00958e195e146f3dc9c97f96d5c51097",
61
64
  });
62
65
  });
@@ -67,55 +70,74 @@ describe("Canton", () => {
67
70
  const canton = new Canton(transport);
68
71
 
69
72
  // WHEN & THEN
70
- return expect(canton.getAddress("invalid path")).rejects.toThrow();
73
+ await expect(canton.getAddress("invalid-path")).rejects.toThrow();
71
74
  });
72
75
 
73
- it("should handle various derivation paths", async () => {
76
+ it("should handle user refused address", async () => {
74
77
  // GIVEN
75
78
  const transport = await openTransportReplayer(
76
79
  RecordStore.fromString(`
77
- => e005000015058000002c80001a6f800000008000000080000001
78
- <= 205e66a10773c0860e73bb6015947806555765df5f9b5b4636df4255a57c57d702205e66a10773c0860e73bb6015947806555765df5f9b5b4636df4255a57c57d7029000
80
+ => e005010015058000002c80001a6f800000008000000080000000
81
+ <= 6985
79
82
  `),
80
83
  );
81
84
  const canton = new Canton(transport);
82
85
 
83
- // WHEN
84
- const result = await canton.getAddress("44'/6767'/0'/0'/1'");
85
-
86
- // THEN
87
- expect(result).toBeDefined();
88
- expect(result.address).toBeDefined();
89
- expect(result.publicKey).toBeDefined();
86
+ // WHEN & THEN
87
+ await expect(canton.getAddress(PATH, true)).rejects.toThrow(new TransportStatusError(0x6985));
90
88
  });
91
-
92
- // should handle user refused address
93
89
  });
94
90
 
95
91
  describe("signTransaction", () => {
96
- // should sign transaction
97
-
98
- // should handle large transaction payloads
92
+ it("should sign untyped versioned message", async () => {
93
+ // GIVEN
94
+ const transport = await openTransportReplayer(
95
+ RecordStore.fromString(`
96
+ => e006010315058000002c80001a6f800000008000000080000000
97
+ <= 9000
98
+ => e006010420d1e98829444207b0e170346b2e80b58a2ffc602b01e190fb742016d407c84efd
99
+ <= 40a65f53c3657bc04efefb67a425ba093a5cb5391d18142f148bb2c48daacf316114cff920a58d5996ca828c7ce265f537f1d7fca8fa82c3c73bd944a96e701a00009000
100
+ `),
101
+ );
102
+ const canton = new Canton(transport);
103
+ const data = {
104
+ transactions: ["d1e98829444207b0e170346b2e80b58a2ffc602b01e190fb742016d407c84efd"],
105
+ };
99
106
 
100
- // should handle empty transaction
107
+ // WHEN
108
+ const result = await canton.signTransaction(PATH, data);
101
109
 
102
- // should request blind signature when required
110
+ // THEN
111
+ expect(result).toEqual(
112
+ "a65f53c3657bc04efefb67a425ba093a5cb5391d18142f148bb2c48daacf316114cff920a58d5996ca828c7ce265f537f1d7fca8fa82c3c73bd944a96e701a00",
113
+ );
114
+ });
103
115
 
104
- it("should sign transaction hash", async () => {
116
+ it("should sign large untyped versioned message with chunking", async () => {
105
117
  // GIVEN
118
+ const largeTransaction =
119
+ "d1e98829444207b0e170346b2e80b58a2ffc602b01e190fb742016d407c84efd".repeat(10);
120
+
121
+ const firstChunk = largeTransaction.substring(0, 510);
122
+ const secondChunk = largeTransaction.substring(510, 640);
123
+
106
124
  const transport = await openTransportReplayer(
107
125
  RecordStore.fromString(`
108
- => e006000315058000002c80001a6f800000008000000080000000
109
- <= 9000
110
- => e006000420d1e98829444207b0e170346b2e80b58a2ffc602b01e190fb742016d407c84efd
111
- <= 40a65f53c3657bc04efefb67a425ba093a5cb5391d18142f148bb2c48daacf316114cff920a58d5996ca828c7ce265f537f1d7fca8fa82c3c73bd944a96e701a00009000
112
- `),
126
+ => e006010315058000002c80001a6f800000008000000080000000
127
+ <= 9000
128
+ => e0060102ff${firstChunk}
129
+ <= 9000
130
+ => e006010441${secondChunk}
131
+ <= 40a65f53c3657bc04efefb67a425ba093a5cb5391d18142f148bb2c48daacf316114cff920a58d5996ca828c7ce265f537f1d7fca8fa82c3c73bd944a96e701a00009000
132
+ `),
113
133
  );
114
134
  const canton = new Canton(transport);
115
- const txHash = "d1e98829444207b0e170346b2e80b58a2ffc602b01e190fb742016d407c84efd";
135
+ const data = {
136
+ transactions: [largeTransaction],
137
+ };
116
138
 
117
139
  // WHEN
118
- const result = await canton.signTransaction("44'/6767'/0'/0'/0'", txHash);
140
+ const result = await canton.signTransaction(PATH, data);
119
141
 
120
142
  // THEN
121
143
  expect(result).toEqual(
@@ -123,18 +145,77 @@ describe("Canton", () => {
123
145
  );
124
146
  });
125
147
 
126
- it("should handle user refused transaction", async () => {
148
+ it("should sign prepared transaction", async () => {
127
149
  // GIVEN
128
150
  const transport = await openTransportReplayer(
129
151
  RecordStore.fromString(`
130
- => e006010015058000002c80001a6f800000008000000080000000
131
- <= 6985
152
+ => e006020315058000002c80001a6f800000008000000080000000
153
+ <= 9000
154
+ => e0060202ff${"1234567890abcdef".repeat(31)}1234567890abcd
155
+ <= 9000
156
+ => e006020608ef1234567890abcd
157
+ <= 9000
158
+ => e0060202ff${"1234567890abcdef".repeat(31)}1234567890abcd
159
+ <= 9000
160
+ => e006020608ef1234567890abcd
161
+ <= 9000
162
+ => e0060202ff${"1234567890abcdef".repeat(31)}1234567890abcd
163
+ <= 9000
164
+ => e006020608ef1234567890abcd
165
+ <= 9000
166
+ => e0060202ff${"1234567890abcdef".repeat(31)}1234567890abcd
167
+ <= 9000
168
+ => e006020408ef1234567890abcd
169
+ <= 40a65f53c3657bc04efefb67a425ba093a5cb5391d18142f148bb2c48daacf316114cff920a58d5996ca828c7ce265f537f1d7fca8fa82c3c73bd944a96e701a009000
132
170
  `),
133
171
  );
134
172
  const canton = new Canton(transport);
135
173
 
136
- // WHEN & THEN
137
- return expect(canton.signTransaction("44'/6767'/0'/0'/0'", "test")).rejects.toThrow();
174
+ const testData = "1234567890abcdef".repeat(31) + "1234567890abcdef1234567890abcd";
175
+ const components = {
176
+ damlTransaction: Buffer.from(testData, "hex"),
177
+ nodes: [Buffer.from(testData, "hex")],
178
+ metadata: Buffer.from(testData, "hex"),
179
+ inputContracts: [Buffer.from(testData, "hex")],
180
+ };
181
+
182
+ // WHEN
183
+ const result = await canton.signTransaction(PATH, components);
184
+
185
+ // THEN
186
+ expect(result).toEqual(
187
+ "40a65f53c3657bc04efefb67a425ba093a5cb5391d18142f148bb2c48daacf316114cff920a58d5996ca828c7ce265f537f1d7fca8fa82c3c73bd944a96e701a00",
188
+ );
189
+ });
190
+
191
+ describe("error handling", () => {
192
+ it("should handle user refused transaction", async () => {
193
+ // GIVEN
194
+ const transport = await openTransportReplayer(
195
+ RecordStore.fromString(`
196
+ => e006010315058000002c80001a6f800000008000000080000000
197
+ <= 6985
198
+ `),
199
+ );
200
+ const canton = new Canton(transport);
201
+ const data = {
202
+ transactions: ["test"],
203
+ };
204
+
205
+ // WHEN & THEN
206
+ await expect(canton.signTransaction(PATH, data)).rejects.toThrow(
207
+ new TransportStatusError(0x6985),
208
+ );
209
+ });
210
+
211
+ it("should handle invalid transaction data", async () => {
212
+ // GIVEN
213
+ const transport = await openTransportReplayer(new RecordStore());
214
+ const canton = new Canton(transport);
215
+
216
+ // WHEN & THEN
217
+ await expect(canton.signTransaction(PATH, null as any)).rejects.toThrow();
218
+ });
138
219
  });
139
220
  });
140
221
 
@@ -144,7 +225,7 @@ describe("Canton", () => {
144
225
  const transport = await openTransportReplayer(
145
226
  RecordStore.fromString(`
146
227
  => e003000000
147
- <= 0202029000
228
+ <= 0101009000
148
229
  `),
149
230
  );
150
231
  const canton = new Canton(transport);
@@ -154,10 +235,8 @@ describe("Canton", () => {
154
235
 
155
236
  // THEN
156
237
  expect(result).toEqual({
157
- version: "2.2.2",
238
+ version: "1.1.0",
158
239
  });
159
240
  });
160
-
161
- // should handle configuration error
162
241
  });
163
242
  });