@sundaeswap/sprinkles 0.1.1 → 0.2.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/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js +451 -210
- package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
- package/dist/cjs/Sprinkle/index.js +333 -86
- package/dist/cjs/Sprinkle/index.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js +451 -210
- package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
- package/dist/esm/Sprinkle/index.js +334 -87
- package/dist/esm/Sprinkle/index.js.map +1 -1
- package/dist/types/Sprinkle/index.d.ts +40 -3
- package/dist/types/Sprinkle/index.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -3
- package/src/Sprinkle/__tests__/tx-dialog.test.ts +517 -234
- package/src/Sprinkle/index.ts +347 -109
|
@@ -3,23 +3,31 @@
|
|
|
3
3
|
var _bunTest = require("bun:test");
|
|
4
4
|
var _typebox = require("@sinclair/typebox");
|
|
5
5
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
6
|
-
// Track
|
|
6
|
+
// Track calls and responses
|
|
7
7
|
let selectCalls = [];
|
|
8
8
|
let selectResponses = [];
|
|
9
|
+
let confirmResponses = [];
|
|
10
|
+
let inputResponses = [];
|
|
9
11
|
|
|
10
12
|
// Mock @inquirer/prompts
|
|
11
13
|
_bunTest.mock.module("@inquirer/prompts", () => ({
|
|
12
|
-
input: (0, _bunTest.mock)(async () =>
|
|
14
|
+
input: (0, _bunTest.mock)(async () => {
|
|
15
|
+
const response = inputResponses.shift();
|
|
16
|
+
return response ?? "";
|
|
17
|
+
}),
|
|
13
18
|
password: (0, _bunTest.mock)(async () => "secret"),
|
|
14
19
|
select: (0, _bunTest.mock)(async opts => {
|
|
15
20
|
selectCalls.push(opts);
|
|
16
21
|
const response = selectResponses.shift();
|
|
17
22
|
if (response === undefined) {
|
|
18
|
-
|
|
19
|
-
return -1;
|
|
23
|
+
return "cancel";
|
|
20
24
|
}
|
|
21
25
|
return response;
|
|
22
26
|
}),
|
|
27
|
+
confirm: (0, _bunTest.mock)(async () => {
|
|
28
|
+
const response = confirmResponses.shift();
|
|
29
|
+
return response ?? false;
|
|
30
|
+
}),
|
|
23
31
|
search: (0, _bunTest.mock)(async () => "result")
|
|
24
32
|
}));
|
|
25
33
|
|
|
@@ -40,232 +48,465 @@ const {
|
|
|
40
48
|
const TestSchema = _typebox.Type.Object({
|
|
41
49
|
name: _typebox.Type.String()
|
|
42
50
|
});
|
|
43
|
-
|
|
51
|
+
|
|
52
|
+
// Helper to create a mock transaction
|
|
53
|
+
const createMockTx = (cbor = "deadbeef") => ({
|
|
54
|
+
toCbor: () => cbor,
|
|
55
|
+
body: () => ({
|
|
56
|
+
toCbor: () => cbor,
|
|
57
|
+
requiredSigners: () => null,
|
|
58
|
+
certs: () => null,
|
|
59
|
+
withdrawals: () => null
|
|
60
|
+
}),
|
|
61
|
+
witnessSet: () => ({
|
|
62
|
+
vkeys: () => null,
|
|
63
|
+
setVkeys: () => {}
|
|
64
|
+
}),
|
|
65
|
+
setWitnessSet: () => {}
|
|
66
|
+
});
|
|
67
|
+
(0, _bunTest.describe)("TxDialog", () => {
|
|
44
68
|
(0, _bunTest.beforeEach)(() => {
|
|
45
69
|
selectCalls = [];
|
|
46
70
|
selectResponses = [];
|
|
71
|
+
confirmResponses = [];
|
|
72
|
+
inputResponses = [];
|
|
47
73
|
clipboardContent = "";
|
|
48
74
|
clipboardShouldFail = false;
|
|
49
75
|
});
|
|
50
|
-
(0, _bunTest.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
(0, _bunTest.describe)("Display", () => {
|
|
77
|
+
(0, _bunTest.test)("shows truncated CBOR by default", async () => {
|
|
78
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog");
|
|
79
|
+
const logs = [];
|
|
80
|
+
const origLog = console.log;
|
|
81
|
+
console.log = (...args) => logs.push(args.join(" "));
|
|
82
|
+
selectResponses = ["cancel"];
|
|
83
|
+
const mockTx = createMockTx("a".repeat(100));
|
|
84
|
+
const mockBlaze = {
|
|
85
|
+
wallet: {
|
|
86
|
+
getUsedAddresses: async () => []
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
90
|
+
console.log = origLog;
|
|
91
|
+
const cborLog = logs.find(l => l.includes("Transaction CBOR:"));
|
|
92
|
+
(0, _bunTest.expect)(cborLog).toBeDefined();
|
|
93
|
+
(0, _bunTest.expect)(cborLog.length).toBeLessThan(100);
|
|
94
|
+
(0, _bunTest.expect)(cborLog).toContain("...");
|
|
95
|
+
});
|
|
96
|
+
(0, _bunTest.test)("shows transaction hash", async () => {
|
|
97
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog-hash");
|
|
98
|
+
const logs = [];
|
|
99
|
+
const origLog = console.log;
|
|
100
|
+
console.log = (...args) => logs.push(args.join(" "));
|
|
101
|
+
selectResponses = ["cancel"];
|
|
102
|
+
const mockTx = createMockTx();
|
|
103
|
+
const mockBlaze = {
|
|
104
|
+
wallet: {
|
|
105
|
+
getUsedAddresses: async () => []
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
109
|
+
console.log = origLog;
|
|
110
|
+
const txLog = logs.find(l => l.includes("Transaction:"));
|
|
111
|
+
(0, _bunTest.expect)(txLog).toBeDefined();
|
|
112
|
+
});
|
|
113
|
+
(0, _bunTest.test)("shows signature count", async () => {
|
|
114
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog-sigs");
|
|
115
|
+
const logs = [];
|
|
116
|
+
const origLog = console.log;
|
|
117
|
+
console.log = (...args) => logs.push(args.join(" "));
|
|
118
|
+
selectResponses = ["cancel"];
|
|
119
|
+
const mockTx = createMockTx();
|
|
120
|
+
const mockBlaze = {
|
|
121
|
+
wallet: {
|
|
122
|
+
getUsedAddresses: async () => []
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
126
|
+
console.log = origLog;
|
|
127
|
+
const sigLog = logs.find(l => l.includes("Signatures:"));
|
|
128
|
+
(0, _bunTest.expect)(sigLog).toBeDefined();
|
|
129
|
+
(0, _bunTest.expect)(sigLog).toContain("0");
|
|
130
|
+
});
|
|
79
131
|
});
|
|
80
|
-
(0, _bunTest.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
132
|
+
(0, _bunTest.describe)("Menu options", () => {
|
|
133
|
+
(0, _bunTest.test)("non-HotWallet has Expand, Copy, Import, Submit, Cancel - no Sign", async () => {
|
|
134
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog2");
|
|
135
|
+
const origLog = console.log;
|
|
136
|
+
console.log = () => {};
|
|
137
|
+
selectResponses = ["cancel"];
|
|
138
|
+
const mockTx = createMockTx();
|
|
139
|
+
const mockBlaze = {
|
|
140
|
+
wallet: {
|
|
141
|
+
getUsedAddresses: async () => []
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
145
|
+
console.log = origLog;
|
|
146
|
+
const menuCall = selectCalls[0];
|
|
147
|
+
(0, _bunTest.expect)(menuCall).toBeDefined();
|
|
148
|
+
const choiceNames = menuCall.choices.map(c => c.name);
|
|
149
|
+
(0, _bunTest.expect)(choiceNames).toContain("Expand CBOR");
|
|
150
|
+
(0, _bunTest.expect)(choiceNames).toContain("Copy CBOR to clipboard");
|
|
151
|
+
(0, _bunTest.expect)(choiceNames).toContain("Import signatures from CBOR");
|
|
152
|
+
(0, _bunTest.expect)(choiceNames).toContain("Submit transaction");
|
|
153
|
+
(0, _bunTest.expect)(choiceNames).toContain("Cancel");
|
|
154
|
+
(0, _bunTest.expect)(choiceNames).not.toContain("Sign with this wallet");
|
|
155
|
+
});
|
|
156
|
+
(0, _bunTest.test)("HotWallet has Sign option", async () => {
|
|
157
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog3");
|
|
158
|
+
const origLog = console.log;
|
|
159
|
+
console.log = () => {};
|
|
160
|
+
const {
|
|
161
|
+
HotWallet
|
|
162
|
+
} = await Promise.resolve().then(() => _interopRequireWildcard(require("@blaze-cardano/sdk")));
|
|
163
|
+
selectResponses = ["cancel"];
|
|
164
|
+
const mockTx = createMockTx();
|
|
165
|
+
const hotWalletProto = HotWallet.prototype;
|
|
166
|
+
const mockWallet = Object.create(hotWalletProto);
|
|
167
|
+
mockWallet.getUsedAddresses = async () => [];
|
|
168
|
+
const mockBlaze = {
|
|
169
|
+
wallet: mockWallet
|
|
170
|
+
};
|
|
171
|
+
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
172
|
+
console.log = origLog;
|
|
173
|
+
const menuCall = selectCalls[0];
|
|
174
|
+
(0, _bunTest.expect)(menuCall).toBeDefined();
|
|
175
|
+
const choiceNames = menuCall.choices.map(c => c.name);
|
|
176
|
+
(0, _bunTest.expect)(choiceNames).toContain("Sign with this wallet");
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
(0, _bunTest.describe)("Copy CBOR", () => {
|
|
180
|
+
(0, _bunTest.test)("copies CBOR to clipboard", async () => {
|
|
181
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog4");
|
|
182
|
+
const origLog = console.log;
|
|
183
|
+
const logs = [];
|
|
184
|
+
console.log = (...args) => logs.push(args.join(" "));
|
|
185
|
+
selectResponses = ["copy", "cancel"];
|
|
186
|
+
const txCbor = "deadbeefcafebabe";
|
|
187
|
+
const mockTx = createMockTx(txCbor);
|
|
188
|
+
const mockBlaze = {
|
|
189
|
+
wallet: {
|
|
190
|
+
getUsedAddresses: async () => []
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
194
|
+
console.log = origLog;
|
|
195
|
+
(0, _bunTest.expect)(clipboardContent).toBe(txCbor);
|
|
196
|
+
(0, _bunTest.expect)(logs.some(l => l.includes("copied to clipboard"))).toBe(true);
|
|
197
|
+
});
|
|
198
|
+
(0, _bunTest.test)("clipboard failure falls back to expanded view", async () => {
|
|
199
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog5");
|
|
200
|
+
const origLog = console.log;
|
|
201
|
+
const logs = [];
|
|
202
|
+
console.log = (...args) => logs.push(args.join(" "));
|
|
203
|
+
clipboardShouldFail = true;
|
|
204
|
+
selectResponses = ["copy", "cancel"];
|
|
205
|
+
const txCbor = "a".repeat(100);
|
|
206
|
+
const mockTx = createMockTx(txCbor);
|
|
207
|
+
const mockBlaze = {
|
|
208
|
+
wallet: {
|
|
209
|
+
getUsedAddresses: async () => []
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
213
|
+
console.log = origLog;
|
|
214
|
+
(0, _bunTest.expect)(logs.some(l => l.includes("Failed to copy"))).toBe(true);
|
|
215
|
+
});
|
|
108
216
|
});
|
|
109
|
-
(0, _bunTest.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
217
|
+
(0, _bunTest.describe)("Expand CBOR", () => {
|
|
218
|
+
(0, _bunTest.test)("shows full content when expanded", async () => {
|
|
219
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog6");
|
|
220
|
+
const origLog = console.log;
|
|
221
|
+
const logs = [];
|
|
222
|
+
console.log = (...args) => logs.push(args.join(" "));
|
|
223
|
+
selectResponses = ["expand", "cancel"];
|
|
224
|
+
const txCbor = "b".repeat(100);
|
|
225
|
+
const mockTx = createMockTx(txCbor);
|
|
226
|
+
const mockBlaze = {
|
|
227
|
+
wallet: {
|
|
228
|
+
getUsedAddresses: async () => []
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
232
|
+
console.log = origLog;
|
|
113
233
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
234
|
+
// First shows truncated, second shows full
|
|
235
|
+
const truncatedLog = logs.find(l => l.includes("...") && l.includes("Transaction CBOR:"));
|
|
236
|
+
const fullLog = logs.find(l => l.includes(txCbor) && !l.includes("..."));
|
|
237
|
+
(0, _bunTest.expect)(truncatedLog).toBeDefined();
|
|
238
|
+
(0, _bunTest.expect)(fullLog).toBeDefined();
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
(0, _bunTest.describe)("Sign", () => {
|
|
242
|
+
(0, _bunTest.test)("beforeSign hook is called before signing", async () => {
|
|
243
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog7");
|
|
244
|
+
const origLog = console.log;
|
|
245
|
+
const origWarn = console.warn;
|
|
246
|
+
console.log = () => {};
|
|
247
|
+
console.warn = () => {};
|
|
248
|
+
const {
|
|
249
|
+
HotWallet
|
|
250
|
+
} = await Promise.resolve().then(() => _interopRequireWildcard(require("@blaze-cardano/sdk")));
|
|
251
|
+
let beforeSignCalled = false;
|
|
252
|
+
selectResponses = ["sign", "cancel"];
|
|
253
|
+
const mockTx = createMockTx();
|
|
254
|
+
const hotWalletProto = HotWallet.prototype;
|
|
255
|
+
const mockWallet = Object.create(hotWalletProto);
|
|
256
|
+
mockWallet.getUsedAddresses = async () => [];
|
|
257
|
+
const mockBlaze = {
|
|
258
|
+
wallet: mockWallet,
|
|
259
|
+
signTransaction: async tx => ({
|
|
260
|
+
witnessSet: () => ({
|
|
261
|
+
vkeys: () => ({
|
|
262
|
+
size: () => 1,
|
|
263
|
+
toCore: () => [["vkey123", "sig123"]]
|
|
264
|
+
})
|
|
265
|
+
})
|
|
266
|
+
})
|
|
267
|
+
};
|
|
268
|
+
await sprinkle.TxDialog(mockBlaze, mockTx, {
|
|
269
|
+
beforeSign: async () => {
|
|
270
|
+
beforeSignCalled = true;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
console.log = origLog;
|
|
274
|
+
console.warn = origWarn;
|
|
275
|
+
(0, _bunTest.expect)(beforeSignCalled).toBe(true);
|
|
276
|
+
});
|
|
277
|
+
(0, _bunTest.test)("Sign option hidden after signing", async () => {
|
|
278
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog-signed");
|
|
279
|
+
const origLog = console.log;
|
|
280
|
+
const origWarn = console.warn;
|
|
281
|
+
console.log = () => {};
|
|
282
|
+
console.warn = () => {};
|
|
283
|
+
const {
|
|
284
|
+
HotWallet
|
|
285
|
+
} = await Promise.resolve().then(() => _interopRequireWildcard(require("@blaze-cardano/sdk")));
|
|
286
|
+
selectResponses = ["sign", "cancel"];
|
|
287
|
+
const mockTx = createMockTx();
|
|
288
|
+
const hotWalletProto = HotWallet.prototype;
|
|
289
|
+
const mockWallet = Object.create(hotWalletProto);
|
|
290
|
+
mockWallet.getUsedAddresses = async () => [];
|
|
291
|
+
const mockBlaze = {
|
|
292
|
+
wallet: mockWallet,
|
|
293
|
+
signTransaction: async tx => ({
|
|
294
|
+
witnessSet: () => ({
|
|
295
|
+
vkeys: () => ({
|
|
296
|
+
size: () => 1,
|
|
297
|
+
toCore: () => [["vkey123", "sig123"]]
|
|
298
|
+
})
|
|
299
|
+
})
|
|
300
|
+
})
|
|
301
|
+
};
|
|
302
|
+
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
303
|
+
console.log = origLog;
|
|
304
|
+
console.warn = origWarn;
|
|
127
305
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
};
|
|
136
|
-
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
137
|
-
console.log = origLog;
|
|
138
|
-
const menuCall = selectCalls[0];
|
|
139
|
-
(0, _bunTest.expect)(menuCall).toBeDefined();
|
|
140
|
-
const choiceNames = menuCall.choices.map(c => c.name);
|
|
141
|
-
(0, _bunTest.expect)(choiceNames).toContain("Sign and submit transaction");
|
|
306
|
+
// First menu should have Sign, second should not
|
|
307
|
+
(0, _bunTest.expect)(selectCalls.length).toBe(2);
|
|
308
|
+
const firstMenuChoices = selectCalls[0].choices.map(c => c.name);
|
|
309
|
+
const secondMenuChoices = selectCalls[1].choices.map(c => c.name);
|
|
310
|
+
(0, _bunTest.expect)(firstMenuChoices).toContain("Sign with this wallet");
|
|
311
|
+
(0, _bunTest.expect)(secondMenuChoices).not.toContain("Sign with this wallet");
|
|
312
|
+
});
|
|
142
313
|
});
|
|
143
|
-
(0, _bunTest.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
314
|
+
(0, _bunTest.describe)("Return values", () => {
|
|
315
|
+
(0, _bunTest.test)("returns cancelled when user cancels", async () => {
|
|
316
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog-cancel");
|
|
317
|
+
const origLog = console.log;
|
|
318
|
+
console.log = () => {};
|
|
319
|
+
selectResponses = ["cancel"];
|
|
320
|
+
const mockTx = createMockTx();
|
|
321
|
+
const mockBlaze = {
|
|
322
|
+
wallet: {
|
|
323
|
+
getUsedAddresses: async () => []
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
const result = await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
327
|
+
console.log = origLog;
|
|
328
|
+
(0, _bunTest.expect)(result.action).toBe("cancelled");
|
|
329
|
+
(0, _bunTest.expect)(result.tx).toBeDefined();
|
|
330
|
+
(0, _bunTest.expect)(result.txId).toBeUndefined();
|
|
331
|
+
});
|
|
332
|
+
(0, _bunTest.test)("returns signed when user signs then cancels", async () => {
|
|
333
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog-signed2");
|
|
334
|
+
const origLog = console.log;
|
|
335
|
+
const origWarn = console.warn;
|
|
336
|
+
console.log = () => {};
|
|
337
|
+
console.warn = () => {};
|
|
338
|
+
const {
|
|
339
|
+
HotWallet
|
|
340
|
+
} = await Promise.resolve().then(() => _interopRequireWildcard(require("@blaze-cardano/sdk")));
|
|
341
|
+
selectResponses = ["sign", "cancel"];
|
|
342
|
+
const mockTx = createMockTx();
|
|
343
|
+
const hotWalletProto = HotWallet.prototype;
|
|
344
|
+
const mockWallet = Object.create(hotWalletProto);
|
|
345
|
+
mockWallet.getUsedAddresses = async () => [];
|
|
346
|
+
const mockBlaze = {
|
|
347
|
+
wallet: mockWallet,
|
|
348
|
+
signTransaction: async tx => ({
|
|
349
|
+
witnessSet: () => ({
|
|
350
|
+
vkeys: () => ({
|
|
351
|
+
size: () => 1,
|
|
352
|
+
toCore: () => [["vkey123", "sig123"]]
|
|
353
|
+
})
|
|
354
|
+
})
|
|
355
|
+
})
|
|
356
|
+
};
|
|
357
|
+
const result = await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
358
|
+
console.log = origLog;
|
|
359
|
+
console.warn = origWarn;
|
|
360
|
+
(0, _bunTest.expect)(result.action).toBe("signed");
|
|
361
|
+
(0, _bunTest.expect)(result.tx).toBeDefined();
|
|
362
|
+
});
|
|
363
|
+
(0, _bunTest.test)("returns submitted with txId on successful submit", async () => {
|
|
364
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog-submit");
|
|
365
|
+
const origLog = console.log;
|
|
366
|
+
console.log = () => {};
|
|
367
|
+
selectResponses = ["submit"];
|
|
368
|
+
confirmResponses = [true]; // Confirm submit with no signatures
|
|
148
369
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
getUsedAddresses: async () => []
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
166
|
-
console.log = origLog;
|
|
167
|
-
(0, _bunTest.expect)(clipboardContent).toBe(txCbor);
|
|
168
|
-
(0, _bunTest.expect)(logs.some(l => l.includes("copied to clipboard"))).toBe(true);
|
|
370
|
+
const mockTx = createMockTx();
|
|
371
|
+
const mockBlaze = {
|
|
372
|
+
wallet: {
|
|
373
|
+
getUsedAddresses: async () => []
|
|
374
|
+
},
|
|
375
|
+
submitTransaction: async () => "txhash123456"
|
|
376
|
+
};
|
|
377
|
+
const result = await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
378
|
+
console.log = origLog;
|
|
379
|
+
(0, _bunTest.expect)(result.action).toBe("submitted");
|
|
380
|
+
(0, _bunTest.expect)(result.txId).toBe("txhash123456");
|
|
381
|
+
(0, _bunTest.expect)(result.tx).toBeDefined();
|
|
382
|
+
});
|
|
169
383
|
});
|
|
170
|
-
(0, _bunTest.
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
384
|
+
(0, _bunTest.describe)("Submit warnings", () => {
|
|
385
|
+
(0, _bunTest.test)("warns when submitting with no signatures", async () => {
|
|
386
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog-warn");
|
|
387
|
+
const origLog = console.log;
|
|
388
|
+
console.log = () => {};
|
|
389
|
+
|
|
390
|
+
// First try to submit, decline warning, then cancel
|
|
391
|
+
selectResponses = ["submit", "cancel"];
|
|
392
|
+
confirmResponses = [false];
|
|
393
|
+
const mockTx = createMockTx();
|
|
394
|
+
const mockBlaze = {
|
|
395
|
+
wallet: {
|
|
396
|
+
getUsedAddresses: async () => []
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
const result = await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
400
|
+
console.log = origLog;
|
|
176
401
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const txCbor = "a".repeat(100);
|
|
182
|
-
const mockTx = {
|
|
183
|
-
toCbor: () => txCbor,
|
|
184
|
-
body: () => ({
|
|
185
|
-
requiredSigners: () => null,
|
|
186
|
-
certs: () => null,
|
|
187
|
-
withdrawals: () => null
|
|
188
|
-
})
|
|
189
|
-
};
|
|
190
|
-
const mockBlaze = {
|
|
191
|
-
wallet: {
|
|
192
|
-
getUsedAddresses: async () => []
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
196
|
-
console.log = origLog;
|
|
197
|
-
(0, _bunTest.expect)(logs.some(l => l.includes("Failed to copy"))).toBe(true);
|
|
198
|
-
// After failure it should show the full CBOR without truncation
|
|
199
|
-
(0, _bunTest.expect)(logs.some(l => l.includes(txCbor) && !l.includes("..."))).toBe(true);
|
|
402
|
+
// Should have returned to menu, then cancelled
|
|
403
|
+
(0, _bunTest.expect)(result.action).toBe("cancelled");
|
|
404
|
+
(0, _bunTest.expect)(selectCalls.length).toBe(2);
|
|
405
|
+
});
|
|
200
406
|
});
|
|
201
|
-
(0, _bunTest.
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
407
|
+
(0, _bunTest.describe)("Exit behavior", () => {
|
|
408
|
+
(0, _bunTest.test)("exits loop after successful submit", async () => {
|
|
409
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog-exit");
|
|
410
|
+
const origLog = console.log;
|
|
411
|
+
console.log = () => {};
|
|
412
|
+
selectResponses = ["submit"];
|
|
413
|
+
confirmResponses = [true];
|
|
414
|
+
const mockTx = createMockTx();
|
|
415
|
+
const mockBlaze = {
|
|
416
|
+
wallet: {
|
|
417
|
+
getUsedAddresses: async () => []
|
|
418
|
+
},
|
|
419
|
+
submitTransaction: async () => "txhash789"
|
|
420
|
+
};
|
|
421
|
+
const result = await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
422
|
+
console.log = origLog;
|
|
206
423
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
424
|
+
// Should only have one menu call - no loop after submit
|
|
425
|
+
(0, _bunTest.expect)(selectCalls.length).toBe(1);
|
|
426
|
+
(0, _bunTest.expect)(result.action).toBe("submitted");
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
(0, _bunTest.describe)("Required signers display", () => {
|
|
430
|
+
(0, _bunTest.test)("shows required signers when present", async () => {
|
|
431
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog-req");
|
|
432
|
+
const logs = [];
|
|
433
|
+
const origLog = console.log;
|
|
434
|
+
console.log = (...args) => logs.push(args.join(" "));
|
|
435
|
+
selectResponses = ["cancel"];
|
|
436
|
+
const mockTx = {
|
|
437
|
+
toCbor: () => "deadbeef",
|
|
438
|
+
body: () => ({
|
|
439
|
+
toCbor: () => "deadbeef",
|
|
440
|
+
requiredSigners: () => ({
|
|
441
|
+
values: () => [{
|
|
442
|
+
toString: () => "abc123def456"
|
|
443
|
+
}, {
|
|
444
|
+
toString: () => "789ghi012jkl"
|
|
445
|
+
}]
|
|
446
|
+
}),
|
|
447
|
+
certs: () => null,
|
|
448
|
+
withdrawals: () => null
|
|
449
|
+
}),
|
|
450
|
+
witnessSet: () => ({
|
|
451
|
+
vkeys: () => null
|
|
452
|
+
})
|
|
453
|
+
};
|
|
454
|
+
const mockBlaze = {
|
|
455
|
+
wallet: {
|
|
456
|
+
getUsedAddresses: async () => []
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
460
|
+
console.log = origLog;
|
|
225
461
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
462
|
+
// Should show "X of Y required" format
|
|
463
|
+
(0, _bunTest.expect)(logs.some(l => l.includes("of") && l.includes("required"))).toBe(true);
|
|
464
|
+
// Should show required signers list
|
|
465
|
+
(0, _bunTest.expect)(logs.some(l => l.includes("Required signers:"))).toBe(true);
|
|
466
|
+
});
|
|
231
467
|
});
|
|
232
|
-
(0, _bunTest.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
} = await Promise.resolve().then(() => _interopRequireWildcard(require("@blaze-cardano/sdk")));
|
|
241
|
-
let beforeSignCalled = false;
|
|
468
|
+
(0, _bunTest.describe)("Import signatures", () => {
|
|
469
|
+
(0, _bunTest.test)("continues on empty CBOR input", async () => {
|
|
470
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog-import1");
|
|
471
|
+
const origLog = console.log;
|
|
472
|
+
const logs = [];
|
|
473
|
+
console.log = (...args) => logs.push(args.join(" "));
|
|
474
|
+
selectResponses = ["import", "cancel"];
|
|
475
|
+
inputResponses = [""]; // Empty input
|
|
242
476
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
477
|
+
const mockTx = createMockTx();
|
|
478
|
+
const mockBlaze = {
|
|
479
|
+
wallet: {
|
|
480
|
+
getUsedAddresses: async () => []
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
const result = await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
484
|
+
console.log = origLog;
|
|
485
|
+
(0, _bunTest.expect)(logs.some(l => l.includes("No CBOR provided"))).toBe(true);
|
|
486
|
+
(0, _bunTest.expect)(result.action).toBe("cancelled");
|
|
487
|
+
});
|
|
488
|
+
(0, _bunTest.test)("handles invalid CBOR gracefully", async () => {
|
|
489
|
+
const sprinkle = new Sprinkle(TestSchema, "/tmp/test-txdialog-import2");
|
|
490
|
+
const origLog = console.log;
|
|
491
|
+
const origErr = console.error;
|
|
492
|
+
const logs = [];
|
|
493
|
+
const errors = [];
|
|
494
|
+
console.log = (...args) => logs.push(args.join(" "));
|
|
495
|
+
console.error = (...args) => errors.push(args.join(" "));
|
|
496
|
+
selectResponses = ["import", "cancel"];
|
|
497
|
+
inputResponses = ["not-valid-cbor"];
|
|
498
|
+
const mockTx = createMockTx();
|
|
499
|
+
const mockBlaze = {
|
|
500
|
+
wallet: {
|
|
501
|
+
getUsedAddresses: async () => []
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
const result = await sprinkle.TxDialog(mockBlaze, mockTx);
|
|
505
|
+
console.log = origLog;
|
|
506
|
+
console.error = origErr;
|
|
507
|
+
(0, _bunTest.expect)(errors.some(l => l.includes("Failed to import"))).toBe(true);
|
|
508
|
+
(0, _bunTest.expect)(result.action).toBe("cancelled");
|
|
265
509
|
});
|
|
266
|
-
console.log = origLog;
|
|
267
|
-
console.warn = origWarn;
|
|
268
|
-
(0, _bunTest.expect)(beforeSignCalled).toBe(true);
|
|
269
510
|
});
|
|
270
511
|
});
|
|
271
512
|
//# sourceMappingURL=tx-dialog.test.js.map
|