@sundaeswap/sprinkles 0.3.0 → 0.5.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.
Files changed (88) hide show
  1. package/dist/cjs/Sprinkle/__tests__/encryption.test.js +20 -8
  2. package/dist/cjs/Sprinkle/__tests__/encryption.test.js.map +1 -1
  3. package/dist/cjs/Sprinkle/__tests__/enhancements.test.js +41 -16
  4. package/dist/cjs/Sprinkle/__tests__/enhancements.test.js.map +1 -1
  5. package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js +85 -38
  6. package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
  7. package/dist/cjs/Sprinkle/__tests__/settings-persistence.test.js +120 -0
  8. package/dist/cjs/Sprinkle/__tests__/settings-persistence.test.js.map +1 -1
  9. package/dist/cjs/Sprinkle/__tests__/show-menu.test.js +93 -7
  10. package/dist/cjs/Sprinkle/__tests__/show-menu.test.js.map +1 -1
  11. package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js +21 -0
  12. package/dist/cjs/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
  13. package/dist/cjs/Sprinkle/encryption.js +131 -0
  14. package/dist/cjs/Sprinkle/encryption.js.map +1 -0
  15. package/dist/cjs/Sprinkle/index.js +318 -352
  16. package/dist/cjs/Sprinkle/index.js.map +1 -1
  17. package/dist/cjs/Sprinkle/prompts.js +393 -0
  18. package/dist/cjs/Sprinkle/prompts.js.map +1 -0
  19. package/dist/cjs/Sprinkle/schemas.js +97 -0
  20. package/dist/cjs/Sprinkle/schemas.js.map +1 -0
  21. package/dist/cjs/Sprinkle/tx-dialog.js +101 -0
  22. package/dist/cjs/Sprinkle/tx-dialog.js.map +1 -0
  23. package/dist/cjs/Sprinkle/type-guards.js +42 -0
  24. package/dist/cjs/Sprinkle/type-guards.js.map +1 -0
  25. package/dist/cjs/Sprinkle/types.js +49 -0
  26. package/dist/cjs/Sprinkle/types.js.map +1 -0
  27. package/dist/cjs/Sprinkle/wallet.js +98 -0
  28. package/dist/cjs/Sprinkle/wallet.js.map +1 -0
  29. package/dist/esm/Sprinkle/__tests__/encryption.test.js +20 -8
  30. package/dist/esm/Sprinkle/__tests__/encryption.test.js.map +1 -1
  31. package/dist/esm/Sprinkle/__tests__/enhancements.test.js +41 -16
  32. package/dist/esm/Sprinkle/__tests__/enhancements.test.js.map +1 -1
  33. package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js +85 -38
  34. package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
  35. package/dist/esm/Sprinkle/__tests__/settings-persistence.test.js +120 -0
  36. package/dist/esm/Sprinkle/__tests__/settings-persistence.test.js.map +1 -1
  37. package/dist/esm/Sprinkle/__tests__/show-menu.test.js +94 -8
  38. package/dist/esm/Sprinkle/__tests__/show-menu.test.js.map +1 -1
  39. package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js +21 -0
  40. package/dist/esm/Sprinkle/__tests__/tx-dialog.test.js.map +1 -1
  41. package/dist/esm/Sprinkle/encryption.js +117 -0
  42. package/dist/esm/Sprinkle/encryption.js.map +1 -0
  43. package/dist/esm/Sprinkle/index.js +172 -337
  44. package/dist/esm/Sprinkle/index.js.map +1 -1
  45. package/dist/esm/Sprinkle/prompts.js +385 -0
  46. package/dist/esm/Sprinkle/prompts.js.map +1 -0
  47. package/dist/esm/Sprinkle/schemas.js +91 -0
  48. package/dist/esm/Sprinkle/schemas.js.map +1 -0
  49. package/dist/esm/Sprinkle/tx-dialog.js +90 -0
  50. package/dist/esm/Sprinkle/tx-dialog.js.map +1 -0
  51. package/dist/esm/Sprinkle/type-guards.js +24 -0
  52. package/dist/esm/Sprinkle/type-guards.js.map +1 -0
  53. package/dist/esm/Sprinkle/types.js +42 -0
  54. package/dist/esm/Sprinkle/types.js.map +1 -0
  55. package/dist/esm/Sprinkle/wallet.js +90 -0
  56. package/dist/esm/Sprinkle/wallet.js.map +1 -0
  57. package/dist/types/Sprinkle/encryption.d.ts +43 -0
  58. package/dist/types/Sprinkle/encryption.d.ts.map +1 -0
  59. package/dist/types/Sprinkle/index.d.ts +13 -174
  60. package/dist/types/Sprinkle/index.d.ts.map +1 -1
  61. package/dist/types/Sprinkle/prompts.d.ts +94 -0
  62. package/dist/types/Sprinkle/prompts.d.ts.map +1 -0
  63. package/dist/types/Sprinkle/schemas.d.ts +125 -0
  64. package/dist/types/Sprinkle/schemas.d.ts.map +1 -0
  65. package/dist/types/Sprinkle/tx-dialog.d.ts +37 -0
  66. package/dist/types/Sprinkle/tx-dialog.d.ts.map +1 -0
  67. package/dist/types/Sprinkle/type-guards.d.ts +22 -0
  68. package/dist/types/Sprinkle/type-guards.d.ts.map +1 -0
  69. package/dist/types/Sprinkle/types.d.ts +62 -0
  70. package/dist/types/Sprinkle/types.d.ts.map +1 -0
  71. package/dist/types/Sprinkle/wallet.d.ts +27 -0
  72. package/dist/types/Sprinkle/wallet.d.ts.map +1 -0
  73. package/dist/types/tsconfig.build.tsbuildinfo +1 -1
  74. package/package.json +1 -1
  75. package/src/Sprinkle/__tests__/encryption.test.ts +21 -8
  76. package/src/Sprinkle/__tests__/enhancements.test.ts +41 -15
  77. package/src/Sprinkle/__tests__/fill-in-struct.test.ts +104 -38
  78. package/src/Sprinkle/__tests__/settings-persistence.test.ts +108 -0
  79. package/src/Sprinkle/__tests__/show-menu.test.ts +96 -8
  80. package/src/Sprinkle/__tests__/tx-dialog.test.ts +21 -0
  81. package/src/Sprinkle/encryption.ts +130 -0
  82. package/src/Sprinkle/index.ts +265 -478
  83. package/src/Sprinkle/prompts.ts +481 -0
  84. package/src/Sprinkle/schemas.ts +111 -0
  85. package/src/Sprinkle/tx-dialog.ts +100 -0
  86. package/src/Sprinkle/type-guards.ts +51 -0
  87. package/src/Sprinkle/types.ts +73 -0
  88. package/src/Sprinkle/wallet.ts +133 -0
@@ -0,0 +1,385 @@
1
+ /**
2
+ * Cancellable prompt wrappers with escape key support.
3
+ * Uses @inquirer/core's createPrompt and useKeypress for proper escape handling.
4
+ */
5
+
6
+ import { createPrompt, useState, useKeypress, usePrefix, usePagination, useMemo, makeTheme, isEnterKey, isUpKey, isDownKey, isBackspaceKey, Separator, ValidationError } from "@inquirer/core";
7
+ import colors from "yoctocolors-cjs";
8
+ import figures from "@inquirer/figures";
9
+
10
+ // Check if key is escape
11
+ const isEscapeKey = key => key.name === "escape";
12
+
13
+ // Theme for select prompt
14
+ const selectTheme = {
15
+ icon: {
16
+ cursor: figures.pointer
17
+ },
18
+ style: {
19
+ disabled: text => colors.dim(`- ${text}`),
20
+ description: text => colors.cyan(text),
21
+ helpTip: colors.dim("(Use arrow keys, Enter to select, Esc to cancel)")
22
+ },
23
+ helpMode: "always"
24
+ };
25
+
26
+ // Theme for input prompt
27
+ const inputTheme = {
28
+ style: {
29
+ helpTip: colors.dim("(Esc to cancel)")
30
+ }
31
+ };
32
+ function isSelectable(item) {
33
+ return !Separator.isSeparator(item) && !item.disabled;
34
+ }
35
+ function normalizeChoices(choices) {
36
+ return choices.map(choice => {
37
+ if (Separator.isSeparator(choice)) return choice;
38
+ if (typeof choice === "string") {
39
+ return {
40
+ value: choice,
41
+ name: choice,
42
+ short: choice,
43
+ disabled: false
44
+ };
45
+ }
46
+ const name = choice.name ?? String(choice.value);
47
+ return {
48
+ value: choice.value,
49
+ name,
50
+ short: choice.short ?? name,
51
+ disabled: choice.disabled ?? false,
52
+ description: choice.description
53
+ };
54
+ });
55
+ }
56
+
57
+ /**
58
+ * Select prompt with escape key support.
59
+ * Returns null if user presses Escape.
60
+ */
61
+ export const selectCancellable = createPrompt((config, done) => {
62
+ const {
63
+ loop = true,
64
+ pageSize = 7
65
+ } = config;
66
+ const theme = makeTheme(selectTheme, config.theme);
67
+ const [status, setStatus] = useState("idle");
68
+ const prefix = usePrefix({
69
+ status: status === "cancelled" ? "done" : status,
70
+ theme
71
+ });
72
+ const items = useMemo(() => normalizeChoices(config.choices), [config.choices]);
73
+ const bounds = useMemo(() => {
74
+ const first = items.findIndex(isSelectable);
75
+ // Find last selectable item (compatible with es2022)
76
+ let last = -1;
77
+ for (let i = items.length - 1; i >= 0; i--) {
78
+ if (isSelectable(items[i])) {
79
+ last = i;
80
+ break;
81
+ }
82
+ }
83
+ if (first === -1) {
84
+ throw new ValidationError("[select prompt] No selectable choices. All choices are disabled.");
85
+ }
86
+ return {
87
+ first,
88
+ last
89
+ };
90
+ }, [items]);
91
+ const defaultItemIndex = useMemo(() => {
92
+ if (!("default" in config)) return -1;
93
+ return items.findIndex(item => isSelectable(item) && item.value === config.default);
94
+ }, [config.default, items]);
95
+ const [active, setActive] = useState(defaultItemIndex === -1 ? bounds.first : defaultItemIndex);
96
+ const selectedChoice = items[active];
97
+ useKeypress((key, rl) => {
98
+ if (isEscapeKey(key)) {
99
+ setStatus("cancelled");
100
+ done(null);
101
+ } else if (isEnterKey(key)) {
102
+ setStatus("done");
103
+ done(selectedChoice.value);
104
+ } else if (isUpKey(key)) {
105
+ rl.clearLine(0);
106
+ if (active === bounds.first && loop) {
107
+ setActive(bounds.last);
108
+ } else {
109
+ let newActive = active - 1;
110
+ while (newActive >= bounds.first && !isSelectable(items[newActive])) {
111
+ newActive--;
112
+ }
113
+ if (newActive >= bounds.first) setActive(newActive);
114
+ }
115
+ } else if (isDownKey(key)) {
116
+ rl.clearLine(0);
117
+ if (active === bounds.last && loop) {
118
+ setActive(bounds.first);
119
+ } else {
120
+ let newActive = active + 1;
121
+ while (newActive <= bounds.last && !isSelectable(items[newActive])) {
122
+ newActive++;
123
+ }
124
+ if (newActive <= bounds.last) setActive(newActive);
125
+ }
126
+ }
127
+ });
128
+ const page = usePagination({
129
+ items,
130
+ active,
131
+ renderItem: ({
132
+ item,
133
+ isActive
134
+ }) => {
135
+ if (Separator.isSeparator(item)) {
136
+ return ` ${item.separator}`;
137
+ }
138
+ const line = item.name;
139
+ if (item.disabled) {
140
+ const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
141
+ return colors.dim(`- ${line} ${disabledLabel}`);
142
+ }
143
+ const cursor = isActive ? figures.pointer : " ";
144
+ const color = isActive ? colors.cyan : x => x;
145
+ return color(`${cursor} ${line}`);
146
+ },
147
+ pageSize,
148
+ loop
149
+ });
150
+ if (status === "cancelled") {
151
+ return `${prefix} ${config.message} ${colors.dim("(cancelled)")}`;
152
+ }
153
+ if (status === "done") {
154
+ return `${prefix} ${config.message} ${colors.cyan(selectedChoice?.short ?? selectedChoice?.name ?? "")}`;
155
+ }
156
+ const helpTip = colors.dim("(Use arrow keys, Enter to select, Esc to cancel)");
157
+ return `${prefix} ${config.message} ${helpTip}\n${page}`;
158
+ });
159
+ /**
160
+ * Input prompt with escape key support.
161
+ * Returns null if user presses Escape.
162
+ */
163
+ export const inputCancellable = createPrompt((config, done) => {
164
+ const [status, setStatus] = useState("idle");
165
+ const [value, setValue] = useState(config.default ?? "");
166
+ const [touched, setTouched] = useState(false);
167
+ const [error, setError] = useState(null);
168
+ const theme = makeTheme(inputTheme);
169
+ const prefix = usePrefix({
170
+ status: status === "cancelled" ? "done" : status,
171
+ theme
172
+ });
173
+ useKeypress(async (key, rl) => {
174
+ if (isEscapeKey(key)) {
175
+ setStatus("cancelled");
176
+ done(null);
177
+ } else if (isEnterKey(key)) {
178
+ // If user has edited, use their value (even if empty); otherwise use default
179
+ const answer = touched ? value : config.default ?? "";
180
+ if (config.validate) {
181
+ const result = await config.validate(answer);
182
+ if (result !== true) {
183
+ setError(typeof result === "string" ? result : "Invalid input");
184
+ return;
185
+ }
186
+ }
187
+ setStatus("done");
188
+ done(answer);
189
+ } else if (isBackspaceKey(key)) {
190
+ // Sync with readline's buffer after backspace
191
+ setValue(rl.line);
192
+ setTouched(true);
193
+ setError(null);
194
+ } else if (key.name !== "tab" && !key.ctrl && !key.meta) {
195
+ // Sync state with readline's current line buffer
196
+ setValue(rl.line);
197
+ setTouched(true);
198
+ setError(null);
199
+ }
200
+ });
201
+ const displayValue = config.transformer ? config.transformer(value, {
202
+ isFinal: status === "done"
203
+ }) : value;
204
+ if (status === "cancelled") {
205
+ return `${prefix} ${config.message} ${colors.dim("(cancelled)")}`;
206
+ }
207
+ if (status === "done") {
208
+ return `${prefix} ${config.message} ${colors.cyan(displayValue)}`;
209
+ }
210
+ const helpTip = colors.dim("(Esc to cancel)");
211
+ const errorMsg = error ? colors.red(`\n> ${error}`) : "";
212
+ return `${prefix} ${config.message} ${helpTip} ${displayValue}${errorMsg}`;
213
+ });
214
+ /**
215
+ * Password prompt with escape key support.
216
+ * Returns null if user presses Escape.
217
+ */
218
+ export const passwordCancellable = createPrompt((config, done) => {
219
+ const [status, setStatus] = useState("idle");
220
+ const [value, setValue] = useState("");
221
+ const [error, setError] = useState(null);
222
+ const theme = makeTheme(inputTheme);
223
+ const prefix = usePrefix({
224
+ status: status === "cancelled" ? "done" : status,
225
+ theme
226
+ });
227
+ const mask = config.mask ?? "*";
228
+ useKeypress(async (key, rl) => {
229
+ if (isEscapeKey(key)) {
230
+ setStatus("cancelled");
231
+ done(null);
232
+ } else if (isEnterKey(key)) {
233
+ if (config.validate) {
234
+ const result = await config.validate(value);
235
+ if (result !== true) {
236
+ setError(typeof result === "string" ? result : "Invalid input");
237
+ return;
238
+ }
239
+ }
240
+ setStatus("done");
241
+ done(value);
242
+ } else if (isBackspaceKey(key)) {
243
+ setValue(value.slice(0, -1));
244
+ setError(null);
245
+ } else if (key.name !== "tab" && !key.ctrl && !key.meta) {
246
+ // Use key.sequence for single character to avoid rl.line buffer issues
247
+ const char = key.sequence ?? "";
248
+ if (char) {
249
+ rl.clearLine(0);
250
+ setValue(value + char);
251
+ setError(null);
252
+ }
253
+ }
254
+ });
255
+ const masked = mask.repeat(value.length);
256
+ if (status === "cancelled") {
257
+ return `${prefix} ${config.message} ${colors.dim("(cancelled)")}`;
258
+ }
259
+ if (status === "done") {
260
+ return `${prefix} ${config.message} ${colors.dim(masked)}`;
261
+ }
262
+ const helpTip = colors.dim("(Esc to cancel)");
263
+ const errorMsg = error ? colors.red(`\n> ${error}`) : "";
264
+ return `${prefix} ${config.message} ${helpTip} ${masked}${errorMsg}`;
265
+ });
266
+ /**
267
+ * Confirm prompt with escape key support.
268
+ * Returns null if user presses Escape.
269
+ */
270
+ export const confirmCancellable = createPrompt((config, done) => {
271
+ const [status, setStatus] = useState("idle");
272
+ // Track value as undefined when no default, requiring explicit y/n
273
+ const [value, setValue] = useState(config.default);
274
+ const theme = makeTheme(inputTheme);
275
+ const prefix = usePrefix({
276
+ status: status === "cancelled" ? "done" : status,
277
+ theme
278
+ });
279
+ useKeypress(key => {
280
+ if (isEscapeKey(key)) {
281
+ setStatus("cancelled");
282
+ done(null);
283
+ } else if (isEnterKey(key)) {
284
+ // Only accept Enter if a value has been chosen (explicit or default)
285
+ if (value !== undefined) {
286
+ setStatus("done");
287
+ done(value);
288
+ }
289
+ } else if (key.name === "y" || key.name === "Y") {
290
+ setValue(true);
291
+ } else if (key.name === "n" || key.name === "N") {
292
+ setValue(false);
293
+ }
294
+ });
295
+ const hint = config.default === true ? "(Y/n)" : config.default === false ? "(y/N)" : "(y/n)";
296
+ const displayValue = value === true ? "Yes" : value === false ? "No" : "";
297
+ if (status === "cancelled") {
298
+ return `${prefix} ${config.message} ${colors.dim("(cancelled)")}`;
299
+ }
300
+ if (status === "done") {
301
+ return `${prefix} ${config.message} ${colors.cyan(displayValue)}`;
302
+ }
303
+ const helpTip = colors.dim("(Esc to cancel)");
304
+ return `${prefix} ${config.message} ${helpTip} ${hint} ${displayValue}`;
305
+ });
306
+
307
+ /**
308
+ * Type-safe wrapper for selectCancellable.
309
+ * Returns the selected value with proper typing, or null if cancelled.
310
+ */
311
+ export async function select(config) {
312
+ return selectCancellable(config);
313
+ }
314
+ /**
315
+ * Search prompt with escape key support.
316
+ * Returns null if user presses Escape.
317
+ *
318
+ * Note: This wraps @inquirer/search which has built-in escape handling,
319
+ * but we provide a consistent API with other cancellable prompts.
320
+ */
321
+ export const searchCancellable = createPrompt((config, done) => {
322
+ const [status, setStatus] = useState("idle");
323
+ const [searchTerm, setSearchTerm] = useState("");
324
+ const [results, setResults] = useState([]);
325
+ const [active, setActive] = useState(0);
326
+ const [loading, setLoading] = useState(false);
327
+ const theme = makeTheme(selectTheme);
328
+ const prefix = usePrefix({
329
+ status: status === "cancelled" ? "done" : status,
330
+ theme
331
+ });
332
+
333
+ // Fetch results when search term changes
334
+ useMemo(async () => {
335
+ setLoading(true);
336
+ try {
337
+ const items = await config.source(searchTerm || undefined);
338
+ setResults(items);
339
+ setActive(0);
340
+ } finally {
341
+ setLoading(false);
342
+ }
343
+ }, [searchTerm]);
344
+ useKeypress((key, rl) => {
345
+ if (isEscapeKey(key)) {
346
+ setStatus("cancelled");
347
+ done(null);
348
+ } else if (isEnterKey(key) && results.length > 0) {
349
+ setStatus("done");
350
+ done(results[active]?.value ?? null);
351
+ } else if (isUpKey(key) && results.length > 0) {
352
+ rl.clearLine(0);
353
+ setActive(active > 0 ? active - 1 : results.length - 1);
354
+ } else if (isDownKey(key) && results.length > 0) {
355
+ rl.clearLine(0);
356
+ setActive(active < results.length - 1 ? active + 1 : 0);
357
+ } else if (isBackspaceKey(key)) {
358
+ setSearchTerm(rl.line);
359
+ } else if (key.name !== "tab" && !key.ctrl && !key.meta) {
360
+ setSearchTerm(rl.line);
361
+ }
362
+ });
363
+ if (status === "cancelled") {
364
+ return `${prefix} ${config.message} ${colors.dim("(cancelled)")}`;
365
+ }
366
+ if (status === "done") {
367
+ const selected = results[active];
368
+ return `${prefix} ${config.message} ${colors.cyan(selected?.name ?? "")}`;
369
+ }
370
+ const helpTip = colors.dim("(Type to search, Esc to cancel)");
371
+ const searchLine = `${prefix} ${config.message} ${helpTip} ${searchTerm}`;
372
+ if (loading) {
373
+ return `${searchLine}\n${colors.dim(" Searching...")}`;
374
+ }
375
+ if (results.length === 0) {
376
+ return `${searchLine}\n${colors.dim(" No results")}`;
377
+ }
378
+ const resultLines = results.slice(0, 7).map((item, i) => {
379
+ const cursor = i === active ? figures.pointer : " ";
380
+ const color = i === active ? colors.cyan : x => x;
381
+ return color(`${cursor} ${item.name}`);
382
+ }).join("\n");
383
+ return `${searchLine}\n${resultLines}`;
384
+ });
385
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","names":["createPrompt","useState","useKeypress","usePrefix","usePagination","useMemo","makeTheme","isEnterKey","isUpKey","isDownKey","isBackspaceKey","Separator","ValidationError","colors","figures","isEscapeKey","key","name","selectTheme","icon","cursor","pointer","style","disabled","text","dim","description","cyan","helpTip","helpMode","inputTheme","isSelectable","item","isSeparator","normalizeChoices","choices","map","choice","value","short","String","selectCancellable","config","done","loop","pageSize","theme","status","setStatus","prefix","items","bounds","first","findIndex","last","i","length","defaultItemIndex","default","active","setActive","selectedChoice","rl","clearLine","newActive","page","renderItem","isActive","separator","line","disabledLabel","color","x","message","inputCancellable","setValue","touched","setTouched","error","setError","answer","validate","result","ctrl","meta","displayValue","transformer","isFinal","errorMsg","red","passwordCancellable","mask","slice","char","sequence","masked","repeat","confirmCancellable","undefined","hint","select","searchCancellable","searchTerm","setSearchTerm","results","setResults","loading","setLoading","source","selected","searchLine","resultLines","join"],"sources":["../../../src/Sprinkle/prompts.ts"],"sourcesContent":["/**\n * Cancellable prompt wrappers with escape key support.\n * Uses @inquirer/core's createPrompt and useKeypress for proper escape handling.\n */\n\nimport {\n createPrompt,\n useState,\n useKeypress,\n usePrefix,\n usePagination,\n useMemo,\n makeTheme,\n isEnterKey,\n isUpKey,\n isDownKey,\n isBackspaceKey,\n Separator,\n ValidationError,\n type Theme,\n} from \"@inquirer/core\";\nimport type { PartialDeep } from \"@inquirer/type\";\nimport colors from \"yoctocolors-cjs\";\nimport figures from \"@inquirer/figures\";\n\n// Check if key is escape\nconst isEscapeKey = (key: { name: string }) => key.name === \"escape\";\n\n// Theme for select prompt\nconst selectTheme = {\n icon: { cursor: figures.pointer },\n style: {\n disabled: (text: string) => colors.dim(`- ${text}`),\n description: (text: string) => colors.cyan(text),\n helpTip: colors.dim(\"(Use arrow keys, Enter to select, Esc to cancel)\"),\n },\n helpMode: \"always\" as const,\n};\n\n// Theme for input prompt\nconst inputTheme = {\n style: {\n helpTip: colors.dim(\"(Esc to cancel)\"),\n },\n};\n\ninterface SelectChoice<T> {\n name?: string;\n value: T;\n description?: string;\n short?: string;\n disabled?: boolean | string;\n}\n\ninterface SelectConfig<T> {\n message: string;\n choices: ReadonlyArray<SelectChoice<T> | Separator | string>;\n default?: T;\n pageSize?: number;\n loop?: boolean;\n theme?: PartialDeep<Theme<typeof selectTheme>>;\n}\n\nfunction isSelectable<T>(item: SelectChoice<T> | Separator): item is SelectChoice<T> {\n return !Separator.isSeparator(item) && !item.disabled;\n}\n\nfunction normalizeChoices<T>(\n choices: ReadonlyArray<SelectChoice<T> | Separator | string>,\n): Array<SelectChoice<T> | Separator> {\n return choices.map((choice) => {\n if (Separator.isSeparator(choice)) return choice;\n if (typeof choice === \"string\") {\n return {\n value: choice as unknown as T,\n name: choice,\n short: choice,\n disabled: false,\n };\n }\n const name = choice.name ?? String(choice.value);\n return {\n value: choice.value,\n name,\n short: choice.short ?? name,\n disabled: choice.disabled ?? false,\n description: choice.description,\n };\n });\n}\n\n/**\n * Select prompt with escape key support.\n * Returns null if user presses Escape.\n */\nexport const selectCancellable = createPrompt<\n unknown | null,\n SelectConfig<unknown>\n>((config, done) => {\n const { loop = true, pageSize = 7 } = config;\n const theme = makeTheme(selectTheme, config.theme);\n const [status, setStatus] = useState<\"idle\" | \"done\" | \"cancelled\">(\"idle\");\n const prefix = usePrefix({ status: status === \"cancelled\" ? \"done\" : status, theme });\n\n const items = useMemo(\n () => normalizeChoices(config.choices),\n [config.choices],\n );\n\n const bounds = useMemo(() => {\n const first = items.findIndex(isSelectable);\n // Find last selectable item (compatible with es2022)\n let last = -1;\n for (let i = items.length - 1; i >= 0; i--) {\n if (isSelectable(items[i]!)) {\n last = i;\n break;\n }\n }\n if (first === -1) {\n throw new ValidationError(\n \"[select prompt] No selectable choices. All choices are disabled.\",\n );\n }\n return { first, last };\n }, [items]);\n\n const defaultItemIndex = useMemo(() => {\n if (!(\"default\" in config)) return -1;\n return items.findIndex(\n (item) => isSelectable(item) && item.value === config.default,\n );\n }, [config.default, items]);\n\n const [active, setActive] = useState(\n defaultItemIndex === -1 ? bounds.first : defaultItemIndex,\n );\n\n const selectedChoice = items[active] as SelectChoice<unknown>;\n\n useKeypress((key, rl) => {\n if (isEscapeKey(key)) {\n setStatus(\"cancelled\");\n done(null);\n } else if (isEnterKey(key)) {\n setStatus(\"done\");\n done(selectedChoice.value);\n } else if (isUpKey(key)) {\n rl.clearLine(0);\n if (active === bounds.first && loop) {\n setActive(bounds.last);\n } else {\n let newActive = active - 1;\n while (newActive >= bounds.first && !isSelectable(items[newActive]!)) {\n newActive--;\n }\n if (newActive >= bounds.first) setActive(newActive);\n }\n } else if (isDownKey(key)) {\n rl.clearLine(0);\n if (active === bounds.last && loop) {\n setActive(bounds.first);\n } else {\n let newActive = active + 1;\n while (newActive <= bounds.last && !isSelectable(items[newActive]!)) {\n newActive++;\n }\n if (newActive <= bounds.last) setActive(newActive);\n }\n }\n });\n\n const page = usePagination({\n items,\n active,\n renderItem: ({ item, isActive }) => {\n if (Separator.isSeparator(item)) {\n return ` ${item.separator}`;\n }\n const line = item.name;\n if (item.disabled) {\n const disabledLabel =\n typeof item.disabled === \"string\" ? item.disabled : \"(disabled)\";\n return colors.dim(`- ${line} ${disabledLabel}`);\n }\n const cursor = isActive ? figures.pointer : \" \";\n const color = isActive ? colors.cyan : (x: string) => x;\n return color(`${cursor} ${line}`);\n },\n pageSize,\n loop,\n });\n\n if (status === \"cancelled\") {\n return `${prefix} ${config.message} ${colors.dim(\"(cancelled)\")}`;\n }\n\n if (status === \"done\") {\n return `${prefix} ${config.message} ${colors.cyan(selectedChoice?.short ?? selectedChoice?.name ?? \"\")}`;\n }\n\n const helpTip = colors.dim(\"(Use arrow keys, Enter to select, Esc to cancel)\");\n return `${prefix} ${config.message} ${helpTip}\\n${page}`;\n});\n\ninterface InputConfig {\n message: string;\n default?: string;\n transformer?: (value: string, options: { isFinal: boolean }) => string;\n validate?: (value: string) => boolean | string | Promise<boolean | string>;\n}\n\n/**\n * Input prompt with escape key support.\n * Returns null if user presses Escape.\n */\nexport const inputCancellable = createPrompt<string | null, InputConfig>(\n (config, done) => {\n const [status, setStatus] = useState<\"idle\" | \"done\" | \"cancelled\">(\"idle\");\n const [value, setValue] = useState(config.default ?? \"\");\n const [touched, setTouched] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const theme = makeTheme(inputTheme);\n const prefix = usePrefix({ status: status === \"cancelled\" ? \"done\" : status, theme });\n\n useKeypress(async (key, rl) => {\n if (isEscapeKey(key)) {\n setStatus(\"cancelled\");\n done(null);\n } else if (isEnterKey(key)) {\n // If user has edited, use their value (even if empty); otherwise use default\n const answer = touched ? value : (config.default ?? \"\");\n if (config.validate) {\n const result = await config.validate(answer);\n if (result !== true) {\n setError(typeof result === \"string\" ? result : \"Invalid input\");\n return;\n }\n }\n setStatus(\"done\");\n done(answer);\n } else if (isBackspaceKey(key)) {\n // Sync with readline's buffer after backspace\n setValue(rl.line);\n setTouched(true);\n setError(null);\n } else if (key.name !== \"tab\" && !key.ctrl && !(key as any).meta) {\n // Sync state with readline's current line buffer\n setValue(rl.line);\n setTouched(true);\n setError(null);\n }\n });\n\n const displayValue = config.transformer\n ? config.transformer(value, { isFinal: status === \"done\" })\n : value;\n\n if (status === \"cancelled\") {\n return `${prefix} ${config.message} ${colors.dim(\"(cancelled)\")}`;\n }\n\n if (status === \"done\") {\n return `${prefix} ${config.message} ${colors.cyan(displayValue)}`;\n }\n\n const helpTip = colors.dim(\"(Esc to cancel)\");\n const errorMsg = error ? colors.red(`\\n> ${error}`) : \"\";\n return `${prefix} ${config.message} ${helpTip} ${displayValue}${errorMsg}`;\n },\n);\n\ninterface PasswordConfig {\n message: string;\n mask?: string;\n validate?: (value: string) => boolean | string | Promise<boolean | string>;\n}\n\n/**\n * Password prompt with escape key support.\n * Returns null if user presses Escape.\n */\nexport const passwordCancellable = createPrompt<string | null, PasswordConfig>(\n (config, done) => {\n const [status, setStatus] = useState<\"idle\" | \"done\" | \"cancelled\">(\"idle\");\n const [value, setValue] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const theme = makeTheme(inputTheme);\n const prefix = usePrefix({ status: status === \"cancelled\" ? \"done\" : status, theme });\n const mask = config.mask ?? \"*\";\n\n useKeypress(async (key, rl) => {\n if (isEscapeKey(key)) {\n setStatus(\"cancelled\");\n done(null);\n } else if (isEnterKey(key)) {\n if (config.validate) {\n const result = await config.validate(value);\n if (result !== true) {\n setError(typeof result === \"string\" ? result : \"Invalid input\");\n return;\n }\n }\n setStatus(\"done\");\n done(value);\n } else if (isBackspaceKey(key)) {\n setValue(value.slice(0, -1));\n setError(null);\n } else if (key.name !== \"tab\" && !key.ctrl && !(key as any).meta) {\n // Use key.sequence for single character to avoid rl.line buffer issues\n const char = (key as any).sequence ?? \"\";\n if (char) {\n rl.clearLine(0);\n setValue(value + char);\n setError(null);\n }\n }\n });\n\n const masked = mask.repeat(value.length);\n\n if (status === \"cancelled\") {\n return `${prefix} ${config.message} ${colors.dim(\"(cancelled)\")}`;\n }\n\n if (status === \"done\") {\n return `${prefix} ${config.message} ${colors.dim(masked)}`;\n }\n\n const helpTip = colors.dim(\"(Esc to cancel)\");\n const errorMsg = error ? colors.red(`\\n> ${error}`) : \"\";\n return `${prefix} ${config.message} ${helpTip} ${masked}${errorMsg}`;\n },\n);\n\ninterface ConfirmConfig {\n message: string;\n default?: boolean;\n}\n\n/**\n * Confirm prompt with escape key support.\n * Returns null if user presses Escape.\n */\nexport const confirmCancellable = createPrompt<boolean | null, ConfirmConfig>(\n (config, done) => {\n const [status, setStatus] = useState<\"idle\" | \"done\" | \"cancelled\">(\"idle\");\n // Track value as undefined when no default, requiring explicit y/n\n const [value, setValue] = useState<boolean | undefined>(config.default);\n const theme = makeTheme(inputTheme);\n const prefix = usePrefix({ status: status === \"cancelled\" ? \"done\" : status, theme });\n\n useKeypress((key) => {\n if (isEscapeKey(key)) {\n setStatus(\"cancelled\");\n done(null);\n } else if (isEnterKey(key)) {\n // Only accept Enter if a value has been chosen (explicit or default)\n if (value !== undefined) {\n setStatus(\"done\");\n done(value);\n }\n } else if (key.name === \"y\" || key.name === \"Y\") {\n setValue(true);\n } else if (key.name === \"n\" || key.name === \"N\") {\n setValue(false);\n }\n });\n\n const hint = config.default === true ? \"(Y/n)\" : config.default === false ? \"(y/N)\" : \"(y/n)\";\n const displayValue = value === true ? \"Yes\" : value === false ? \"No\" : \"\";\n\n if (status === \"cancelled\") {\n return `${prefix} ${config.message} ${colors.dim(\"(cancelled)\")}`;\n }\n\n if (status === \"done\") {\n return `${prefix} ${config.message} ${colors.cyan(displayValue)}`;\n }\n\n const helpTip = colors.dim(\"(Esc to cancel)\");\n return `${prefix} ${config.message} ${helpTip} ${hint} ${displayValue}`;\n },\n);\n\n/**\n * Type-safe wrapper for selectCancellable.\n * Returns the selected value with proper typing, or null if cancelled.\n */\nexport async function select<T>(config: SelectConfig<T>): Promise<T | null> {\n return selectCancellable(config as SelectConfig<unknown>) as Promise<T | null>;\n}\n\ninterface SearchConfig<T> {\n message: string;\n source: (\n term: string | undefined,\n ) => Promise<{ name: string; value: T }[]> | { name: string; value: T }[];\n}\n\n/**\n * Search prompt with escape key support.\n * Returns null if user presses Escape.\n *\n * Note: This wraps @inquirer/search which has built-in escape handling,\n * but we provide a consistent API with other cancellable prompts.\n */\nexport const searchCancellable = createPrompt<unknown | null, SearchConfig<unknown>>(\n (config, done) => {\n const [status, setStatus] = useState<\"idle\" | \"done\" | \"cancelled\">(\"idle\");\n const [searchTerm, setSearchTerm] = useState(\"\");\n const [results, setResults] = useState<{ name: string; value: unknown }[]>([]);\n const [active, setActive] = useState(0);\n const [loading, setLoading] = useState(false);\n const theme = makeTheme(selectTheme);\n const prefix = usePrefix({ status: status === \"cancelled\" ? \"done\" : status, theme });\n\n // Fetch results when search term changes\n useMemo(async () => {\n setLoading(true);\n try {\n const items = await config.source(searchTerm || undefined);\n setResults(items);\n setActive(0);\n } finally {\n setLoading(false);\n }\n }, [searchTerm]);\n\n useKeypress((key, rl) => {\n if (isEscapeKey(key)) {\n setStatus(\"cancelled\");\n done(null);\n } else if (isEnterKey(key) && results.length > 0) {\n setStatus(\"done\");\n done(results[active]?.value ?? null);\n } else if (isUpKey(key) && results.length > 0) {\n rl.clearLine(0);\n setActive(active > 0 ? active - 1 : results.length - 1);\n } else if (isDownKey(key) && results.length > 0) {\n rl.clearLine(0);\n setActive(active < results.length - 1 ? active + 1 : 0);\n } else if (isBackspaceKey(key)) {\n setSearchTerm(rl.line);\n } else if (key.name !== \"tab\" && !key.ctrl && !(key as any).meta) {\n setSearchTerm(rl.line);\n }\n });\n\n if (status === \"cancelled\") {\n return `${prefix} ${config.message} ${colors.dim(\"(cancelled)\")}`;\n }\n\n if (status === \"done\") {\n const selected = results[active];\n return `${prefix} ${config.message} ${colors.cyan(selected?.name ?? \"\")}`;\n }\n\n const helpTip = colors.dim(\"(Type to search, Esc to cancel)\");\n const searchLine = `${prefix} ${config.message} ${helpTip} ${searchTerm}`;\n\n if (loading) {\n return `${searchLine}\\n${colors.dim(\" Searching...\")}`;\n }\n\n if (results.length === 0) {\n return `${searchLine}\\n${colors.dim(\" No results\")}`;\n }\n\n const resultLines = results\n .slice(0, 7)\n .map((item, i) => {\n const cursor = i === active ? figures.pointer : \" \";\n const color = i === active ? colors.cyan : (x: string) => x;\n return color(`${cursor} ${item.name}`);\n })\n .join(\"\\n\");\n\n return `${searchLine}\\n${resultLines}`;\n },\n);\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,91 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ /**
3
+ * Network selection schema (mainnet, preview, preprod).
4
+ */
5
+ export const NetworkSchema = Type.Union([Type.Literal("mainnet"), Type.Literal("preview"), Type.Literal("preprod")]);
6
+
7
+ /**
8
+ * Recursive multisig script module for Cardano native scripts.
9
+ */
10
+ export const MultisigScriptModule = Type.Module({
11
+ MultisigScript: Type.Union([Type.Object({
12
+ Signature: Type.Object({
13
+ key_hash: Type.String()
14
+ }, {
15
+ ctor: 0n
16
+ })
17
+ }), Type.Object({
18
+ AllOf: Type.Object({
19
+ scripts: Type.Array(Type.Ref("MultisigScript"))
20
+ }, {
21
+ ctor: 1n
22
+ })
23
+ }), Type.Object({
24
+ AnyOf: Type.Object({
25
+ scripts: Type.Array(Type.Ref("MultisigScript"))
26
+ }, {
27
+ ctor: 2n
28
+ })
29
+ }), Type.Object({
30
+ AtLeast: Type.Object({
31
+ required: Type.BigInt(),
32
+ scripts: Type.Array(Type.Ref("MultisigScript"))
33
+ }, {
34
+ ctor: 3n
35
+ })
36
+ }), Type.Object({
37
+ Before: Type.Object({
38
+ time: Type.BigInt()
39
+ }, {
40
+ ctor: 4n
41
+ })
42
+ }), Type.Object({
43
+ After: Type.Object({
44
+ time: Type.BigInt()
45
+ }, {
46
+ ctor: 5n
47
+ })
48
+ }), Type.Object({
49
+ Script: Type.Object({
50
+ script_hash: Type.String()
51
+ }, {
52
+ ctor: 6n
53
+ })
54
+ })])
55
+ });
56
+ export const MultisigScript = MultisigScriptModule.Import("MultisigScript");
57
+ /**
58
+ * Provider settings schema for blockchain data providers.
59
+ */
60
+ export const ProviderSettingsSchema = Type.Union([Type.Object({
61
+ type: Type.Literal("blockfrost"),
62
+ projectId: Type.String({
63
+ minLength: 1,
64
+ title: "Blockfrost Project ID"
65
+ })
66
+ }), Type.Object({
67
+ type: Type.Literal("maestro"),
68
+ apiKey: Type.String({
69
+ minLength: 1,
70
+ title: "Maestro API Key"
71
+ })
72
+ })]);
73
+
74
+ /**
75
+ * Wallet settings schema for hot and cold wallets.
76
+ */
77
+ export const WalletSettingsSchema = Type.Union([Type.Object({
78
+ type: Type.Literal("hot"),
79
+ privateKey: Type.String({
80
+ minLength: 1,
81
+ title: "Hot Wallet Private Key",
82
+ sensitive: true
83
+ })
84
+ }), Type.Object({
85
+ type: Type.Literal("cold"),
86
+ address: Type.String({
87
+ minLength: 1,
88
+ title: "Cold Wallet Address"
89
+ })
90
+ })]);
91
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","names":["Type","NetworkSchema","Union","Literal","MultisigScriptModule","Module","MultisigScript","Object","Signature","key_hash","String","ctor","AllOf","scripts","Array","Ref","AnyOf","AtLeast","required","BigInt","Before","time","After","Script","script_hash","Import","ProviderSettingsSchema","type","projectId","minLength","title","apiKey","WalletSettingsSchema","privateKey","sensitive","address"],"sources":["../../../src/Sprinkle/schemas.ts"],"sourcesContent":["import { Type } from \"@sinclair/typebox\";\nimport type { TExact } from \"./types.js\";\n\n/**\n * Network selection schema (mainnet, preview, preprod).\n */\nexport const NetworkSchema = Type.Union([\n Type.Literal(\"mainnet\"),\n Type.Literal(\"preview\"),\n Type.Literal(\"preprod\"),\n]);\n\n/**\n * Recursive multisig script module for Cardano native scripts.\n */\nexport const MultisigScriptModule = Type.Module({\n MultisigScript: Type.Union([\n Type.Object({\n Signature: Type.Object(\n {\n key_hash: Type.String(),\n },\n { ctor: 0n },\n ),\n }),\n Type.Object({\n AllOf: Type.Object(\n {\n scripts: Type.Array(Type.Ref(\"MultisigScript\")),\n },\n { ctor: 1n },\n ),\n }),\n Type.Object({\n AnyOf: Type.Object(\n {\n scripts: Type.Array(Type.Ref(\"MultisigScript\")),\n },\n { ctor: 2n },\n ),\n }),\n Type.Object({\n AtLeast: Type.Object(\n {\n required: Type.BigInt(),\n scripts: Type.Array(Type.Ref(\"MultisigScript\")),\n },\n { ctor: 3n },\n ),\n }),\n Type.Object({\n Before: Type.Object(\n {\n time: Type.BigInt(),\n },\n { ctor: 4n },\n ),\n }),\n Type.Object({\n After: Type.Object(\n {\n time: Type.BigInt(),\n },\n { ctor: 5n },\n ),\n }),\n Type.Object({\n Script: Type.Object(\n {\n script_hash: Type.String(),\n },\n { ctor: 6n },\n ),\n }),\n ]),\n});\n\nexport const MultisigScript = MultisigScriptModule.Import(\"MultisigScript\");\nexport type TMultisigScript = TExact<typeof MultisigScript>;\n\n/**\n * Provider settings schema for blockchain data providers.\n */\nexport const ProviderSettingsSchema = Type.Union([\n Type.Object({\n type: Type.Literal(\"blockfrost\"),\n projectId: Type.String({ minLength: 1, title: \"Blockfrost Project ID\" }),\n }),\n Type.Object({\n type: Type.Literal(\"maestro\"),\n apiKey: Type.String({ minLength: 1, title: \"Maestro API Key\" }),\n }),\n]);\n\n/**\n * Wallet settings schema for hot and cold wallets.\n */\nexport const WalletSettingsSchema = Type.Union([\n Type.Object({\n type: Type.Literal(\"hot\"),\n privateKey: Type.String({\n minLength: 1,\n title: \"Hot Wallet Private Key\",\n sensitive: true,\n }),\n }),\n Type.Object({\n type: Type.Literal(\"cold\"),\n address: Type.String({ minLength: 1, title: \"Cold Wallet Address\" }),\n }),\n]);\n"],"mappings":"AAAA,SAASA,IAAI,QAAQ,mBAAmB;AAGxC;AACA;AACA;AACA,OAAO,MAAMC,aAAa,GAAGD,IAAI,CAACE,KAAK,CAAC,CACtCF,IAAI,CAACG,OAAO,CAAC,SAAS,CAAC,EACvBH,IAAI,CAACG,OAAO,CAAC,SAAS,CAAC,EACvBH,IAAI,CAACG,OAAO,CAAC,SAAS,CAAC,CACxB,CAAC;;AAEF;AACA;AACA;AACA,OAAO,MAAMC,oBAAoB,GAAGJ,IAAI,CAACK,MAAM,CAAC;EAC9CC,cAAc,EAAEN,IAAI,CAACE,KAAK,CAAC,CACzBF,IAAI,CAACO,MAAM,CAAC;IACVC,SAAS,EAAER,IAAI,CAACO,MAAM,CACpB;MACEE,QAAQ,EAAET,IAAI,CAACU,MAAM,CAAC;IACxB,CAAC,EACD;MAAEC,IAAI,EAAE;IAAG,CACb;EACF,CAAC,CAAC,EACFX,IAAI,CAACO,MAAM,CAAC;IACVK,KAAK,EAAEZ,IAAI,CAACO,MAAM,CAChB;MACEM,OAAO,EAAEb,IAAI,CAACc,KAAK,CAACd,IAAI,CAACe,GAAG,CAAC,gBAAgB,CAAC;IAChD,CAAC,EACD;MAAEJ,IAAI,EAAE;IAAG,CACb;EACF,CAAC,CAAC,EACFX,IAAI,CAACO,MAAM,CAAC;IACVS,KAAK,EAAEhB,IAAI,CAACO,MAAM,CAChB;MACEM,OAAO,EAAEb,IAAI,CAACc,KAAK,CAACd,IAAI,CAACe,GAAG,CAAC,gBAAgB,CAAC;IAChD,CAAC,EACD;MAAEJ,IAAI,EAAE;IAAG,CACb;EACF,CAAC,CAAC,EACFX,IAAI,CAACO,MAAM,CAAC;IACVU,OAAO,EAAEjB,IAAI,CAACO,MAAM,CAClB;MACEW,QAAQ,EAAElB,IAAI,CAACmB,MAAM,CAAC,CAAC;MACvBN,OAAO,EAAEb,IAAI,CAACc,KAAK,CAACd,IAAI,CAACe,GAAG,CAAC,gBAAgB,CAAC;IAChD,CAAC,EACD;MAAEJ,IAAI,EAAE;IAAG,CACb;EACF,CAAC,CAAC,EACFX,IAAI,CAACO,MAAM,CAAC;IACVa,MAAM,EAAEpB,IAAI,CAACO,MAAM,CACjB;MACEc,IAAI,EAAErB,IAAI,CAACmB,MAAM,CAAC;IACpB,CAAC,EACD;MAAER,IAAI,EAAE;IAAG,CACb;EACF,CAAC,CAAC,EACFX,IAAI,CAACO,MAAM,CAAC;IACVe,KAAK,EAAEtB,IAAI,CAACO,MAAM,CAChB;MACEc,IAAI,EAAErB,IAAI,CAACmB,MAAM,CAAC;IACpB,CAAC,EACD;MAAER,IAAI,EAAE;IAAG,CACb;EACF,CAAC,CAAC,EACFX,IAAI,CAACO,MAAM,CAAC;IACVgB,MAAM,EAAEvB,IAAI,CAACO,MAAM,CACjB;MACEiB,WAAW,EAAExB,IAAI,CAACU,MAAM,CAAC;IAC3B,CAAC,EACD;MAAEC,IAAI,EAAE;IAAG,CACb;EACF,CAAC,CAAC,CACH;AACH,CAAC,CAAC;AAEF,OAAO,MAAML,cAAc,GAAGF,oBAAoB,CAACqB,MAAM,CAAC,gBAAgB,CAAC;AAG3E;AACA;AACA;AACA,OAAO,MAAMC,sBAAsB,GAAG1B,IAAI,CAACE,KAAK,CAAC,CAC/CF,IAAI,CAACO,MAAM,CAAC;EACVoB,IAAI,EAAE3B,IAAI,CAACG,OAAO,CAAC,YAAY,CAAC;EAChCyB,SAAS,EAAE5B,IAAI,CAACU,MAAM,CAAC;IAAEmB,SAAS,EAAE,CAAC;IAAEC,KAAK,EAAE;EAAwB,CAAC;AACzE,CAAC,CAAC,EACF9B,IAAI,CAACO,MAAM,CAAC;EACVoB,IAAI,EAAE3B,IAAI,CAACG,OAAO,CAAC,SAAS,CAAC;EAC7B4B,MAAM,EAAE/B,IAAI,CAACU,MAAM,CAAC;IAAEmB,SAAS,EAAE,CAAC;IAAEC,KAAK,EAAE;EAAkB,CAAC;AAChE,CAAC,CAAC,CACH,CAAC;;AAEF;AACA;AACA;AACA,OAAO,MAAME,oBAAoB,GAAGhC,IAAI,CAACE,KAAK,CAAC,CAC7CF,IAAI,CAACO,MAAM,CAAC;EACVoB,IAAI,EAAE3B,IAAI,CAACG,OAAO,CAAC,KAAK,CAAC;EACzB8B,UAAU,EAAEjC,IAAI,CAACU,MAAM,CAAC;IACtBmB,SAAS,EAAE,CAAC;IACZC,KAAK,EAAE,wBAAwB;IAC/BI,SAAS,EAAE;EACb,CAAC;AACH,CAAC,CAAC,EACFlC,IAAI,CAACO,MAAM,CAAC;EACVoB,IAAI,EAAE3B,IAAI,CAACG,OAAO,CAAC,MAAM,CAAC;EAC1BgC,OAAO,EAAEnC,IAAI,CAACU,MAAM,CAAC;IAAEmB,SAAS,EAAE,CAAC;IAAEC,KAAK,EAAE;EAAsB,CAAC;AACrE,CAAC,CAAC,CACH,CAAC","ignoreList":[]}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Transaction dialog helper utilities.
3
+ * Functions for working with transaction signatures and display.
4
+ */
5
+
6
+ import { CborSet, VkeyWitness, blake2b_256 } from "@blaze-cardano/core";
7
+
8
+ /**
9
+ * Get the payment key hash from a HotWallet's first address.
10
+ */
11
+ export async function getWalletPaymentKeyHash(wallet) {
12
+ try {
13
+ const addresses = await wallet.getUsedAddresses();
14
+ const address = addresses[0];
15
+ if (!address) return null;
16
+ const paymentCredential = address.asBase()?.getPaymentCredential();
17
+ return paymentCredential?.hash?.toString() ?? null;
18
+ } catch {
19
+ return null;
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Count the number of vkey signatures in a transaction's witness set.
25
+ */
26
+ export function countSignatures(tx) {
27
+ const vkeys = tx.witnessSet().vkeys();
28
+ return vkeys ? vkeys.size() : 0;
29
+ }
30
+
31
+ /**
32
+ * Check if a specific public key has already signed the transaction.
33
+ * Compares by vkey (public key bytes).
34
+ */
35
+ export function hasVkeySigned(tx, vkeyHex) {
36
+ const vkeys = tx.witnessSet().vkeys();
37
+ if (!vkeys) return false;
38
+ const vkeyArray = vkeys.toCore();
39
+ return vkeyArray.some(([vkey]) => vkey === vkeyHex);
40
+ }
41
+
42
+ /**
43
+ * Get the list of required signer key hashes from the transaction body.
44
+ */
45
+ export function getRequiredSigners(tx) {
46
+ const requiredSigners = tx.body().requiredSigners();
47
+ if (!requiredSigners) return [];
48
+ return Array.from(requiredSigners.values()).map(s => s.toString());
49
+ }
50
+
51
+ /**
52
+ * Compute the transaction body hash for display.
53
+ */
54
+ export function getTxBodyHash(tx) {
55
+ const bodyCbor = tx.body().toCbor();
56
+ return blake2b_256(bodyCbor);
57
+ }
58
+
59
+ /**
60
+ * Format a hash for display: first 8 chars + ... + last 8 chars.
61
+ */
62
+ export function formatHash(hash) {
63
+ if (hash.length <= 20) return hash;
64
+ return `${hash.slice(0, 8)}...${hash.slice(-8)}`;
65
+ }
66
+
67
+ /**
68
+ * Merge signatures from source transaction into target transaction.
69
+ * Prevents duplicate signatures by comparing vkey (public key).
70
+ * Returns the count of newly added signatures.
71
+ */
72
+ export function mergeSignatures(target, source) {
73
+ const targetWs = target.witnessSet();
74
+ const sourceWs = source.witnessSet();
75
+ const targetVkeys = targetWs.vkeys()?.toCore() ?? [];
76
+ const sourceVkeys = sourceWs.vkeys()?.toCore() ?? [];
77
+
78
+ // Find vkeys in source that aren't in target (by comparing public key)
79
+ const existingPubKeys = new Set(targetVkeys.map(([vkey]) => vkey));
80
+ const newVkeys = sourceVkeys.filter(([vkey]) => !existingPubKeys.has(vkey));
81
+ if (newVkeys.length === 0) {
82
+ return 0;
83
+ }
84
+
85
+ // Merge the new vkeys into target
86
+ targetWs.setVkeys(CborSet.fromCore([...targetVkeys, ...newVkeys], VkeyWitness.fromCore));
87
+ target.setWitnessSet(targetWs);
88
+ return newVkeys.length;
89
+ }
90
+ //# sourceMappingURL=tx-dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tx-dialog.js","names":["CborSet","VkeyWitness","blake2b_256","getWalletPaymentKeyHash","wallet","addresses","getUsedAddresses","address","paymentCredential","asBase","getPaymentCredential","hash","toString","countSignatures","tx","vkeys","witnessSet","size","hasVkeySigned","vkeyHex","vkeyArray","toCore","some","vkey","getRequiredSigners","requiredSigners","body","Array","from","values","map","s","getTxBodyHash","bodyCbor","toCbor","formatHash","length","slice","mergeSignatures","target","source","targetWs","sourceWs","targetVkeys","sourceVkeys","existingPubKeys","Set","newVkeys","filter","has","setVkeys","fromCore","setWitnessSet"],"sources":["../../../src/Sprinkle/tx-dialog.ts"],"sourcesContent":["/**\n * Transaction dialog helper utilities.\n * Functions for working with transaction signatures and display.\n */\n\nimport { Core, HotWallet } from \"@blaze-cardano/sdk\";\nimport { CborSet, VkeyWitness, blake2b_256 } from \"@blaze-cardano/core\";\n\n/**\n * Get the payment key hash from a HotWallet's first address.\n */\nexport async function getWalletPaymentKeyHash(\n wallet: HotWallet,\n): Promise<string | null> {\n try {\n const addresses = await wallet.getUsedAddresses();\n const address = addresses[0];\n if (!address) return null;\n const paymentCredential = address.asBase()?.getPaymentCredential();\n return paymentCredential?.hash?.toString() ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Count the number of vkey signatures in a transaction's witness set.\n */\nexport function countSignatures(tx: Core.Transaction): number {\n const vkeys = tx.witnessSet().vkeys();\n return vkeys ? vkeys.size() : 0;\n}\n\n/**\n * Check if a specific public key has already signed the transaction.\n * Compares by vkey (public key bytes).\n */\nexport function hasVkeySigned(tx: Core.Transaction, vkeyHex: string): boolean {\n const vkeys = tx.witnessSet().vkeys();\n if (!vkeys) return false;\n const vkeyArray = vkeys.toCore();\n return vkeyArray.some(([vkey]) => vkey === vkeyHex);\n}\n\n/**\n * Get the list of required signer key hashes from the transaction body.\n */\nexport function getRequiredSigners(tx: Core.Transaction): string[] {\n const requiredSigners = tx.body().requiredSigners();\n if (!requiredSigners) return [];\n return Array.from(requiredSigners.values()).map((s) => s.toString());\n}\n\n/**\n * Compute the transaction body hash for display.\n */\nexport function getTxBodyHash(tx: Core.Transaction): string {\n const bodyCbor = tx.body().toCbor();\n return blake2b_256(bodyCbor);\n}\n\n/**\n * Format a hash for display: first 8 chars + ... + last 8 chars.\n */\nexport function formatHash(hash: string): string {\n if (hash.length <= 20) return hash;\n return `${hash.slice(0, 8)}...${hash.slice(-8)}`;\n}\n\n/**\n * Merge signatures from source transaction into target transaction.\n * Prevents duplicate signatures by comparing vkey (public key).\n * Returns the count of newly added signatures.\n */\nexport function mergeSignatures(\n target: Core.Transaction,\n source: Core.Transaction,\n): number {\n const targetWs = target.witnessSet();\n const sourceWs = source.witnessSet();\n\n const targetVkeys = targetWs.vkeys()?.toCore() ?? [];\n const sourceVkeys = sourceWs.vkeys()?.toCore() ?? [];\n\n // Find vkeys in source that aren't in target (by comparing public key)\n const existingPubKeys = new Set(targetVkeys.map(([vkey]) => vkey));\n const newVkeys = sourceVkeys.filter(([vkey]) => !existingPubKeys.has(vkey));\n\n if (newVkeys.length === 0) {\n return 0;\n }\n\n // Merge the new vkeys into target\n targetWs.setVkeys(\n CborSet.fromCore([...targetVkeys, ...newVkeys], VkeyWitness.fromCore),\n );\n target.setWitnessSet(targetWs);\n\n return newVkeys.length;\n}\n"],"mappings":"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","ignoreList":[]}