@ledgerhq/coin-canton 0.9.0-nightly.1 → 0.9.0-nightly.2
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/CHANGELOG.md +16 -0
- 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/onboard.d.ts.map +1 -1
- package/lib/bridge/onboard.js +48 -22
- package/lib/bridge/onboard.js.map +1 -1
- package/lib/bridge/signOperation.d.ts.map +1 -1
- package/lib/bridge/signOperation.js +10 -3
- package/lib/bridge/signOperation.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/sign.d.ts +8 -0
- package/lib/common-logic/transaction/sign.d.ts.map +1 -0
- package/lib/common-logic/transaction/sign.js +27 -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 +1 -0
- package/lib/network/gateway.d.ts.map +1 -1
- package/lib/network/gateway.js +2 -7
- 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/types/signer.d.ts +10 -1
- 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/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/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/signOperation.js +10 -3
- package/lib-es/bridge/signOperation.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/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 +24 -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 +1 -0
- package/lib-es/network/gateway.d.ts.map +1 -1
- package/lib-es/network/gateway.js +1 -8
- 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/types/signer.d.ts +10 -1
- package/lib-es/types/signer.d.ts.map +1 -1
- package/lib-es/types/transaction-proto.json +1238 -0
- package/package.json +10 -7
- package/scripts/generate.js +261 -0
- package/src/bridge/deviceTransactionConfig.test.ts +14 -10
- package/src/bridge/deviceTransactionConfig.ts +2 -2
- package/src/bridge/getTransactionStatus.test.ts +19 -19
- package/src/bridge/onboard.integ.test.ts +0 -20
- package/src/bridge/onboard.ts +57 -33
- package/src/bridge/signOperation.test.ts +114 -0
- package/src/bridge/signOperation.ts +12 -5
- package/src/bridge/sync.integ.test.ts +157 -132
- package/src/common-logic/index.ts +1 -0
- package/src/common-logic/transaction/sign.test.ts +317 -0
- package/src/common-logic/transaction/sign.ts +33 -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 +2 -0
- package/src/network/gateway.ts +3 -8
- package/src/test/cantonTestUtils.ts +789 -24
- package/src/test/prepare-transfer-serialized.json +26 -0
- package/src/test/prepare-transfer.json +3298 -0
- package/src/types/signer.ts +17 -3
- package/src/types/transaction-proto.json +1238 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/coin-canton",
|
|
3
|
-
"version": "0.9.0-nightly.
|
|
3
|
+
"version": "0.9.0-nightly.2",
|
|
4
4
|
"description": "Canton coin integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ledger",
|
|
@@ -100,15 +100,16 @@
|
|
|
100
100
|
"dependencies": {
|
|
101
101
|
"bignumber.js": "^9.1.2",
|
|
102
102
|
"invariant": "^2.2.4",
|
|
103
|
+
"protobufjs": "7.5.4",
|
|
103
104
|
"rxjs": "^7.8.1",
|
|
104
|
-
"@ledgerhq/
|
|
105
|
-
"@ledgerhq/
|
|
105
|
+
"@ledgerhq/cryptoassets": "^13.32.0-nightly.1",
|
|
106
|
+
"@ledgerhq/coin-framework": "^6.8.0-nightly.2",
|
|
106
107
|
"@ledgerhq/devices": "8.6.2-nightly.0",
|
|
107
108
|
"@ledgerhq/errors": "^6.27.0-nightly.0",
|
|
108
109
|
"@ledgerhq/live-env": "^2.19.0",
|
|
109
|
-
"@ledgerhq/live-network": "^2.0.
|
|
110
|
+
"@ledgerhq/live-network": "^2.1.0-nightly.0",
|
|
110
111
|
"@ledgerhq/logs": "^6.13.0",
|
|
111
|
-
"@ledgerhq/types-live": "^6.88.0-nightly.
|
|
112
|
+
"@ledgerhq/types-live": "^6.88.0-nightly.1"
|
|
112
113
|
},
|
|
113
114
|
"devDependencies": {
|
|
114
115
|
"@types/invariant": "^2.2.37",
|
|
@@ -116,13 +117,15 @@
|
|
|
116
117
|
"dotenv": "^16.4.5",
|
|
117
118
|
"expect": "^27.4.6",
|
|
118
119
|
"jest": "^29.7.0",
|
|
120
|
+
"protobufjs-cli": "1.1.2",
|
|
119
121
|
"ts-jest": "^29.1.1",
|
|
120
122
|
"typescript": "^5.4.5",
|
|
121
|
-
"@ledgerhq/
|
|
122
|
-
"@ledgerhq/
|
|
123
|
+
"@ledgerhq/disable-network-setup": "^0.1.0-nightly.0",
|
|
124
|
+
"@ledgerhq/types-cryptoassets": "^7.29.0"
|
|
123
125
|
},
|
|
124
126
|
"scripts": {
|
|
125
127
|
"clean": "rimraf lib lib-es",
|
|
128
|
+
"generate-proto": "node scripts/generate.js",
|
|
126
129
|
"build": "tsc && tsc -m esnext --moduleResolution bundler --outDir lib-es",
|
|
127
130
|
"coverage": "jest --coverage",
|
|
128
131
|
"prewatch": "pnpm build",
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* eslint @typescript-eslint/no-var-requires: off */
|
|
3
|
+
/* eslint no-console: off */
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { execSync } from "node:child_process";
|
|
7
|
+
import https from "node:https";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
|
|
13
|
+
const outputFile = path.join(__dirname, "../src/types/transaction-proto.json");
|
|
14
|
+
const tempDir = path.join(__dirname, "temp-proto");
|
|
15
|
+
|
|
16
|
+
const APP_CANTON_REPO = "LedgerHQ/app-canton";
|
|
17
|
+
const APP_CANTON_BRANCH = "develop";
|
|
18
|
+
const APP_CANTON_BASE_URL = `https://raw.githubusercontent.com/${APP_CANTON_REPO}/${APP_CANTON_BRANCH}`;
|
|
19
|
+
|
|
20
|
+
const DAML_REPO = "digital-asset/daml";
|
|
21
|
+
const DAML_BRANCH = "main";
|
|
22
|
+
const DAML_BASE_URL = `https://raw.githubusercontent.com/${DAML_REPO}/${DAML_BRANCH}`;
|
|
23
|
+
|
|
24
|
+
const RESERVED_WORDS = [
|
|
25
|
+
{ pattern: /\bbool bool\b/g, replacement: "bool bool_" },
|
|
26
|
+
{ pattern: /\bEnum enum\b/g, replacement: "Enum enum_" },
|
|
27
|
+
{ pattern: /\bstring constructor = (\d+);/g, replacement: "string constructor_ = $1;" },
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
function handleFileFinish(file, resolve) {
|
|
31
|
+
file.close();
|
|
32
|
+
resolve();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function handleFileError(filePath, reject) {
|
|
36
|
+
return err => {
|
|
37
|
+
fs.unlink(filePath, () => {
|
|
38
|
+
/* empty function */
|
|
39
|
+
});
|
|
40
|
+
reject(err);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function handleHttpResponse(url, file, filePath, resolve, reject) {
|
|
45
|
+
return response => {
|
|
46
|
+
if (response.statusCode !== 200) {
|
|
47
|
+
reject(new Error(`Failed to download ${url}: ${response.statusCode}`));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
response.pipe(file);
|
|
52
|
+
|
|
53
|
+
file.on("finish", () => handleFileFinish(file, resolve));
|
|
54
|
+
file.on("error", handleFileError(filePath, reject));
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function downloadFile(url, filePath) {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
const file = fs.createWriteStream(filePath);
|
|
61
|
+
|
|
62
|
+
https.get(url, handleHttpResponse(url, file, filePath, resolve, reject)).on("error", err => {
|
|
63
|
+
reject(err instanceof Error ? err : new Error(err));
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const PROTO_FILES = [
|
|
69
|
+
{
|
|
70
|
+
repoPath: "proto/device.proto",
|
|
71
|
+
localPath: "device.proto",
|
|
72
|
+
source: "app-canton",
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
repoPath: "proto/com/daml/ledger/api/v2/value.proto",
|
|
76
|
+
localPath: "com/daml/ledger/api/v2/value.proto",
|
|
77
|
+
source: "app-canton",
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
repoPath: "proto/com/daml/ledger/api/v2/value_cb.proto",
|
|
81
|
+
localPath: "com/daml/ledger/api/v2/value_cb.proto",
|
|
82
|
+
source: "app-canton",
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
repoPath:
|
|
86
|
+
"sdk/canton/community/ledger-api/src/main/protobuf/com/daml/ledger/api/v2/interactive/interactive_submission_common_data.proto",
|
|
87
|
+
localPath: "com/daml/ledger/api/v2/interactive/interactive_submission_common_data.proto",
|
|
88
|
+
source: "daml",
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
repoPath:
|
|
92
|
+
"sdk/canton/community/ledger-api/src/main/protobuf/com/daml/ledger/api/v2/interactive/transaction/v1/interactive_submission_data.proto",
|
|
93
|
+
localPath:
|
|
94
|
+
"com/daml/ledger/api/v2/interactive/transaction/v1/interactive_submission_data.proto",
|
|
95
|
+
source: "daml",
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
repoPath: "proto/interactive_submission_data_cb.proto",
|
|
99
|
+
localPath:
|
|
100
|
+
"com/daml/ledger/api/v2/interactive/transaction/v1/interactive_submission_data_cb.proto",
|
|
101
|
+
source: "app-canton",
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
repoPath: "proto/google/protobuf/any.proto",
|
|
105
|
+
localPath: "google/protobuf/any.proto",
|
|
106
|
+
source: "app-canton",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
repoPath: "proto/google/protobuf/duration.proto",
|
|
110
|
+
localPath: "google/protobuf/duration.proto",
|
|
111
|
+
source: "app-canton",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
repoPath: "proto/google/protobuf/empty.proto",
|
|
115
|
+
localPath: "google/protobuf/empty.proto",
|
|
116
|
+
source: "app-canton",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
repoPath: "proto/google/protobuf/timestamp.proto",
|
|
120
|
+
localPath: "google/protobuf/timestamp.proto",
|
|
121
|
+
source: "app-canton",
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
repoPath: "proto/google/rpc/error_details.proto",
|
|
125
|
+
localPath: "google/rpc/error_details.proto",
|
|
126
|
+
source: "app-canton",
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
repoPath: "proto/google/rpc/status.proto",
|
|
130
|
+
localPath: "google/rpc/status.proto",
|
|
131
|
+
source: "app-canton",
|
|
132
|
+
},
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
function ensureDirectoryExists(dirPath) {
|
|
136
|
+
if (!fs.existsSync(dirPath)) {
|
|
137
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function getDownloadUrl(protoFile) {
|
|
142
|
+
const baseUrl = protoFile.source === "daml" ? DAML_BASE_URL : APP_CANTON_BASE_URL;
|
|
143
|
+
return `${baseUrl}/${protoFile.repoPath}`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function downloadProtoFile(protoFile) {
|
|
147
|
+
const url = getDownloadUrl(protoFile);
|
|
148
|
+
const localPath = path.join(tempDir, protoFile.localPath);
|
|
149
|
+
|
|
150
|
+
ensureDirectoryExists(path.dirname(localPath));
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
await downloadFile(url, localPath);
|
|
154
|
+
console.log(`Downloaded: ${protoFile.localPath}`);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error(`Failed to download ${protoFile.localPath}:`, error.message);
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function downloadProtoFiles() {
|
|
162
|
+
console.log("Downloading proto files from...");
|
|
163
|
+
|
|
164
|
+
if (!fs.existsSync(tempDir)) {
|
|
165
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
for (const protoFile of PROTO_FILES) {
|
|
169
|
+
await downloadProtoFile(protoFile);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
console.log("All proto files downloaded successfully!");
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Replace reserved words to make sure only C allowed names are used
|
|
176
|
+
// see https://github.com/LedgerHQ/app-canton/blob/develop/proto/proto_gen.sh#L257
|
|
177
|
+
function replaceReservedWords(filePath) {
|
|
178
|
+
if (!fs.existsSync(filePath)) return;
|
|
179
|
+
|
|
180
|
+
let content = fs.readFileSync(filePath, "utf8");
|
|
181
|
+
|
|
182
|
+
for (const { pattern, replacement } of RESERVED_WORDS) {
|
|
183
|
+
content = content.replace(pattern, replacement);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
fs.writeFileSync(filePath, content);
|
|
187
|
+
console.log(`Updated field names in ${path.basename(filePath)}`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Clean up temp directory
|
|
191
|
+
function cleanup() {
|
|
192
|
+
if (fs.existsSync(tempDir)) {
|
|
193
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
194
|
+
console.log("Cleaned up temporary files");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function processProtoFiles() {
|
|
199
|
+
// Replace field names in proto files
|
|
200
|
+
replaceReservedWords(path.join(tempDir, "com/daml/ledger/api/v2/value.proto"));
|
|
201
|
+
replaceReservedWords(path.join(tempDir, "com/daml/ledger/api/v2/value_cb.proto"));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function generateProtobufBindings() {
|
|
205
|
+
// Sanitize paths to prevent command injection
|
|
206
|
+
const sanitizedTempDir = path.resolve(tempDir);
|
|
207
|
+
const sanitizedOutputFile = path.resolve(outputFile);
|
|
208
|
+
const deviceProtoPath = path.join(sanitizedTempDir, "device.proto");
|
|
209
|
+
|
|
210
|
+
// Validate that paths exist and are within expected directories
|
|
211
|
+
if (!fs.existsSync(deviceProtoPath)) {
|
|
212
|
+
throw new Error(`Device proto file not found: ${deviceProtoPath}`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (!sanitizedTempDir.startsWith(path.resolve(__dirname))) {
|
|
216
|
+
throw new Error("Invalid temp directory path");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (!sanitizedOutputFile.startsWith(path.resolve(__dirname, ".."))) {
|
|
220
|
+
throw new Error("Invalid output file path");
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Use npx from the same Node.js installation directory to avoid PATH manipulation
|
|
224
|
+
const npxPath = path.join(process.execPath, "..", "npx");
|
|
225
|
+
const absoluteNpxPath = path.resolve(npxPath);
|
|
226
|
+
|
|
227
|
+
execSync(
|
|
228
|
+
absoluteNpxPath,
|
|
229
|
+
[
|
|
230
|
+
"pbjs",
|
|
231
|
+
"-t",
|
|
232
|
+
"json",
|
|
233
|
+
"-w",
|
|
234
|
+
"es6",
|
|
235
|
+
"--path",
|
|
236
|
+
sanitizedTempDir,
|
|
237
|
+
"-o",
|
|
238
|
+
sanitizedOutputFile,
|
|
239
|
+
deviceProtoPath,
|
|
240
|
+
],
|
|
241
|
+
{
|
|
242
|
+
stdio: "inherit",
|
|
243
|
+
cwd: __dirname,
|
|
244
|
+
},
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
console.log("Generating protobuf bindings...");
|
|
250
|
+
|
|
251
|
+
await downloadProtoFiles();
|
|
252
|
+
processProtoFiles();
|
|
253
|
+
generateProtobufBindings();
|
|
254
|
+
|
|
255
|
+
console.log("Protobuf bindings generated successfully!");
|
|
256
|
+
} catch (error) {
|
|
257
|
+
console.error("Error generating protobuf bindings:", error.message);
|
|
258
|
+
process.exit(1);
|
|
259
|
+
} finally {
|
|
260
|
+
cleanup();
|
|
261
|
+
}
|
|
@@ -2,21 +2,25 @@ import getDeviceTransactionConfig from "./deviceTransactionConfig";
|
|
|
2
2
|
import BigNumber from "bignumber.js";
|
|
3
3
|
|
|
4
4
|
describe("getDeviceTransactionConfig", () => {
|
|
5
|
-
it("should return amount field when it's more than 0", () => {
|
|
5
|
+
it("should return amount field when it's more than 0", async () => {
|
|
6
6
|
expect(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
(
|
|
8
|
+
await getDeviceTransactionConfig({
|
|
9
|
+
transaction: {},
|
|
10
|
+
status: { amount: new BigNumber(1), estimatedFees: new BigNumber(0) },
|
|
11
|
+
} as any)
|
|
12
|
+
)[0],
|
|
11
13
|
).toEqual({ type: "amount", label: "Amount" });
|
|
12
14
|
});
|
|
13
15
|
|
|
14
|
-
it("should return fee field when it's more than 0", () => {
|
|
16
|
+
it("should return fee field when it's more than 0", async () => {
|
|
15
17
|
expect(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
(
|
|
19
|
+
await getDeviceTransactionConfig({
|
|
20
|
+
transaction: {},
|
|
21
|
+
status: { amount: new BigNumber(0), estimatedFees: new BigNumber(1) },
|
|
22
|
+
} as any)
|
|
23
|
+
)[0],
|
|
20
24
|
).toEqual({ type: "fees", label: "Fees" });
|
|
21
25
|
});
|
|
22
26
|
});
|
|
@@ -3,7 +3,7 @@ import type { Transaction, TransactionStatus } from "../types";
|
|
|
3
3
|
import type { CommonDeviceTransactionField } from "@ledgerhq/coin-framework/transaction/common";
|
|
4
4
|
|
|
5
5
|
// This method adds additional fields that need to be reviewed when signing a transaction on the device.
|
|
6
|
-
function getDeviceTransactionConfig({
|
|
6
|
+
async function getDeviceTransactionConfig({
|
|
7
7
|
transaction: {},
|
|
8
8
|
status: { amount, estimatedFees },
|
|
9
9
|
}: {
|
|
@@ -11,7 +11,7 @@ function getDeviceTransactionConfig({
|
|
|
11
11
|
parentAccount: Account | null | undefined;
|
|
12
12
|
transaction: Transaction;
|
|
13
13
|
status: TransactionStatus;
|
|
14
|
-
}): Array<CommonDeviceTransactionField
|
|
14
|
+
}): Promise<Array<CommonDeviceTransactionField>> {
|
|
15
15
|
const fields: Array<CommonDeviceTransactionField> = [];
|
|
16
16
|
|
|
17
17
|
if (!amount.isZero()) {
|
|
@@ -56,7 +56,7 @@ describe("getTransactionStatus", () => {
|
|
|
56
56
|
currency: mockCurrency,
|
|
57
57
|
balance: new BigNumber(1000), // 1000 units
|
|
58
58
|
spendableBalance: new BigNumber(1000),
|
|
59
|
-
freshAddress: "test::
|
|
59
|
+
freshAddress: "test::33333333333333333333333333333333333333333333333333333333333333333333",
|
|
60
60
|
freshAddressPath: "44'/60'/0'/0/0",
|
|
61
61
|
index: 0,
|
|
62
62
|
derivationMode: "canton",
|
|
@@ -93,7 +93,7 @@ describe("getTransactionStatus", () => {
|
|
|
93
93
|
const transaction: Transaction = {
|
|
94
94
|
family: "canton",
|
|
95
95
|
amount: new BigNumber(100),
|
|
96
|
-
recipient: "valid::
|
|
96
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
97
97
|
fee: null,
|
|
98
98
|
tokenId: "",
|
|
99
99
|
};
|
|
@@ -108,7 +108,7 @@ describe("getTransactionStatus", () => {
|
|
|
108
108
|
const transaction: Transaction = {
|
|
109
109
|
family: "canton",
|
|
110
110
|
amount: new BigNumber(100),
|
|
111
|
-
recipient: "valid::
|
|
111
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
112
112
|
fee: new BigNumber(0),
|
|
113
113
|
tokenId: "",
|
|
114
114
|
};
|
|
@@ -123,7 +123,7 @@ describe("getTransactionStatus", () => {
|
|
|
123
123
|
const transaction: Transaction = {
|
|
124
124
|
family: "canton",
|
|
125
125
|
amount: new BigNumber(100), // Use larger amount to avoid balance issues
|
|
126
|
-
recipient: "valid::
|
|
126
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
127
127
|
fee: new BigNumber(1500), // 15x the amount
|
|
128
128
|
tokenId: "",
|
|
129
129
|
};
|
|
@@ -138,7 +138,7 @@ describe("getTransactionStatus", () => {
|
|
|
138
138
|
const transaction: Transaction = {
|
|
139
139
|
family: "canton",
|
|
140
140
|
amount: new BigNumber(100),
|
|
141
|
-
recipient: "valid::
|
|
141
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
142
142
|
fee: new BigNumber(10), // 0.1x the amount
|
|
143
143
|
tokenId: "",
|
|
144
144
|
};
|
|
@@ -155,7 +155,7 @@ describe("getTransactionStatus", () => {
|
|
|
155
155
|
const transaction: Transaction = {
|
|
156
156
|
family: "canton",
|
|
157
157
|
amount: new BigNumber(950), // 950 + 10 fee = 960, but balance is 1000 and reserve is 100
|
|
158
|
-
recipient: "valid::
|
|
158
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
159
159
|
fee: new BigNumber(10),
|
|
160
160
|
tokenId: "",
|
|
161
161
|
};
|
|
@@ -169,7 +169,7 @@ describe("getTransactionStatus", () => {
|
|
|
169
169
|
const transaction: Transaction = {
|
|
170
170
|
family: "canton",
|
|
171
171
|
amount: new BigNumber(50), // Below reserve amount of 100
|
|
172
|
-
recipient: "valid::
|
|
172
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
173
173
|
fee: new BigNumber(10),
|
|
174
174
|
tokenId: "",
|
|
175
175
|
};
|
|
@@ -183,7 +183,7 @@ describe("getTransactionStatus", () => {
|
|
|
183
183
|
const transaction: Transaction = {
|
|
184
184
|
family: "canton",
|
|
185
185
|
amount: new BigNumber(800), // 800 + 10 fee = 810, balance is 1000, reserve is 100, so 900 available
|
|
186
|
-
recipient: "valid::
|
|
186
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
187
187
|
fee: new BigNumber(10),
|
|
188
188
|
tokenId: "",
|
|
189
189
|
};
|
|
@@ -213,7 +213,7 @@ describe("getTransactionStatus", () => {
|
|
|
213
213
|
const transaction: Transaction = {
|
|
214
214
|
family: "canton",
|
|
215
215
|
amount: new BigNumber(100),
|
|
216
|
-
recipient: "test::
|
|
216
|
+
recipient: "test::33333333333333333333333333333333333333333333333333333333333333333333", // Same as account.freshAddress
|
|
217
217
|
fee: new BigNumber(10),
|
|
218
218
|
tokenId: "",
|
|
219
219
|
};
|
|
@@ -241,7 +241,7 @@ describe("getTransactionStatus", () => {
|
|
|
241
241
|
const transaction: Transaction = {
|
|
242
242
|
family: "canton",
|
|
243
243
|
amount: new BigNumber(100),
|
|
244
|
-
recipient: "valid::
|
|
244
|
+
recipient: "valid::22222222222222222222222222222222222222222222222222222222222222222222",
|
|
245
245
|
fee: new BigNumber(10),
|
|
246
246
|
tokenId: "",
|
|
247
247
|
};
|
|
@@ -272,7 +272,7 @@ describe("getTransactionStatus", () => {
|
|
|
272
272
|
const transaction: Transaction = {
|
|
273
273
|
family: "canton",
|
|
274
274
|
amount: new BigNumber(0),
|
|
275
|
-
recipient: "valid::
|
|
275
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
276
276
|
fee: new BigNumber(10),
|
|
277
277
|
tokenId: "",
|
|
278
278
|
};
|
|
@@ -286,7 +286,7 @@ describe("getTransactionStatus", () => {
|
|
|
286
286
|
const transaction: Transaction = {
|
|
287
287
|
family: "canton",
|
|
288
288
|
amount: new BigNumber(100),
|
|
289
|
-
recipient: "valid::
|
|
289
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
290
290
|
fee: new BigNumber(10),
|
|
291
291
|
tokenId: "",
|
|
292
292
|
};
|
|
@@ -302,7 +302,7 @@ describe("getTransactionStatus", () => {
|
|
|
302
302
|
const transaction: Transaction = {
|
|
303
303
|
family: "canton",
|
|
304
304
|
amount: new BigNumber(100),
|
|
305
|
-
recipient: "valid::
|
|
305
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
306
306
|
fee: new BigNumber(10),
|
|
307
307
|
tokenId: "",
|
|
308
308
|
};
|
|
@@ -318,7 +318,7 @@ describe("getTransactionStatus", () => {
|
|
|
318
318
|
const transaction: Transaction = {
|
|
319
319
|
family: "canton",
|
|
320
320
|
amount: new BigNumber(100),
|
|
321
|
-
recipient: "valid::
|
|
321
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
322
322
|
fee: new BigNumber(10),
|
|
323
323
|
tokenId: "",
|
|
324
324
|
};
|
|
@@ -340,7 +340,7 @@ describe("getTransactionStatus", () => {
|
|
|
340
340
|
const transaction: Transaction = {
|
|
341
341
|
family: "canton",
|
|
342
342
|
amount: new BigNumber(50),
|
|
343
|
-
recipient: "valid::
|
|
343
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
344
344
|
fee: new BigNumber(10),
|
|
345
345
|
tokenId: "",
|
|
346
346
|
};
|
|
@@ -359,7 +359,7 @@ describe("getTransactionStatus", () => {
|
|
|
359
359
|
const transaction: Transaction = {
|
|
360
360
|
family: "canton",
|
|
361
361
|
amount: new BigNumber(50),
|
|
362
|
-
recipient: "valid::
|
|
362
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
363
363
|
fee: new BigNumber(10),
|
|
364
364
|
tokenId: "",
|
|
365
365
|
};
|
|
@@ -380,7 +380,7 @@ describe("getTransactionStatus", () => {
|
|
|
380
380
|
const transaction: Transaction = {
|
|
381
381
|
family: "canton",
|
|
382
382
|
amount: new BigNumber(50),
|
|
383
|
-
recipient: "valid::
|
|
383
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
384
384
|
fee: new BigNumber(10),
|
|
385
385
|
tokenId: "",
|
|
386
386
|
};
|
|
@@ -400,7 +400,7 @@ describe("getTransactionStatus", () => {
|
|
|
400
400
|
const transaction: Transaction = {
|
|
401
401
|
family: "canton",
|
|
402
402
|
amount: new BigNumber(50),
|
|
403
|
-
recipient: "valid::
|
|
403
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
404
404
|
fee: new BigNumber(10),
|
|
405
405
|
tokenId: "",
|
|
406
406
|
};
|
|
@@ -432,7 +432,7 @@ describe("getTransactionStatus", () => {
|
|
|
432
432
|
const transaction: Transaction = {
|
|
433
433
|
family: "canton",
|
|
434
434
|
amount: new BigNumber(5), // Small amount
|
|
435
|
-
recipient: "valid::
|
|
435
|
+
recipient: "valid::11111111111111111111111111111111111111111111111111111111111111111111",
|
|
436
436
|
fee: new BigNumber(100), // High fee relative to amount
|
|
437
437
|
tokenId: "",
|
|
438
438
|
};
|
|
@@ -221,25 +221,5 @@ describe("onboard (devnet)", () => {
|
|
|
221
221
|
expect(finalResult.isApproved).toBe(true);
|
|
222
222
|
expect(typeof finalResult.isApproved).toBe("boolean");
|
|
223
223
|
}, 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
224
|
});
|
|
245
225
|
});
|